VMpwn入门

前言
由于在 2025GHCTF
新生赛上看到了 VMpwn
,所以打算浅浅入个门,参考一下出题人的文章吧,写的挺详细的。
😘😘文章链接
VMpwn的介绍
VMpwn可以理解为让我们自己去输入opcode,然后程序会读取对应的opcode来执行对应的操作,常见的有
- 模拟寄存器操作,比如说寄存器加减乘除,异或等。
- 模拟stack,入栈出栈
- 模拟data段
- 模拟text段
除了上述还有蛮多,暂且不说了,但基本的数据都是位于 bss段
上的。
也正是因为数据基本都在bss段上,所以常见的漏洞就是进行溢出改写,通常不会对模拟的数据数组进行下标检查。
还有要基本理解的地方,借用出题人的图片:
例题
建议先看第二个例题:2025GHCTF
OGeek2019 Final OVM
参考:https://x1ng.top/2020/12/17/%E5%AD%A6%E4%B9%A0VM-PWN/
题目链接:click_me
1 | comment = malloc(0x8CuLL); |
- 具体的函数上面所示,sp、pc、code_num、code都由我们输入,重点在于
execute
函数。
1 | v4 = (a1 & 0xF0000u) >> 16; |
- 函数开头就有这些操作,对这些数据都是单字节的,其中result是最高字节,v2最低字节,参考开头的图片我们可以猜测,v2和v3是作为源操作数的,v4就是目的寄存器,result就作为指令来进行操作,下面简单分析一下各个result对应什么指令
1 | // 为了方便写,记r1,r2为原操作数,r3作为目的寄存器 |
逆向完之后差不多如上,漏洞点其实也挺明显的。
0x30
0x40
,两个操作之间没有对数组下表进行检查,因此我们可以任意地址写,正如之前所说,这些stack
memory
comment
reg
数组都位于bss段上,我们通过memory溢出到comment[0]的地址之后,由于后面还有个read函数,因此我们可以做到任意地址写!!!- 溢出到comment[0],然后再往上有free的地址,由于题目开了
Full RELRO
,我们不能直接改free@got,因此我们还要改hook函数的地址,观察到最后的read是往comment地址
开入,free(comment),如果将free_hook-0x8
改为comment的地址,然后写入b'/bin/sh\x00' + p64(system)
,那么comment就是 b’/bin/sh\x00’, free_hook就是system的地址,然后执行 free(comment)就是 system(b’/bin/sh\x00’),就getshell了。
1 | 溢出free_hook-0x8为comment,然后输入b'/bin/sh\x00' + p64(system) |
- 下图为comment上方的got表,我们通过修改comment来获得free的相关地址
1 | 0x202060 - 0x201F68 = 248 |
- 还有一点要说的,最后输入0xff的时候要注意,每次都会在之前跳入下面if的判定中,我也不知道为什么,动调的时候发现的,但是控制reg[13]不为0就行了。
EXP
1 | from pwn import * |
2025GHCTF
- 先看主函数:
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
- 具体和第一题差不多,就不细说了,来逆向一下execute函数即可:
1 | 0x10: r3 = r1 |
漏洞点还是一样的明显,数组越界,memory可以越界到funcptr,然后直接对该地址写入backdoor的地址即可
差距0x20/4 = 0x8
,即往memory[-0x8]写入(int四字节)
EXP
1 | from pwn import * |
- 标题: VMpwn入门
- 作者: D0wnBe@t
- 创建于 : 2025-03-05 20:26:02
- 更新于 : 2025-03-07 13:38:38
- 链接: http://downbeat.top/2025/03/05/VMpwn入门/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论