From Anime Game to Android System Security Vulnerability

Hello, I’m @topjohnwu, the developer of the popular Android modding tool: Magisk. In this article I’d love to share the whole journey from the process of analyzing the root detection mechanism of a popular anime game Fate/Grand Order (US/JP), to discovering a widespread security/privacy bug that exists on potentially millions of Android devices.

Table of Contents

TL;DR

Fate/Grand Order

I’ve been fighting with all sorts of weird device integrity detection methods over the years, but nothing is near the level of FGO. For some reason, the developers at Aniplex are extremely obsessed with detecting Magisk, as if it is an ultimate mission they are destined to accomplish. Other than the standard and common sensitive binaries, mount point, and environment variables checks, they went out the way to ban USB debugging, blacklist the package name of Magisk Manager (com.topjohnwu.magisk), and also parse through all system services and blacklisted Magisk related services. All of them are mitigated in Magisk with various different techniques that I will spare you from the lengthy details.

Experiments

To do any analysis, USB debugging (ADB) is pretty much required. The Aniplex devs are smart and sneaky: the app simply refuses to run with ADB enabled. I’ve got some tricks up my sleeves so it is possible for me to enable ADB without being detected. However, I decide not to disclose the trick publicly since I really don’t want to make my life more difficult in the future. Just keep in mind that all following steps are done in a USB debuggable environment.

Analysis

MagiskHide exploits the fact that Android apps’ processes aremount_namespace isolated. Magisk modifications are only reverted and hidden in specific target processes, which is the reason why non-target processes can still use root graciously. Through experiments, the issue can theoretically be narrowed down to:

  1. MagiskHide is simply just too slow (FGO detects root before MagiskHide have a chance to hijack the process)

Digging Deeper

We utilize the tool strace to analyze what’s going on with FGO without taking apart the APK and do reverse engineering. If you want the full strace output, here you go (the target process PID is 9184). BTW here is an interesting info within the traces, the blacklisted packages (and some files):

com.cih.game_cih
com.hexview.android.memspector
cn.mm.gk
pl.Nyki.Dax
catch_.me_.if_.you_.can_
com.sbgamehacker
jp.kbc.ma34.devicefaker
com.saurik.substrate
de.robv.android.xposed.installer
com.felixheller.sharedprefseditor
cn.mc.sq
cn.mc1.sq
com.cih.game_cih
pl.aqua.gameguardian
org.sbtools.gamehack
com.hexview.android.memspector
mr.big.stuff
cat.dcat.roothide
de.robv.android.xposed.installer
com.saurik.substrate
com.topjohnwu.magisk
com.loserskater.suhidegui
eu.chainfire.suhide
eu.chainfire.supersu
eu.chainfire.supersu.pro
com.noshufou.android.su
com.koushikdutta.superuser
me.phh.superuser
/system/app/superuser.apk
/system/app/Superuser.apk
/system/app/SuperUser.apk
/system/app/SUPERUSER.apk
/su/suhide
A snippet of the strace output

ProcFS Leak

I recall I once tried calling ps -A in terminal emulators without root, and it doesn’t return anything other than the process itself and its child processes. I quickly pulled out the good old trusty Terminal Emulator for Android, ran the command ps -A on my OnePlus 6 and… oh my god.

PID 2665 and PID 4654 should not show up here

The Bug

After a few days of investigation, the issue is narrowed down to a misconfiguration when mounting /proc. Ever since Android 7.0, /proc should be mounted with hidepid=2 (more info here). However, on the OnePlus 6 running stock OOS 9.0.2, it is not mounted with the flag enabled.

What’s the Issue?

What does leaking procfs info actually means? By using /proc information, you can determine what apps, processes, and services are running on the device with no permissions needed, and also a variety of information can also be leaked, like in the case of FGO which abuses this bug to read mount info from other processes to detect Magisk. Although with SELinux protection the damage won’t be as severe as it could since no apps are allowed to read anything outside of its own secontext, this is still a bug that should be fixed on all devices running Android 7.0+.

Widespread

So is OnePlus the only OEM shipping systems with this vulnerability? Short answer, NO. The whole team at XDA-Developers helped testing on all kinds of devices, and so far Google (Pixel and Nexus line-up) and Samsung are the few big players that implement this security feature properly on their devices. This means a significant number of devices out there does not have procfs protection included, even though it should already be implemented back in the Nougat days!! The full list of tested devices and the results is covered in this article from XDA.

ProcGate

I created a simple app, ProcGate, that is capable of detecting whether your device is vulnerable, no root is required. It also has the ability to fix a vulnerable system by remounting /proc if you have root access. In addition, if you are rooted with Magisk or SuperSU, the app can also add a boot script with the fix included so that your procfs will always be remounted properly on boot. The app currently only supports Android 7.0+ since remounting /proc on lower Android versions might cause issues and is not properly tested yet.

Conclusion

If you get all the way here, thanks for spending your precious time reading this long article. Also I have to apologize for drawing some conclusions on my Twitter account too hastily, and false information spreads out of my control. Hopefully this article can be used to straight the facts out there.