ciscn_2019_n_3 题解
发布日期:2021-05-15 04:19:05 浏览次数:20 分类:精选文章

本文共 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_freerec_str_free

通过对这两个函数的检查,我发现它们都是正确地释放内存的大对象,但没有将指针置为空。这意味着地址被复用,这样就留给了攻击者可能性,一旦触发漏洞,攻击者就可以利用这些有效的但已被释放的指针。

现在重点是在 do_deldo_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 函数。

上一篇:ret2text失败--记录一次简单的栈溢出
下一篇:Lctf-2016-pwn100 题解

发表评论

最新留言

关注你微信了!
[***.104.42.241]2025年05月25日 03时16分26秒