TL;DR To intercept network traffic for Android 7.0 targeted applications, introduce a res/xml/network_security_config.xml file.

Expected Reading Time: 5 mins

In this post I am exploring the new security feature of Android 7.0, which by default makes applications to not to trust “user” installed CA certificates (non-admin), and how to bypass this new security feature. I started with the feeling that it might not be easy to find a way past these checks, but it panned out to be quite straightforward and much less technical than expected.

Android 7.0 (Nougat) has introduced many new security features to harden the OS. The changes ranges from low level stuff like using more of Linux Seccomp, having File based encryption, to making mediaserver more secure by compartmentalization and compiler level checks for integer overflows. Among all these changes, Android 7.0 also changed the default trust level of installed CA certificates for the applications.

In Android Nougat, the default trusted CA certificates by the applications has changed. In the earlier versions of Android, by default the application apart from trusting the “system” installed CA certificates, it also used to trust the “user” added CA certificates as well. For example, while using some MITM proxy like mitmproxy, burp etc, you can simply install the proxy’s certificate on Android device/emulator and then you can intercept and observe the network traffic in clear text. But from Android 7.0 onwards, the default behaviour has been altered and the “user” installed certificates won’t be trusted anymore by the applications. Thus, intercepting application’s traffic using a proxy will not be possible out of the box.

So how to observe the network traffic for the applications targeting Android 7.0? Apparently, Google has not provided any simple switch in settings menu, which can be toggled and apps start trusting user installed CA certs. So it means we need to get our hands dirty.

So with a task in hand, I picked up an open source Android application and compiled with target SDK Level 24 (for Android 7.0). I prepared a release build and installed on a device running Android 7.0. I used mitmproxy for the job to intercept network traffic. And to no surprises, the application was not able to connect and reported no internet connectivity.

As the adage goes, RTFD, lo and behold, the hint is there in the same blog post. For ease of setting network security configuration, Android provides a network security configuration file, while lets you to “customize network security settings in a safe, declarative configuration file without modifying app code”. So that is all needed. We need to decompile the application using apktool and introduce a network_security_config.xml (shown below) file at res/xml folder of the application. Recompile the application with apktool again, sign it using jarsigner and we are good to go.

<network-security-config>  
      <base-config>  
            <trust-anchors>  
                <!-- Trust preinstalled CAs -->  
                <certificates src="system" />  
                <!-- Additionally trust user added CAs -->  
                <certificates src="user" />  
           </trust-anchors>  
      </base-config>  
 </network-security-config>

Once this file is created, also update the AndroidManifest.xml file to reflect the above changes.

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    ... >
        ...
    </application>
</manifest>

For the better understanding, I highly recommend to read the original blog and the security config documentation.

In the end it turned out to be quite trivial than expected, but nevertheless requires few extra steps now to intercept an applications traffic. This technique might be not be needed immediately, as most applications will still be targeting at least Android 4.4 for now, for which the user added CA certificate are still trusted.