Intercepting HTTPS traffic is a necessity with any mobile security assessment. By adding a custom CA to Android, this can easily be done. As of Android Nougat, however, apps don’t trust client certificates anymore unless the app explicitly enables this. In this blogpost, we present a new Magisk module, that circumvents this requirement, by automatically adding client certificates to the system-wide trust store, which is by default trusted by all apps.
Basic HTTPS interception
Intercepting HTTPS on Android is a very straight-forward job, which only takes a few steps:
- Set Burp as your proxy
- Visit http://burp
- Install the Burp certificate as a user certificate
After following these steps, you can view all HTTPS traffic that is sent through the user’s browser. A more detailed explanation can be found on Portswigger’s website.
In the past, this approach would even work for app traffic as the application would trust all installed user certificate by default. One way to prevent app traffic from being intercepted, is by installing certificate pinning. Certificate pinning means that on each SSL connection the certificates presented by the server will be compared to a locally stored version. The connection will only succeed if the server can provide the correct identity. This is a great security feature, but can be tricky to implement.
Enter Android Nougat
Starting with Android Nougat, apps no longer trust user certificates by default. A developer can still choose to accept user certificates by configuring the networkSecurityConfig attribute in the app’s AndroidManifest.xml file, but by default, they are no longer trusted.
A first approach would be to decompile, modify and recompile the application, which are quite some steps to perform. If the app turns out to have protection against repackaging files, this would also be very difficult. An example of this technique can be found on warroom.securestate.com.
A different approach is adding the user certificate to the system store. The system store is located at /system/etc/security/cacerts and contains a file for each installed root certificate.
A very simple solution would be copying the user installed file (found at /data/misc/user/0/cacerts-added) to this folder. This is only possible, however, if the system is mounted as r/w. Now, while it is possible to remount /system and perform the necessary actions, this is a rather dirty solution and some root-detection algorithms will detect this modification.
Magisk is a “Universal Systemless Interface, to create an altered mask of the system without changing the system itself.” The fact that Magisk doesn’t modify the /system partition makes it a very nice solution for security assessments where the application has enhanced root detection. By activating “Magisk Hide” for the targeted application, Magisk becomes completely invisible.
Magisk also supports custom modules that are fairly easy to create. In order to have any user certificate recognized as system certificates, we made a simple Magisk module which can be found on our github. The logic of the module is very basic:
- Find installed user certificates
- Add them to the /system/etc/security/cacerts directory
When installed, the content of the Magisk module is mounted on /magisk/trustusercerts/. This folder contains multiple files, but the most important one is the system directory. This directory is automatically merged with the real /system directory, without actually touching the /system partition. As a result, all certificates in /magisk/trusteusercerts/etc/security/ will end up in /system/etc/security.
Using the module is easy:
- Install the module
- Install certificates through the normal flow
- Restart your device
After installation, the certificates will show up in your system wide trust store and will be trusted by applications:
Of course, if the application has implemented SSL Pinning, you still won’t be able to intercept HTTPS traffic, but this little module makes Android Nougat apps perform the same way as pre-Android Nougat apps.
If you have any suggestions on how to improve this module, or any ideas on how to add the ability to disable SSL Pinning on the Magisk level, let us know!
About the author
Jeroen Beckers is a mobile security expert working in the NVISO Cyber Resilience team. He also loves to program, both on high and low level stuff, and deep diving into the Android internals doesn’t scare him. You can find Jeroen on LinkedIn.