
本文共 1693 字,大约阅读时间需要 5 分钟。
利用UAF漏洞
在我最近的研究中,我利用了UAF(Use after Free)漏洞,这是一个常见但还有点难度的漏洞类型。为了详细解释这个过程,我会从头到尾观察样本的内存管理和攻击方法。
样本分析
我的样本是一个32位小端程序,使用了栈保护和NX保护。这意味着传统的预计算的堆 overflow 攻击可能不管用,但UAF漏洞可以通过堆的双向链表( thông tin carbide) stland upside-down pointers 进行利用。
运行样本后,我发现它模仿了一个简单的笔记管理功能。每个笔记可以拥有不同的值类型(整型或文本),通过选项进行 CRUD 操作。其中,选项4打印了一些随机金额信息,但这没有什么影响,因为我们主要关注留下的脚本对内存中的 free ed 指针的攻击。
静态分析
程序的主要逻辑在 main
函数中。它通过多次 while 循环处理不同的选项,每个选项调用不同的函数。因为没有使用异常处理?哦不,程序对某些选项的分支处理得比较简单,所以这为我们提供了一个利用的思路。
do_new
函数
do_new
函数负责分配内存节点。每个节点被存储在 records
数组中,这是一个大小固定的指针数组。存放的数据结构中,每个节点的前四字节是打印函数的指针,后四字节是 free 函数的指针,最后四字节存储用户输入的值。
注意到这里有一个重要的点:这个分配是非堆分配的吗?啊,放在 fastbin 中,因为它使用的是手动分配,那么这可能会影响双向链表的结构。当调用 do_del
后,记录指针 0 和 1 的值被改 为 free,变成 free susceptible buffers。
对于文本节点,最后四个字节不是用户输入,而是指向一个额外的内存块。
rec_int_free
和 rec_str_free
通过对这两个函数的检查,我发现它们都是正确地释放内存的大对象,但没有将指针置为空。这意味着地址被复用,这样就留给了攻击者可能性,一旦触发漏洞,攻击者就可以利用这些有效的但已被释放的指针。
现在重点是在 do_del
和 do_dump
函数上。我发现,这些函数使用 system
函数来构建壳。是否通过一些直接输入的漏洞来冲击这个函数?
那具体的步骤呢?
利用步骤
首先,我需要做两个整型节点的 new,记录索引 0 和 1,size 为 0xc。然后,我需要删除这两个节点,这样它们会被标记为 free,进入 fastbin 中。
此时,fastbin 链接结构是这样:Integer[1] -> Integer[0],接下来是 Text 节点。
然后,申请一个 Text 节点,size 为 0xc。这里记录索引 2,她指向的是 Text[2] 节点。那么 Text[2] 节点本身有一个 Value 节点,大小也是 0xc,这也构成了一个栈回收的子链。
因此,现在 Value 节点可以通过 Text[2] 节点来访问。大致的内存结构是这样的:
Text[2] 0xc 使用了整型 1 节点的内存块,Value 节点也有 0xc 的内存空间。
这样,我们就对 Text[2] 节点中的 Value 节点赋值,然后通过整型 0 节点来调用相关的函数,绕过正常的安全检查,假装没有被 free 所以 gadgets 还在内存中。
这让我成功起到了 system("/bin/sh"),终端进入交互式控制,这可能是一个欧yes 的开始。
不过,直接给 system 传递一个带 00 的字符串,不一定能成功,因为可能会被截断。但如果是我这里发现的,.position中的 sys_addr 前有一个 00,它导致的简单烤鸭味道成功了。
最后的测试表明,这个方法确实可行,但需要调整的脚本,确保和特定的libc版本兼容,这样就生产了一个真正起作用的 ROP chain,牛刀。
对我来说,发现这个漏洞的关键在于理解机制:堆被实现的双向链表,fastbin 的分配策略,以及如何利用这些结构让系统通过没有阻断的方式暴露-pointer 函数。
发表评论
最新留言
关于作者
