How we use Dirty Pipe to get reverse root shell on Android Emulator and Pixel 6
In February this year, a vulnerability named Dirty Pipe was revealed for Linux kernel 5.8+, which allows arbitrary writing of read-only files. On Android, Google Pixel 6 and SAMSUNG Galaxy S22 all used a version of Android 12 that can trigger the vulnerability. We tried to use this vulnerability to escalate privileges on Android 12 by using Android Emulator x86_64 as the initial environment before porting it to Google Pixel 6.
Privilege escalation using Dirty Pipe is relatively easy in general Linux environments. An attacker can escalate privileges by modifying the binary with the suid flag, or by writing to /etc/shadow. However, neither of them exists in the Android environment. In addition, Android enables SELinux by default, restricting users to only perform operations permitted by the policy. We try to find another path that can bypass SELinux while gaining root privileges.
Read-only files do not exhibit CoW behavior when it is maliciously written, so as long as we are writing into a read-only file that has already been mmaped by the process, we will be directly modifying the corresponding memory. Utilizing this feature, we use Dirty Pipe to overwrite the read-only file used by init to hijack init and obtain root and init context for subsequent attacks.
SELinux has very powerful permission management, but making permissions too strict will get in the way during development, hence some backdoors were intentionally left for developers. This also allows attackers to bypass SELinux more easily, but it still requires loading kernel modules.
SELinux has a special rule transition that can change a process’ context during execve, while init can transition to the context with module_load permission, open and read the corresponding executable and loadable files. Kernel modules can thus be loaded through Dirty Pipe.
In this talk, we will describe how we found a way to hijack the init process, loading a kernel module despite Dirty Pipe’s inability to write the first byte of the page, bypassing the SELinux protection mechanism, and finally, how we managed to successfully get the reverse root shell on the mobile phone.