Magisk is one of the popular rooting tools for Android. Magisk Manager is an app which helps to manage the magisk module and also comes with other features.One such notable feature is Magisk hide. Magisk hide prevents applications from detecting the presence of root. Security sensitive apps detected the presence of Magisk Manager app as an indication of rooted device. Magisk Manager on the other hand allowed to hide itself by changing its package name to a random name. Apps then resorted to detect the Magisk Manager app by extracting its app signature and through other ways. Magisk now has up the ante with the latest Magisk Manager v7.4.0 where it provides full hide capability from Android version 9.0+. Nevertheless it’s a never ending cat and mouse game. The key point to be noted is, mere presence of Magisk Manager app cannot be treated as device being rooted, but it is definitely suspicious to have this app from the perspective of security sensitive applications. In this post I attempt to provide a way to detect Magisk Hide by using one of the features of Android OS. This was found to be working with Magisk Manager App v7.4.0 and Magisk v20.1, tested on Android versions 8.0, 8.1, 9.0, 10.0
Magisk Hide & Android Service
When an app spawns a service through Android APIs ( startService, bindService ), the service either runs in the same process context of the app or in a different process depending on the configuration mentioned in the AndroidManifest. When the Service runs as a different process, the parent process is usually zygote and the process runs with the same process name with a suffix taken from Manifest file. Magisk Hide for quite sometime was not able to hide the Magisk mount paths from this newly spawned service. This was one of the detection techniques used by gaming, banking apps to detect magisk from the spawned remoted service. In one of the updates Magisk Hide started to hide the su and magisk paths from this remote service.
Android introduced the concept fo Isolated Process from Android version 4.1 . This allows apps to spawn a service which can run under its own user id but a different SELinux context is created. This service does not have any permissions on it own. This concept was created mainly for browsers like Chrome where each tab being opened runs in an isolated process in such a way that any malicious script running in the context of the browser will not be able to abuse the privileges otherwise granted for a browser app.Below snapshot indicate the unique user ids and SELinux context assigned for the isolated process
Magisk Hide & Isolated Process
Magisk has a Log daemon which keeps checking for process start with magisk hide list. If the process in the hide list is started, it un-mounts the magisk specific paths and /sbin paths for this process and its sub-processes.
But when an isolated process is started, magisk unmounts the magisk specific paths and sbin for this process but this is not effectively reflecting in the /proc/<pid>/mounts.
Here is a comparison on /proc/pid/mounts between isolated process and the main app process which is hidden by magisk hide.
Effectively Magisk has unmounted the su and magisk specific paths from the app and isolated process. But there are some traces of magisk paths left out in /proc/pid/mounts, /mountinfo, /mountstats which can be used as one of the detection mechanisms for Magisk Hide. These paths are not accessible from the isolated process. You can find the source code for detecting magisk hide in github.