Tool Release: Magisk Module – Conscrypt Trust User Certs
Android 14 introduced a new feature which allows to remotely install CA certificates. This change implies that instead of using the
/system/etc/security/cacerts directory to check the trusted CA’s, this new feature uses the
com.android.conscrypt APEX module, and reads the certificates from the directory
Inspired by this blog post by Tim Perry, I decided to create a Magisk module that would automate the work required to intercept traffic on Android 14 with tooling such as Burp Suite, and that uses the installed user certificates in a similar fashion as the MagiskTrustUserCerts module does.
This Magisk module makes all installed user CA’s part of the Conscrypt APEX module’s CA certificates, so that they will automatically be used when building the trust chain on Android 14.
The Magisk module is available for download from https://github.com/nccgroup/ConscryptTrustUserCerts
Note: It should be noted that if an application has implemented SSL Pinning, it would not be possible to intercept the HTTPS traffic.
APEX: A quick overview
The Android Pony EXpress (APEX) container format was introduced in Android 10 and it is used in the install flow for lower-level system modules. This format facilitates the updates of system components that do not fit into the standard Android application model. Some example components are native services and libraries, hardware abstraction layers (HALs), runtime (ART), and class libraries.
With the introduction of APEX, system libraries in Android can be updated individually like Android apps. The main benefit of this is that system components can be individually updated via the Android Package Manager instead of having to wait for a full system update.
What is Conscrypt?
The Conscrypt module (
com.android.conscrypt) is distributed as an APEX file and it is used as a Java Security Provider. On Android 14, an updatable root trust store has been introduced within Conscrypt. This allows for faster CA updates allowing to revoke trust of problematic or failing CAs on all Android 14 devices.
Creating the Magisk module
The script that appears on Tim Perry’s blog post was used as the template for the module, but some modifications were required in order to use it as a Magisk module.
In Magisk, boot scripts can be run in 2 different modes: post-fs-data and late_start service mode. As it was required that the Zygote process was started, the boot script was set to be run in the late_start service mode.
To ensure that the boot process was completed before we mounted our CA certificates over the Conscrypt directory inside Zygote’s mount namespace, the system property
sys.boot_completed was used to check that the process finished, as it is set to 1 once the whole boot process is completed.
The following piece of code was added at the beginning of the script:
while [ "$(getprop sys.boot_completed)" != 1 ]; do /system/bin/sleep 1s done
The script was also modified in order to use the user installed CA’s with the following code:
cp /data/misc/user/0/cacerts-added/* /data/local/tmp/tmp-ca-copy/
Once we had done the prior modifications, we had a functional Magisk module to intercept HTTPS traffic on Android 14.
Daniel Romero for his support throughout the research process.