byt3quester/CVE-2022-22706-poc

GitHub: byt3quester/CVE-2022-22706-poc

针对 Arm Mali GPU 驱动程序 CVE-2022-22706 权限校验缺陷的 PoC,通过构造页缓存可写别名实现非特权进程提权至 root。

Stars: 0 | Forks: 0

# CVE-2022-22706 - 页缓存写入 Arm Mali GPU 驱动程序向用户空间提供了一个其锁定为只读页面的 CPU 可写映射, 因此非特权进程会获得一个页缓存的可写别名,而该页缓存所支持的文件 只能以 `O_RDONLY` 方式打开。 `exploit.c` 清空了 `/etc/passwd` 页缓存中 root 的密码字段,并执行 `su root`。磁盘上的文件从未被修改过。 ## 漏洞 关于谁可以写入导入的页面,有两处决策存在冲突。 CPU 映射的可写性来自 `KBASE_REG_CPU_WR`,但锁定操作仅根据 `KBASE_REG_GPU_WR` 来请求写入 权限: ``` /* mali_kbase_mem.c */ pinned_pages = pin_user_pages_remote( mm, address, alloc->imported.user_buf.nr_pages, reg->flags & KBASE_REG_GPU_WR ? FOLL_WRITE : 0, pages, NULL, NULL); ``` 在设置了 `CPU_WR` 且清除了 `GPU_WR` 的情况下进行导入,你会同时得到两部分内容:一个导入的 CPU 可写映射,以及一个在没有 `FOLL_WRITE` 的情况下获取的 `get_user_pages` 锁定。如果没有 `FOLL_WRITE`,`get_user_pages` 永远不会打破只读文件映射上的 COW,它会返回 页缓存页本身。然后,驱动程序将这些确切的页面作为可写页面重新映射到用户空间。 已由 [`5381ff7`](https://android.googlesource.com/kernel/google-modules/gpu/+/5381ff7b4106b277ff207396e293ede2bf959f0c%5E%21/) ("GPUCORE-32592 修复 userbuf 导入以尊重 RO 内存")修复,该补丁改为从 `KBASE_REG_CPU_WR | KBASE_REG_GPU_WR` 而不是仅从 `GPU_WR` 来获取写入权限。 ## 利用流程 ``` sequenceDiagram participant U as unprivileged process participant K as mali_kbase participant PC as page cache U->>U: mmap /etc/passwd O_RDONLY, PROT_READ U->>K: MEM_IMPORT(anon page, CPU_RD|CPU_WR|GPU_RD) Note over K: address recorded, nothing pinned yet U->>U: munmap(anon) + mremap file mapping onto that VA U->>K: mmap(import cookie) → writable CPU mapping U->>K: JOB_SUBMIT(EXTERNAL_RESOURCES) K->>PC: pin_user_pages_remote() without FOLL_WRITE U->>PC: memcpy() through the writable mapping U->>U: execl("/bin/su", "su", "root") ``` `MEM_IMPORT` 仅记录一个地址;锁定操作发生在稍后的 `JOB_SUBMIT` 时。这个间隙 使得匿名页能够在两者之间被替换为文件映射。 该编辑的长度保持不变,因此 root 行之后的内容不会发生偏移: ``` root:x:0:0:root:/root:/bin/sh ← before root::0:0:rootx:/root:/bin/sh ← after (empty password) ``` busybox 的 `su` 在密码字段为空时,会在提示之前返回 `CHECKPASS_PW_HAS_EMPTY_PASSWORD`,并且 只有当其恰好为 `x` 时才会读取 `/etc/shadow`。 ## 构建与运行 ``` gcc -static -o exploit exploit.c ``` 将其复制到 VM 中,并作为非特权用户运行: ``` $ ./exploit ``` ## 演示 ![demo](https://static.pigsec.cn/wp-content/uploads/repos/cas/50/506f473443f391c1a881e66eb6ea3b75d869c98670eb43203a8acddac26bd171.gif) 该演示是通过 SSH 以 `user` (uid 1000) 身份登录 QEMU 目标录制的。`./exploit` 修补了 `/etc/passwd` 页缓存中 root 的所在行,并执行了 `su root`,这直接进入了一个 root shell 而无需输入密码。 退出该 shell 并再次运行 `su` 仍然会获得 root 权限:该页面保持缓存状态,因此之后每次对 `/etc/passwd` 的 `open()`/`read()` 操作都会读取到被修补的字节。 在执行 `echo 1 > /proc/sys/vm/drop_caches` 驱逐了该页面并从存储中重新读取文件后, `su` 会再次要求输入密码。磁盘上的字节从未被触碰过。 ## 参考 * [Arm — Mali GPU 驱动程序漏洞](https://developer.arm.com/Arm%20Security%20Center/Mali%20GPU%20Driver%20Vulnerabilities) * [STAR Labs — Mali-cious Intent:利用 GPU 漏洞 (CVE-2022-22706 / CVE-2021-39793)](https://starlabs.sg/blog/2025/02-mali-cious-intent-exploiting-gpu-vulnerabilities-cve-2022-22706-/-cve-2021-39793/) * [上游修复 — `5381ff7`](https://android.googlesource.com/kernel/google-modules/gpu/+/5381ff7b4106b277ff207396e293ede2bf959f0c%5E%21/)
标签:ARM架构, CSV导出, Mali驱动, Web报告查看器, 内存管理, 内核漏洞, 安全渗透, 客户端加密, 提权, 身份验证强制