Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
cve-2023-20768 — Android 内核 CVE 分析与 PoC,针对 MediaTek ION 分配器的类型混淆漏洞,涵盖根因差异分析、非特权触发以及可利用性评估。 | Kitploit
工具/GitHubGitHub/murf-xd/cve-2023-20768
Android安全漏洞分析漏洞利用逆向工程移动安全二进制分析二进制利用
GitHubmurf-xd/cve-2023-20768

cve-2023-20768

Android 内核 CVE 分析与 PoC,针对 MediaTek ION 分配器的类型混淆漏洞,涵盖根因差异分析、非特权触发以及可利用性评估。

查看仓库
31个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

三星 Galaxy M32 上的 CVE-2023-20768 —— 可达性研究

摘要。 CVE-2023-20768 是 MediaTek ION 分配器中的类型混淆漏洞(CWE-843)。我检查了它在运行 2022 年 7 月固件的三星 SM-M325F(Galaxy M32,Helio G80)上是否实际可利用。存在易受攻击的代码,并且我证明了当由非特权进程触发时,它确实会在此设备上运行。我未能将其武器化。ioctl 路径受到输入验证的限制,而包含真正越界读取的路径只会处理真正的 ION 缓冲区,因为对 dma_buf_ops 指针的第二次检查会拒绝我可能伪造的任何内容。本文涵盖了我是如何得出这个结论的,包括一个后来被证明是错误的中间结论。

该 CVE 已公开并被修复。所有测试均在我自己的设备上进行,已用 Magisk 获取 root 权限。

为什么是这款设备

该漏洞位于 MediaTek 的 ION 代码中,而非上游 Linux 或三星编写的任何代码。MediaTek 在其 BSP 中提供 Android ION 分配器的自有分支,该 BSP 会提供给每一位基于其芯片构建的厂商。M32 使用 Helio G80,因此也会包含这段代码。同一款手机若是 Exynos SoC 则完全不受影响。

根本原因

我提取了 2022 年(易受攻击)和 2023 年(已修补)的 vmlinux 镜像,并在 IDA 中对它们进行了差异对比。两个 ION 函数发生了变化:

函数20222023
ion_drv_file_to_bufferstrstr(name, "dmabuf")is_dma_buf_file()
_ion_ioctlstrcmp(name, "ion")is_dma_buf_file()

is_dma_buf_file 在 2022 年的镜像中不存在,在 2023 年的镜像中才出现。因此,这两个函数此前都是通过名称来判断某个 struct file 是否为 dma_buf,而修复方式将其替换为真正的类型检查。在这里混淆对象,意味着内核会将非 dma_buf 当作 dma_buf 来读取。

从用户态触达该代码

在这两个函数中,_ion_ioctl 是非特权进程可以触达的那个:

root@kitploit:~
open("/dev/ion")
  -> ion_ioctl                      (.unlocked_ioctl)
  -> ION_IOC_CUSTOM  (0xC0104906)
  -> ion_custom_ioctl
  -> _ion_ioctl
  -> case 0: ION_SYS_CACHE_SYNC
  -> find_vma(user_VA)              (call site at _ion_ioctl+0x9f0)
  -> strcmp(vma->vm_file...name, "ion")

该请求是一个 ion_custom_data { u32 cmd = 0; u64 arg; },它指向一个 120 字节的 ion_sys_data:

偏移量字段

spoof.c 构建了这个结构。

证明它确实会被分发

我无法直接追踪它。该设备通过三星的 SELinux 策略和内核加固屏蔽了 kprobe_events、set_ftrace_filter 和 function_graph,且 ION 的 printk 受调试开关控制,因此 dmesg 保持静默。

于是我改用返回码作为判定依据。发出四个请求,返回结果的模式会告诉你执行走到了哪里:

C 返回成功意味着 switch 确实在根据 sys_cmd 进行分发。A 和 B 结果不同意味着 VA 正在被处理,这使执行流程进入了 find_vma 内部。这就是易受攻击的路径,无需 root 即可触达。

它停在了哪里

触达检查并不等于绕过它。我测试了 strcmp 实际接受哪些内容:

  • 一个通过 ION_IOC_SHARE 映射再执行 mmap 的真实 ION 缓冲区能通过,返回 0。
  • 一个名为 memfd:ion 的 memfd 失败,返回 -EFAULT。
  • 一个普通文件,文件名就叫 ion,同样失败,返回 -EFAULT。

因此,在 vm_file+0x60 处被比较的字段并不是文件名。它是 dma_buf 内部字段,几乎可以肯定是 dma_buf->exp_name,ION 将其设置为 "ion"。该检查在设计上就是不健全的,但我从用户态所能创建的任何内容都无法设置该字段。

随后我对该路径进行了模糊测试:sync_type 取值范围 0 到 7,size 取值 {0, 1, 0x1000, 0x100000, 0xffffffff},VA 取值 {真实 ion 缓冲区, memfd, 0},共 120 个用例,外加一个针对释放后使用的已释放句柄探测。没有崩溃,设备保持运行。超大的 size 会在 find_vma 之前退出并返回 0。sync_type 3 到 5 会进入 m4u 路径并返回 -EPERM。大于 5 的值返回 -EINVAL。已释放的句柄返回 -EINVAL,因此 ION 会对其校验,那里不存在 UAF。

另一个函数,以及一次错误的转向

真正的越界读取位于 ion_drv_file_to_buffer 中。它执行 ldr [private_data+0x28],将非 dma_buf 的 private_data 当作 dma_buf 来读取。存在一个 ops == &ion_dma_buf_ops 比较(该表位于 0xFFFFFF800A097F18),但该比较发生在这次读取之后,因此并不能阻止它。在下游,__do_dump_share_fd 会从返回的缓冲区中读取 +0x28、+0x48、+0x50、+0xb8、+0xe4 处的字段并打印它们,而 ldr x8, [buf+0x28]; ldr [x8+0x30] 对于混淆对象来说是一次野指针解引用。

触发点是 ion_dump_all_share_fds,它使用 iterate_fd 遍历每个 ION 客户端进程的文件描述符。我最初的结论是,只有当你读取 ION 的 debugfs 节点时它才会运行,而这个内核未设置 CONFIG_DEBUG_FS。我通过三种方式验证了这一点:/proc/config.gz、debugfs 未出现在 /proc/filesystems 中,以及 mount -t debugfs 返回 ENODEV。于是我认为这条路径在结构上不可达,将其排除。

这个结论是错的。OOM killer 的内存转储函数 dump_header 在 0xffffff8008204b9c 处直接调用了 bl ion_mm_heap_memory_detail,而 dump_header 又是从 out_of_memory 和 oom_kill_process 调用的。无需 debugfs。

memcg_oom.c 证实了这一点。它在 /dev/memcg 下创建一个 cgroup,将 memory.limit_in_bytes 和 memory.memsw.limit_in_bytes 都限制为 8MB(只限制前者会让子进程逃逸到 zram 交换空间),并 fork 一个子进程不断分配内存直至其被杀死。随后 dmesg 显示:

root@kitploit:~
dump_header <- oom_kill_process <- out_of_memory <- mem_cgroup_oom_synchronize

紧接着是完整的 ion_mm_heap_memory_detail 以及 __do_dump_share_fd 输出,它们解析出了真实的 gralloc dma_buf。因此,这个易受攻击的函数会在任何非特权进程都能引发的过程中执行。还有第三个触发点:MediaTek 看门狗中 hang_detect_dump_thread 的 ShowStatus。

为什么它仍然无法利用

我持有 32 个名为 memfd:dmabuf 的 memfd,并触发了相同的 memcg OOM。如果其中有任何一个被送入 ion_drv_file_to_buffer,strstr 就会通过,private_data 将为 NULL,内核会在 KERN_ERR 级别打印 [ION]ion_drv_file_to_buffer warnning, dmabuf is NULL。但这一行从未出现。只有 graphics 和 gralloc 客户端被转储。要么是普通的 /dev/ion 客户端的 fd 表不是这里的 iterate_fd 所遍历的对象,要么是 memfd 在打印之前就静默失败了。

无论哪种情况,OOM 转储都只会处理系统合法的 dma_buf,它们会干净地通过。memfd 也是唯一一种我能充分控制名称以包含 "dmabuf" 的 fd 类型,而它无法造成错误。

结论

漏洞确实存在。易受攻击的代码在此构建中是可达的,并且确实会执行,无需 root 即可触发。但从用户态无法在此设备上将其武器化。ioctl 路径受到句柄校验、大小检查以及 access_ok 的限制。转储路径只会看到真正的 ION 缓冲区,伪造被 ops == &ion_dma_buf_ops 阻止。要想更进一步,需要一个 exp_name 为 "ion" 且可控的非 ION 对象,或者其他原语,例如 ION 缓冲区 UAF,或者 TOCTOU 竞态。

文件

  • spoof.c — 用于 cache-sync ioctl 的 PoC 以及差分判定工具
  • memcg_oom.c — 用于转储路径的 memcg OOM 触发程序
  • trigger.c、oom_trigger.c — 早期的触发尝试
  • boot_images/ — 提取的内核镜像(2022 和 2023)以及 2022 构建的 IDA 数据库
下载工具
+0x00sys_cmd = 0
+0x08ion 句柄(先分配一个,heap_id_mask = 0x1 即可)
+0x10用户虚拟地址
+0x18低半部分 = size,高半部分 = sync_type,取值范围为 {0,1,2}
用例请求结果
Asys_cmd=0, 伪造的 VA-EFAULT
Bsys_cmd=0, VA = 00
Csys_cmd=40
Dsys_cmd=99-EFAULT