这次长安杯出现了两道wasm的题目,一道常规wasm逆向,另一道是unity+wasm,大佬们都去打别的比赛了,让我拿到了第一道wasm的二血,最终成绩线上第二。
静态分析
1 jeb
jeb的WebAssembly Decompiler可以直接反编译wasm,反编译出来的代码也较为清晰
但仍存在很多问题,很多变量还需要猜一下。
在strings里面发现了rc4的密钥,盲猜是个rc4,进入__f11函数,发现里面大概是rc4的加密,要比较的密文是gvar_440,使用rc4解密解不出来,猜测是进行了魔改,但是这个代码太难看了,看了半天并没有发现什么更改的地方(太菜了),只能换种方法动调看看
2 wabt
使用wabt项目可以将wasm文件处理成为c文件,但可读性较差,项目地址https://github.com/WebAssembly/wabt
用法:
在bin文件夹下使用命令./wasm2wat ./wasm1.wasm -o wasm1.wat
可以得到wasm汇编格式的wat文件,也就是jeb中看到的那种汇编格式
使用命令./wasm2c ./wasm1.wasm -o wasm1.wat
可以得到C语言的.c和.h文件
然后再用命令gcc -c webassembly.c -o webassembly.o
将文件编译成为ida可以分析的.o文件
动态调试
首先使用python开启端口python -m http.server 8888
然后在浏览器地址栏输入http://127.0.0.1:8888/wasm1.html 就可以调试了
f12打开开发人员工具,在源里面找到对应的wasm文件,在func11处下断点
注意旁边的作用域,这里面存储的是变量的值
而其中几个524开头的数指向的是存储的地址,可以在模块->memories->$env.memmories->buffer里面查看,但是只能一个个找
比如说在5246224这个位置存储的就是rc4的key
既然我们知道这大概是个rc4的加密体系,那么只要知道每次异或得数据就可以解密密文
跟进到f10函数,在f10中查找xor,发现关键点
可以肯定这里就是进行异或处理的位置
对变量进行观察,发现var66就是我们的输入,那自然var59就是每次异或的数据,在这里下个断点,将每次var59的数据记录下来
最终解密脚本
data=[0x8f,0xef,ord('|'),0xe4,0x9,0x9d,ord(';'),0x7f,0x91,0x19,ord('F'),0x9e,0x12,0x0c,0x0e,0xdb,ord('9'),0xad,ord('G'),0xa9,ord('?'),0x1c]
flag=''
xor_data=[233,131,29,131,114,212,85,11,244,107,35,173,102,61,96,188,102,218,6,218,114,97]
for i in range(len(xor_data)):
flag+=chr(xor_data[i]^data[i])
print(flag)
总结
对于wasm的逆向和常规逆向的流程相差不大,首先静态观察,其次动态调试,静态观察因为jeb的存在可以比较方便的查看代码,但距离可读性较好仍有一定的差距,动态分析可以直接跟进函数查看wasm风格的汇编代码,只要了解常规指令的含义和数据存储地址就可以很快的整理清楚程序的逻辑