Vulnerability-wiki

Use-After-Free(UAF)漏洞详解

漏洞概述

Use-After-Free(UAF)漏洞 是一种内存错误,当程序尝试访问已经释放(freed)的内存区域时就会触发。攻击者可以利用这一漏洞,通过精心构造的数据重新分配这段内存,并进行任意代码执行、权限提升或程序崩溃等攻击行为。

❗ 该漏洞常见于 C/C++ 程序中,尤其是在内存管理不当的复杂系统或内核模块中。


原理详解

  1. 申请内存: 程序通过 mallocnew 或类似方法申请一段内存。

  2. 释放内存: 使用完毕后,程序使用 freedelete 释放这段内存。

  3. 悬垂指针(Dangling Pointer): 程序中某处依旧保留指向该内存的指针,此时指针未置空。

  4. 再次访问: 程序继续通过该指针访问已释放的内存,可能造成:

    • 程序崩溃(访问非法内存)
    • 数据泄漏
    • 内存被篡改
    • 恶意代码执行(如攻击者通过重新分配控制内存内容)

漏洞触发条件


危害等级

威胁 说明
任意代码执行 攻击者控制释放内存中的内容,插入恶意指令并被程序执行
本地提权 通过内核 UAF 漏洞实现从普通用户提权为 root
泄露敏感信息 读取原本已释放的内存中遗留数据
程序崩溃 导致服务异常中止,造成拒绝服务(DoS)

漏洞利用示例(用户态)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char *data;
} Item;

int main() {
    Item *item = (Item *)malloc(sizeof(Item));
    item->data = (char *)malloc(100);
    strcpy(item->data, "secret");

    free(item->data); // 释放内存

    // Use-After-Free: 继续访问已释放内存
    printf("Data: %s\n", item->data); // 未定义行为,可能泄露或崩溃

    // 攻击者此时可能通过重新分配使这块内存指向恶意数据
    return 0;
}

防御措施

方法 描述
指针置空 free(ptr); ptr = NULL; 避免悬垂指针
内存检测工具 使用 AddressSanitizer(ASan)、Valgrind 等工具检测 UAF
使用智能指针 在 C++ 中使用 std::shared_ptrstd::unique_ptr 自动管理生命周期
强类型语言 如 Java、Python 等自动内存管理语言不易产生 UAF
启用系统防护 利用堆隔离、堆完整性检查、CET(Control-flow Enforcement Technology)等现代防护机制

案例参考

CVE-2019-2215 - Android Binder UAF 内核提权漏洞

这是一个 Android 内核中的 UAF 漏洞,出现在 Binder 驱动的 binder_thread 结构中。攻击者可以通过构造特定的 Binder 请求,触发 UAF,从而提权获取 root 权限。

参考链接:https://nvd.nist.gov/vuln/detail/CVE-2019-2215


总结

Use-After-Free 是一种高危内存安全漏洞,具有强大的攻击能力和破坏性。程序员在设计系统时应避免手动管理内存,使用现代安全机制,并通过自动化工具进行漏洞检测和测试。