2021 BlueHens CTF 2021
Contents
题目
标题 | 类型 |
---|---|
watman | re |
解题
访问该地址
F12查看源码
可以看到页面代码较为简单,主要为一张图片一个whtml还有一个wasm文件,所以这题主要考验wasm逆向
首先我们从html代码中,可以看出,flagChecker是由checker.wasm导出的方法,点击按钮后,执行该方法
flagChecker接收三个参数,分别是由输入框内容经encode变换后的数组、128、257
WebAssembly(缩写为Wasm)是基于堆栈的虚拟机的二进制指令格式。Wasm被设计为可编程C / C ++ / Rust等高级语言的可移植目标,可在Web上部署客户端和服务器应用程序。
wasm是基于堆栈的虚拟机的二进制指令格式。与x86架构的汇编又很大的区别。
进一步的说明后续补充
我们可以从开发者工具中看到cheker.wasm的相关指令,下图为flagChecker的代码
|
|
动态调试时可通过Chrome的调试功能,下断点进行调试。
相关指令集
可参考以下指令集
基本指令
这里简单介绍一下大量用到的基本指令:
local.get
(get_local
)
从函数的参数中读取内容,示例和下一条一起(
local.set
(set_local
)
基本的用途是向本地变量中写入值,如下例:
|
|
local.tee
它同样是用来向本地变量写入值的,但它写入之后原值仍然保留在栈中,相当于省了一步 local.get
。
i32.const
这个之前也提到过了,向站内压入一个数字,对应的还有其他三种类型的 .const
,这里就不再重复了。
i32.add
等
这里的等指的是一系列算术运算,我们只是单独拿出 add
来举例。它弹出栈顶的两个元素并将其相加,最终将结果压入栈中。
其中包括i32.mul(乘)、i32.rem_s(取余)
i32.load
和 i32.store
顾名思义,从 Memory
中取出/向 Memory
存入数据的指令。
load
接受一个参数,就是地址;store
接收两个参数:先弹出需要存入的值,再弹出存入的地址。
这二者还经常带有特殊的属性:offset
表示 n
位的偏移,align
表示 2^n
位的偏移。
控制指令 – 分支
分支最常使用是 if
,如下例:
|
|
这里需要注意的是,if
的判断过程都是在 if
之前进行的,if
本身只能从栈中弹出一个元素,并且判断其是否为 0,非 0 则成立。
这里需要介绍的一条指令是 if_br
,它可以跳出当前的块。if_br 1
就相当于跳出当前的 if
,回到 if
开头重新判断。
还有一种判断指令:select
。select
接收三个参数:a
、b
和 condition
。在判断时,condition
位于栈顶被首先弹出,当 condition
成立时,向栈中压入 a
,否则就压入 b
。
控制指令 – 循环
循环使用的是 loop
,和 if
一样,它也并没有实际的意义,跳转需要通过 br
进行。
基于以上指令和动态调试的结果
可以还原flag验证脚本
|
|
Author Zhe
LastMod 2021-03-30