kuzeyardabulut/CVE-2024-1065

GitHub: kuzeyardabulut/CVE-2024-1065

针对 ARM Mali GPU 内核驱动 CVE-2024-1065 UAF 漏洞的页缓存提权 PoC,演示通过竞争重用已释放物理页面覆盖 SUID binary 代码段以实现 root 权限。

Stars: 0 | Forks: 1

# CVE-2024-1065 — 页缓存利用 PoC CVE-2024-1065 漏洞的概念验证(PoC)利用程序,这是 ARM Mali GPU kernel 驱动程序中的一个物理页面释放后重用(UAF)漏洞。该利用程序演示了**页缓存利用**:通过竞争将一个已释放的 `MIGRATE_MOVABLE` 页面作为 SUID binary 的内存代码镜像,然后覆盖它以在磁盘上不修改任何文件的情况下,以 root 身份实现任意代码执行。 ## 工作原理 1. **触发 UAF** — 通过 `KBASE_IOCTL_MEM_IMPORT` 将一个匿名页导入 Mali GPU 驱动,并将其映射两次到用户空间。释放这两个映射会将物理页面返回给 `MIGRATE_MOVABLE` buddy freelist,而 `cpu_mapping2` 仍然是它的别名引用。 2. **喷射页缓存** — 利用程序打开 `/usr/bin/passwd` 100 次,并使用 `posix_fadvise(POSIX_FADV_DONTNEED)` 反复驱逐 `PAGE_OFFSET` 处的页面,然后通过 `pread` 触发缓存未命中。每次未命中都会迫使 kernel 分配一个新的 `MIGRATE_MOVABLE` 页面,不断循环遍历 freelist,直到 UAF 页面被选中。 3. **确认重叠** — 通过 `cpu_mapping2` 在 `MAIN_OFFSET` 处读取探测字节,确认 UAF 页面现在支持该 binary 的页缓存条目。值 `0x00` 和 `0x61` 表示失败;其他任何值都是真实的 binary 代码。 4. **注入 shellcode** — 通过 `cpu_mapping2` 执行 `memcpy`,用调用 `setuid(0)`、`setgid(0)` 和 `execve("/bin/sh")` 的 shellcode 覆盖 `main()`。 5. **执行** — 调用 `execve("/usr/bin/passwd")`。ELF 加载器将 binary 的页缓存页面映射为可执行。损坏的页面已经存在 —— 不会发生磁盘读取 —— 因此 shellcode 以 root 身份运行。 ## 环境要求 | 要求 | 值 | |---|---| | 架构 | x86-64 | | Kernel | 5.15 (在 `5.15.0+` 上测试) | | Kernel 配置 | `CONFIG_MALI_NO_MALI=y`, `CONFIG_MALI_CSF_SUPPORT=y`, `r48` | | 设备 | 用户空间可访问 `/dev/mali0` | | 目标 binary | `/usr/bin/passwd` (SUID root) | ## 编译 ``` gcc -O2 -o exploit exploit.c ``` ## 用法 ``` ./exploit ``` 预期输出: ``` [*] Opened /usr/bin/passwd x100 [*] MEM_IMPORT: flags=0x... gpu_va=0x... va_pages=0x1 [*] gpu_mapping (VA 1): 0x... [*] cpu_mapping2 (VA 2): 0x... [*] UAF triggered — stale mapping alive at 0x... [*] Spraying page cache (100 attempts)... [+] Overlap confirmed on attempt N (byte=0xf3) — cpu_mapping2 aliases the page cache! [*] Shellcode written. Triggering execve... # id uid=0(root) gid=0(root) groups=0(root) ``` ## 更改目标 所有特定于目标的值都定义在 `exploit.c` 的顶部: ``` #define TARGET_BINARY "/usr/bin/passwd" #define PAGE_OFFSET 0x4000 /* file offset of the page containing main() */ #define MAIN_OFFSET 0xbc0 /* intra-page offset of main() */ ``` 要针对其他不同的 binary,可以通过在入口点地址(`readelf -h`)反汇编 `_start` 来找到函数偏移量,然后计算: ``` PAGE_OFFSET = sym_va & ~0xfff MAIN_OFFSET = sym_va & 0xfff ``` 运行前请验证: ``` dd if= bs=1 skip=$((PAGE_OFFSET + MAIN_OFFSET)) count=8 2>/dev/null | xxd ``` ## 故障排除 | 症状 | 原因 | 解决方法 | |---|---|---| | 喷射在 100 次尝试后失败 | UAF 页面在竞争窗口前被消耗 | 在触发 UAF 之前预先驱逐目标页面;增加 `NUM_FDS` | | `kernel BUG at mm/page_poison.c` | 探测检查在 `0xaa` 的页中毒字节上通过 | 在确认检查中添加 `probe != 0xaa` | | `SYSCHK` 在 `MEM_IMPORT` 上失败 | Mali 驱动未加载或版本不正确 | 检查 `CONFIG_MALI_NO_MALI` 和驱动程序版本握手 | ## 参考 - [CVE-2024-1065 — Project Zero bug 报告](https://project-zero.issues.chromium.org/issues/42451668) - [Dirty Pagetable — Black Hat USA 2023](https://yanglingxi1993.github.io/dirty_pagetable/dirty_pagetable.html) - [The Dirty Pipe Vulnerability (CVE-2022-0847)](https://dirtypipe.cm4all.com)
标签:0day挖掘, ARM Mali, PoC, UAF漏洞, Web报告查看器, 内核安全, 协议分析, 安全渗透, 客户端加密, 暴力破解, 权限提升