byt3quester/CVE-2023-20938-poc

GitHub: byt3quester/CVE-2023-20938-poc

针对 Android binder 驱动 CVE-2023-20938 UAF 漏洞的本地权限提升 PoC,可实现从无特权 shell 到 root 的完整利用链。

Stars: 0 | Forks: 0

# CVE-2023-20938 — Android binder UAF 权限提升 这是一个针对 **CVE-2023-20938**(Android binder 驱动中的 use-after-free 漏洞)的本地权限提升概念验证(PoC)。它可以从一个无特权 shell 中获取 **uid 0**,将 **SELinux 降级为 permissive 模式**,然后生成一个 root shell。 本次构建的目标环境:**Android Cuttlefish / Goldfish AVD, x86_64, kernel 5.10.107**。 ## 演示 ![exploit 演示](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/18f6ab1019161204.gif) 使用 [asciinema](https://asciinema.org/) 录制,并使用 [`agg`](https://github.com/asciinema/agg) 渲染为 GIF: ## 漏洞详情 - **CVE:** CVE-2023-20938 - **组件:** `drivers/android/binder.c`, `binder_transaction_buffer_release()` - **类型:** use-after-free (kmalloc-128) `binder_transaction_buffer_release()` 过度信任攻击者提供的 `offsets_size`。如果发送一个 `offsets_size` 比完整条目少一个字节(`sizeof(offset) - 1 == 7`)的 transaction,会导致释放路径错误解析末尾的 `flat_binder_object`,并对 `binder_node` 的引用计数过度递减,从而在仍存在悬垂引用(dangling reference)时将其释放。 ## 工作原理 该漏洞利用程序将跨缓存(cross-cache)泄漏串联到任意读取和受控写入中,随后重写凭证(credentials)。各个阶段如下(参见 `poc_cf.c` 中的 `main()`): ``` B. Cross-cache leak free a wave of binder_nodes (kmalloc-128) -> page returns to the buddy allocator -> reclaim the page with eventpoll epitems (eventpoll_epi cache, 0x80-byte objects). A dangling binder transaction now reads kernel pointers out of an epitem, leaking a struct file and its epitem address. C. Arbitrary read re-trigger the UAF and use a sprayed fake binder_node to turn binder's hlist_del unlink into a controlled *(where) = what write. Two writes redirect a victim file's f_inode at a fake inode overlaid on the epitem and mark it S_PRIVATE. FIGETBSZ on the file then returns *(epitem.event.data + 24): a steerable 4-byte read. D/E/F. Privilege escalation defeat KASLR (leak eventfd_fops via f_op), walk init_task's task list to the launcher's cred, zero its uid/gid set and seccomp.mode, then zero selinux_state to drop SELinux to permissive. G. A pre-forked, eventfd-free launcher execs a root shell. ``` 需要两个无特权进程共享一个 binder 节点来驱动该 UAF;这是通过 hwservicemanager 的 `ITokenManager`(`createToken` / 通过 token 进行 `get` 操作)实现的。 ## 构建 ``` clang -static -Wall -Wextra -o poc_cf poc_cf.c -lpthread ``` `binder.h` 必须与 `poc_cf.c` 放在同一目录下。该构建特意采用静态编译,以便这个单一二进制文件能在没有工具链的目标环境中直接运行。 ## 运行 ### 1. 启动存在漏洞的 Cuttlefish 客户机 在你的 Cuttlefish 宿主机包目录中,使用匹配的 kernel + initramfs 启动 AVD: ``` HOME=$PWD ./bin/launch_cvd \ --kernel_path=bzImage \ --initramfs_path=initramfs.img ``` ### 2. 推送并运行 ``` adb push poc_cf /data/local/tmp/ adb shell /data/local/tmp/poc_cf ``` 成功运行后会依次走过各个阶段,并最终进入一个 root shell: ## 可靠性 该漏洞利用是**概率性**的。每个阶段都在内部进行了重试。因此,无论你看到的是干净的退出还是客户机崩溃(panic),只需**重新运行**即可(AVD 的 `/data` 会在重启时被擦除,因此发生 panic 后需要重新推送二进制文件)。 如果在较慢或较繁忙的目标上回收命中率不佳,请延长等待时间或增加 spray 数量(位于 `poc_cf.c` 顶部的 `#define`): | 宏定义 | 默认值 | 含义 | | ------------------ | ------- | ----------------------------------------------- | | `SETTLE_US` | 5000 | 节点释放后,在进行 spray 之前的暂停时间 | | `FAKE_SPRAY_COUNT` | 8 | 竞争回收该槽位的被阻塞的 `sendmsg()` 数量 | | `FAKE_WAIT_US` | 10000 | 释放 spray 后,在进行 unlink 之前的暂停时间 | | `PRESKIP_US` | 1000 | 牺牲性的第一个 sendmsg 之后的暂停时间 | | `KW_RETRY_COUNT` | 8 | 每次单独 unlink 写入的尝试次数 | | `STAGE_C_TRIES` | 8 | 启用任意读取功能的尝试次数 | ## 重新适配其他构建版本 结构体偏移量和未随机化的符号基准(`*_NOKASLR`)**特定于这个确切的 5.10.107 构建**,无法应用于其他环境。要移植到不同的 kernel,请使用从匹配的 `vmlinux` 中提取的值,更新 `poc_cf.c` 顶部附近的偏移量块和符号块。我在提取偏移量后,在 Pixel 7 上进行了尝试。 ## 参考资料 - Google 的 Android 进攻安全博客 [https://androidoffsec.withgoogle.com/posts/attacking-android-binder-analysis-and-exploitation-of-cve-2023-20938/]
标签:0day挖掘, Android, DSL, PoC, UAF漏洞, Web报告查看器, 内核安全, 客户端加密, 暴力破解, 本地提权