关于wasm逆向的实战方法
字数 1076 2025-08-23 18:31:18
WebAssembly逆向实战方法详解
一、WebAssembly简介
WebAssembly(缩写为Wasm)是一种基于堆栈的虚拟机的二进制指令格式,设计作为编程语言的可移植编译目标,支持在Web上部署客户端和服务器应用程序。与JavaScript不同,它不是直接手动编写的语言,而是C/C++、Rust、C#和TypeScript等上层语言的编译目标。
二、WebAssembly逆向分析工具
1. WebAssembly Binary Toolkit (WABT)
- 功能:提供命令行工具wasm2wat,可将.wasm文件翻译为可读性更强的.wat格式
- 项目地址:https://github.com/WebAssembly/wabt
- 常用命令:
wasm2wat wasm1.wasm -o wasm1.wat # 转换为wat格式 wasm2c ./wasm1.wasm -o wasm1.c # 转换为C语言代码 gcc -c webassembly.c -o webassembly.o # 编译为.o文件供IDA分析
2. WebAssembly Studio IDE
- 基于web的IDE,可以将.wasm文件中的特征提取并转变为其他格式,包括x86-64的翻译
3. Radare2
- 可以分解指令,但不能重构控制流图
4. JEB反编译器
- 虽然主要用于Android应用,但在wasm逆向中也有作用
- 可读性一般,不如直接看wat文件
5. Chrome浏览器调试
- 对于少量wasm代码,可直接使用浏览器动态调试
- 对抗非正常wasm文件的有效方法
三、逆向实战方法
方法一:wasm2c转换分析
- 安装wabt工具:
sudo apt install wabt - 反编译wasm文件:
wasm2c test.wasm -o test.c - 编译为可执行文件:
注意:可能无法直接运行,主要用于静态分析gcc -c test.c -o test.o
方法二:Chrome动态调试
- 构造测试输入(如假flag)
- 在wasm代码中设置断点
- 逐步执行并观察内存和寄存器变化
四、实战案例分析
题目分析
- 题目来自TetCTF,flag格式:TetCTF{...},长度27
- 核心验证逻辑在wasm中实现
- 使用20个元素的数组进行验证
加密逻辑分析
- 全局密文数组:
t = [38793, 584, 738, 38594, 63809, 647, 833, 63602, 47526, 494, 663, 47333, 67041, 641, 791, 66734, 35553, 561, 673, 35306] - 输入处理:
- 每个输入字符的ASCII码加83
- 按2,3,4,1的顺序计算
- 加密方程:
((b+(a+g[0])^32)+83 = t[1] ((c+(t[1]-g[1])^36)+83 = t[2] ((d+(t[2]*g[2])^19)+83 = t[3] ((a+(t[3]^g[3])^55)+83 = t[0]
解密脚本
g = [115, 82, 52, 149, 136, 67, 76, 97, 71, 90, 71, 74, 124, 104, 84, 67, 114, 127, 52, 31]
t = [38793, 584, 738, 38594, 63809, 647, 833, 63602, 47526, 494, 663, 47333, 67041, 641, 791, 66734, 35553, 561, 673, 35306]
def brute_force_solve(g, t, o):
for a in range(32+83, 127+83):
for b in range(32+83, 127+83):
eq1 = ((b + (a + g[0+4*o])) ^ 32) + 83
if eq1 == t[1+4*o]:
for c in range(32+83, 127+83):
eq2 = ((c + (eq1 - g[1+4*o])) ^ 36) + 83
if eq2 == t[2+4*o]:
for d in range(32+83, 127+83):
eq3 = ((d + (eq2 * g[2+4*o])) ^ 19) + 83
eq4 = ((a + (eq3 ^ g[3+4*o])) ^ 55) + 83
if eq3 == t[3+4*o] and eq4 == t[0+4*o]:
return a, b, c, d
return None, None, None, None
for o in range(0,5):
a, b, c, d = brute_force_solve(g, t, o)
print(chr(a-83), chr(b-83), chr(c-83), chr(d-83), sep="", end="")
最终flag
TetCTF{WebAss3mblyMystique}
五、总结与技巧
-
wasm逆向流程:
- 静态分析:使用wasm2wat/wasm2c转换代码
- 动态调试:Chrome开发者工具
- 算法分析:理解加密逻辑
-
对抗非正常wasm文件:
- Chrome动态调试是最可靠的方法
- 可以结合GPT辅助分析复杂逻辑
-
优化方向:
- 爆破方法效率较低,可使用z3等约束求解器
- 对于简单wasm代码,可直接阅读wat格式
-
实用技巧:
- 构造假输入触发验证逻辑
- 关注内存操作和全局变量
- 注意wasm中的堆栈操作特性