在抽奖页面网页源代码中,有几行提示和代码:
WebAssembly.instantiateStreaming(fetch('get_verify_code.wasm')).then(({instance}) => {
window.getVerifyCode = (prefix) => {
console.log('prefix:', prefix);
const startTime = Date.now();
const memory = new Uint8Array(instance.exports.memory.buffer);
const prefixBufPtr = 16;
const prefixBufLen = ((new TextEncoder()).encodeInto(prefix, memory.subarray(prefixBufPtr))).written;
const resultBufPtr = 0;
const resultBufLen = 16;
const resultLen = instance.exports.get_verify_code(prefixBufPtr, prefixBufLen, resultBufPtr, resultBufLen);
const code = (new TextDecoder()).decode(memory.subarray(resultBufPtr, resultBufPtr + resultLen));
console.log(`solved: ${prefix + code} ${(Date.now() - startTime) / 1000}s`);
return code;
};
});
如下图所示:
在代码(不包括注释)的第一行可以看到,网页试图通过绝对路径加载get_verify_code.wasm
二进制文件(因此该文件实际URL路径为https://2025challenge.52pojie.cn/get_verify_code.wasm
)
在代码(不包括注释)的第二行可以看到,网页试图调用get_verify_code.wasm
中的getVerifyCode
函数
这不得拉下来逆一逆?
那么,废话不多说,我们把get_verify_code.wasm
下载下来看一看到底是何方神圣,一探究竟,如下图所示:
我们使用wabt工具集中的wasm-decompile
工具来将get_verify_code.wasm
转换为伪代码之后进行分析:
wasm-decompile.exe get_verify_code.wasm -o code.txt
转换为伪代码后,我们搜索其中的所有函数,发现export function
只有2
个,并且其中一个就是getVerifyCode(a, b, c, d)
函数,如下图所示:
查看另一个export function
后,发现是calc_flag10_uid_timestamp_resultbufptr_resultbuflen_return_resultlen(a, b, c, d)
函数,如下图所示:
由于伪代码非常杂乱,我们借助AI分析一下该函数的输入值和作用,如下图所示:
我们通过导入Python
的time
库,利用time.time()
直接计算时间戳,然后再导入wasmtime
库在本地加载get_verify_code.wasm
(将Python脚本与get_verify_code.wasm
放置在同一目录下),依次传入uid, timestamp, buf_ptr, buf_len
,调用calc_flag10_uid_timestamp_resultbufptr_resultbuflen_return_resultlen(uid, timestamp, buf_ptr, buf_len)
,即可得到flag,代码如下:
import wasmtime
import time
store = wasmtime.Store()
module = wasmtime.Module.from_file(store.engine, "get_verify_code.wasm")
instance = wasmtime.Instance(store, module, [])
calc_flag10 = instance.exports(store)["calc_flag10_uid_timestamp_resultbufptr_resultbuflen_return_resultlen"]
memory = instance.exports(store)["memory"]
uid = int(input("Please enter your UID: "))
timestamp = int(time.time())
buf_ptr = 1049296
buf_len = 32
res_len = calc_flag10(store, uid, timestamp, buf_ptr, buf_len)
raw = memory.data_ptr(store)[buf_ptr:buf_ptr+res_len]
flag = bytes(raw).decode("utf-8")
print(flag)
附件(包含题目get_verify_code.wasm
文件 & 转换后的code.txt
伪代码文件 & 解题Python脚本文件):
flag10.zip
(13.6 KB, 下载次数: 1)