Kuboid
Open Luck·Kuboid.in
Black Hat2023
Open in YouTube ↗

Two bugs with one PoC: Rooting Pixel 6 from Android 12 to Android 13

Black Hat1,605 views38:25over 2 years ago

This talk demonstrates two distinct kernel vulnerabilities in the Android GPU driver, specifically targeting the Mali GPU, to achieve local privilege escalation (LPE) and root access on Pixel 6 devices. The speaker details how these vulnerabilities, including a use-after-free and an improper memory access check, can be chained to bypass modern Android kernel mitigations like KASLR and UAO. The presentation provides a step-by-step guide on crafting a proof-of-concept exploit that leverages these bugs to gain root privileges on Android 13. The research highlights the effectiveness of analyzing older, known vulnerabilities to discover new, exploitable paths in complex kernel drivers.

Rooting the Pixel 6: Exploiting Mali GPU Driver Vulnerabilities

TLDR: This research details how two distinct kernel vulnerabilities in the Mali GPU driver can be chained to achieve local privilege escalation on Pixel 6 devices. By exploiting a use-after-free and an improper memory access check, an attacker can bypass kernel mitigations like KASLR and UAO to gain root access. This work underscores the critical importance of auditing complex, third-party kernel drivers that often serve as the path of least resistance for privilege escalation.

Security researchers often focus on the high-level application layer, but the real battle for device control is fought in the kernel. When you are looking for a path to root, the GPU driver is almost always the most fertile ground. It is complex, it is proprietary, and it is frequently updated with patches that are often incomplete. The research presented at Black Hat 2023 on the Mali GPU driver is a masterclass in how to turn a seemingly minor memory corruption bug into a full-blown root exploit on modern Android devices like the Pixel 6.

The Anatomy of the Exploit

The core of this research involves chaining two vulnerabilities to bypass the hardening measures that make modern Android kernels difficult to compromise. The first bug is a use-after-free (UAF) condition, and the second is an improper memory access check.

The UAF vulnerability allows an attacker to manipulate the kernel heap. By triggering a specific sequence of operations, you can force the kernel to free a memory object while a dangling pointer still references it. If you can then reallocate that memory with an object you control, you effectively gain a primitive for memory corruption.

The second vulnerability, CVE-2021-28664, stems from a failure to properly validate memory access permissions. In the original driver code, the developer checked for GPU write permissions but failed to verify CPU write permissions. This oversight allows an attacker to map read-only memory as writable, providing a powerful read/write primitive that is essential for further exploitation.

Bypassing Modern Mitigations

Modern Android kernels are heavily defended. Features like Kernel Address Space Layout Randomization (KASLR) and User Access Override (UAO) are designed to stop exactly the kind of exploitation described here. However, these mitigations are not silver bullets.

KASLR is meant to hide the location of kernel code, but if you have a memory leak, you can calculate the kernel base address and defeat the randomization. In this exploit, the researcher uses the task_struct object as a target. Because task_struct contains numerous kernel pointers, leaking it provides the necessary information to bypass KASLR.

UAO, which prevents the kernel from accessing user-space memory when it should not, is also a significant hurdle. The researcher demonstrates that by corrupting the addr_limit of the thread_info structure, you can trick the kernel into treating user-space memory as kernel-space, effectively neutralizing UAO. This is a classic technique, but seeing it applied against modern Android 13 mitigations is a stark reminder that architectural defenses are only as strong as the code that enforces them.

Practical Exploitation Flow

For a pentester or researcher, the exploit flow is straightforward but requires precise timing. The goal is to gain root, and the steps are as follows:

  1. Map a large chunk of anonymous memory with read/write permissions.
  2. Import this memory into the GPU driver using the vulnerable KBASE_IOCTL_MEM_IMPORT command.
  3. Trigger the UAF condition to manipulate the kernel heap.
  4. Use the improper access check to gain a read/write primitive.
  5. Leak the task_struct to bypass KASLR.
  6. Overwrite the addr_limit to bypass UAO.
  7. Patch the cred structure of your process to set the UID to 0.

The following snippet illustrates the logic used to trigger the memory import that leads to the vulnerability:

// Simplified PoC logic for memory import
mem_import.u.ptr = (u64)ro_page; // Read-only memory
mem_import.u.len = ro_len;
mem_import.type = BASE_MEM_IMPORT_TYPE_USER_BUFFER;
ioctl(fd, KBASE_IOCTL_MEM_IMPORT, &mem_import);

This sequence effectively turns a driver-level bug into a system-wide compromise. The use of mmap to map files into memory and then manipulating them via the GPU driver remains a highly effective technique for privilege escalation.

Defensive Considerations

Defending against these types of attacks is notoriously difficult because the vulnerabilities exist within the driver code itself, which is often provided by the hardware vendor rather than the OS maintainer. For blue teams, the focus must be on minimizing the attack surface.

If your organization manages a fleet of Android devices, the most effective defense is a rigorous patch management program. Ensure that security updates are applied as soon as they are released by the OEM. Additionally, consider using mobile device management (MDM) solutions to restrict the installation of untrusted applications, as these exploits typically require a local, unprivileged app to trigger the initial vulnerability.

Looking Ahead

This research proves that even with hardware-backed security and sophisticated kernel mitigations, the complexity of modern drivers remains a massive liability. The fact that these bugs were found in the Mali GPU driver, a component used in millions of devices, highlights the systemic risk of proprietary code.

If you are a researcher, stop looking for the "perfect" bug. Instead, look for the "old" bugs in "new" places. The techniques used to exploit CVE-2020-0041 are still relevant today, and the logic of memory corruption remains constant. The next time you are auditing a kernel driver, look for the places where the developer assumed the hardware would handle the security check. You will likely find that it does not.

Talk Type
exploit demo
Difficulty
expert
Has Demo Has Code Tool Released


Black Hat Asia 2023

45 talks · 2023
Browse conference →
Premium Security Audit

We break your app before they do.

Professional penetration testing and vulnerability assessments by the Kuboid Secure Layer team. Securing your infrastructure at every layer.

Get in Touch
Official Security Partner
kuboid.in