Basic Network Monitoring/Sniffing
Remotely sniffing all Android traffic in real-time is possible withtcpdump, netcat (nc), and Wire- shark. First, make sure that you have the latest version ofAndroid tcpdumpon your phone. Here are theinstallation steps:
adb root adb remount
adb push /wherever/you/put/tcpdump /system/xbin/tcpdump
If execution ofadb rootreturns the erroradbd cannot run as root in production builds, install tcpdump as follows:
adb push /wherever/you/put/tcpdump /data/local/tmp/tcpdump adb shell
su
mount-orw,remount /system;
cp /data/local/tmp/tcpdump /system/xbin/
cd /system/xbin chmod 755 tcpdump
In certain production builds, you might encounter an error mount: '/system' not in /proc/
mounts.
In that case, you can replace the above line$ mount -o rw,remount /system;with$ mount -o rw,remount /, as described inthis Stack Overflow post.
Remember: To use tcpdump, you need root privileges on the phone!
Executetcpdumponce to see if it works. Once a few packets have come in, you can stop tcpdump by pressing CTRL+c.
$ tcpdump
tcpdump: verbose output suppressed, use-vor-vvfor full protocol decode listening on wlan0, link-type EN10MB(Ethernet), capture size 262144 bytes 04:54:06.590751 00:9e:1e:10:7f:69(oui Unknown)>Broadcast, RRCP-0x23 reply 04:54:09.659658 00:9e:1e:10:7f:69(oui Unknown)>Broadcast, RRCP-0x23 reply 04:54:10.579795 00:9e:1e:10:7f:69(oui Unknown)>Broadcast, RRCP-0x23 reply
^C
3 packets captured 3 packets received by filter 0 packets dropped by kernel
To remotely sniff the Android phone’s network traffic, first executetcpdumpand pipe its output to netcat(nc):
tcpdump-iwlan0-s0 -w -|nc-l -p11111
The tcpdump command above involves
• listening on the wlan0 interface,
• defining the size (snapshot length) of the capture in bytes to get everything (-s0), and
• writing to a file (-w). Instead of a filename, we pass -, which will make tcpdump write to stdout.
By using the pipe (|), we sent all output from tcpdump to netcat, which opens a listener on port 11111. You’ll usually want to monitor the wlan0 interface. If you need another interface, list the available options with the command$ ip addr.
To access port 11111, you need to forward the port to your host computer via adb.
adb forward tcp:11111 tcp:11111
The following command connects you to the forwarded port via netcat and piping to Wireshark.
nc localhost 11111|wireshark-k -S -i -
Wireshark should start immediately (-k). It gets all data from stdin (-i -) via netcat, which is connected to the forwarded port. You should see all the phone’s traffic from the wlan0 interface.
You can display the captured traffic in a human-readable format with Wireshark. Figure out which protocols are used and whether they are unencrypted. Capturing all traffic (TCP and UDP) is important, so you should execute all functions of the tested application and analyze it.
This neat little trick allows you now to identify what kind of protocols are used and to which endpoints the app is talking to. The questions is now, how can I test the endpoints if Burp is not capable of showing the traffic? There is no easy answer for this, but a few Burp plugins that can get you started.
Firebase/Google Cloud Messaging (FCM/GCM)
Firebase Cloud Messaging (FCM), the successor to Google Cloud Messaging (GCM), is a free service offered by Google that allows you to send messages between an application server and client apps. The server and client app communicate via the FCM/GCM connection server, which handles downstream and upstream messages.
Downstream messages (push notifications) are sent from the application server to the client app;
upstream messages are sent from the client app to the server.
FCM is available for Android, iOS, and Chrome. FCM currently provides two connection server protocols: HTTP and XMPP. As described in theofficial documentation, these protocols are imple- mented differently. The following example demonstrates how to intercept both protocols.
Preparation of Test Setup
You need to either configure iptables on your phone or use bettercap to be able to intercept traffic.
FCM can use either XMPP or HTTP to communicate with the Google backend.
HTTP
FCM uses the ports 5228, 5229, and 5230 for HTTP communication. Usually, only port 5228 is used.
• Configure local port forwarding for the ports used by FCM. The following example applies to macOS:
$ echo"
rdr pass inet proto tcp from any to any port 5228-> 127.0.0.1 port 8080 rdr pass inet proto tcp from any to any port 5229 -> 127.0.0.1 port 8080 rdr pass inet proto tcp from any to any port 5230 -> 127.0.0.1 port 8080
"|sudo pfctl-ef -
• The interception proxy must listen to the port specified in the port forwarding rule above (port 8080).
XMPP
For XMPP communication,FCM uses ports5235 (Production) and 5236 (Testing).
• Configure local port forwarding for the ports used by FCM. The following example applies to macOS:
$ echo"
rdr pass inet proto tcp from any to any port 5235-> 127.0.0.1 port 8080 rdr pass inet proto tcp from any to any port 5236 -> 127.0.0.1 port 8080
"|sudo pfctl-ef -
Intercepting the Requests
The interception proxy must listen to the port specified in the port forwarding rule above (port 8080).
Start the app and trigger a function that uses FCM. You should see HTTP messages in your inter- ception proxy.
End-to-End Encryption for Push Notifications
As an additional layer of security, push notifications can be encrypted by usingCapillary. Capillary is a library to simplify the sending of end-to-end (E2E) encrypted push messages from Java-based application servers to Android clients.
Setting Up an Interception Proxy
Several tools support the network analysis of applications that rely on the HTTP(S) protocol. The most important tools are the so-called interception proxies; OWASP ZAP and Burp Suite Profes- sional are the most famous. An interception proxy gives the tester a man-in-the-middle position.
This position is useful for reading and/or modifying all app requests and endpoint responses, which are used for testing Authorization, Session, Management, etc.
Interception Proxy for a Virtual Device
Setting Up a Web Proxy on an Android Virtual Device (AVD)
The following procedure, which works on the Android emulator that ships with Android Studio 3.x, is for setting up an HTTP proxy on the emulator:
1. Set up your proxy to listen on localhost and for example port 8080.
2. Configure the HTTP proxy in the emulator settings:
• Click on the three dots in the emulator menu bar
• Open theSettingsMenu
• Click on theProxytab
• SelectManual proxy configuration
• Enter “127.0.0.1” in theHost Namefield and your proxy port in thePort numberfield (e.g., “8080”)
• TapApply
HTTP and HTTPS requests should now be routed over the proxy on the host computer. If not, try toggling airplane mode off and on.
A proxy for an AVD can also be configured on the command line by using theemulator command when starting an AVD. The following example starts the AVD Nexus_5X_API_23 and setting a proxy to 127.0.0.1 and port 8080.
emulator @Nexus_5X_API_23-http-proxy127.0.0.1:8080
Installing a CA Certificate on the Virtual Device
An easy way to install a CA certificate is to push the certificate to the device and add it to the certificate store via Security Settings. For example, you can install the PortSwigger (Burp) CA certificate as follows:
1. Start Burp and use a web browser on the host to navigate to burp/, then downloadcacert.
derby clicking the “CA Certificate” button.
2. Change the file extension from.derto.cer.
3. Push the file to the emulator:
adb push cacert.cer /sdcard/
4. Navigate toSettings->Security->Install from SD Card.
5. Scroll down and tapcacert.cer.
You should then be prompted to confirm installation of the certificate (you’ll also be asked to set a device PIN if you haven’t already).
This installs the certificate in the user certificate store (Tested on Genymotion VM). In order to place the certificate in the root store you can perform the following steps:
1. Run adb as root withadb rootandadb shell.
2. Locate the newly installed certificate at/data/misc/user/0/cacerts-added/.
3. Copy the certificate to the following folder/system/etc/security/cacerts/.
4. Reboot the Android VM.
For Android 7.0 (API level 24) and above follow the same procedure described in the “Bypassing the Network Security Configuration” section.
Interception Proxy for a Physical Device
The available network setup options must be evaluated first. The mobile device used for test- ing and the host computer running the interception proxy must be connected to the same Wi-Fi network. Use either an (existing) access point or createan ad-hoc wireless network.
Once you’ve configured the network and established a connection between the testing host com- puter and the mobile device, several steps remain.
• The proxy must beconfigured to point to the interception proxy.
• The interception proxy’s CA certificate must be added to the trusted certificates in the An- droid device’s certificate storage. The location of the menu used to store CA certificates may depend on the Android version and Android OEM modifications of the settings menu.
• Some application (e.g. theChrome browser) may showNET::ERR_CERT_VALIDITY_TOO_LONG errors, if the leaf certificate happens to have a validity extending a certain time (39 months in case of Chrome). This happens if the default Burp CA certificate is used, since the Burp Suite issues leaf certificates with the same validity as its CA certificate. You can circumvent this by creating your own CA certificate and import it to the Burp Suite, as explained in this blog post.
After completing these steps and starting the app, the requests should show up in the interception proxy.
A video of setting upOWASP ZAPwith an Android device can be found onsecure.force.com.
A few other differences: from Android 8.0 (API level 26) onward, the network behavior of the app changes when HTTPS traffic is tunneled through another connection. And from Android 9 (API level 28) onward, the SSLSocket and SSLEngine will behave a little bit different in terms of error handling when something goes wrong during the handshakes.
As mentioned before, starting with Android 7.0 (API level 24), the Android OS will no longer trust user CA certificates by default, unless specified in the application. In the following section, we explain two methods to bypass this Android security control.
Bypassing the Network Security Configuration
In this section we will present several methods to bypass Android’sNetwork Security Configura- tion.
Adding Custom User Certificates to the Network Security Configuration
There are different configurations available for the Network Security Configuration to add non- system Certificate Authoritiesvia the src attribute:
<certificatessrc=["system"| "user" | "raw resource"]
overridePins=["true"| "false"] />
Each certificate can be one of the following:
• "raw resource"is an ID pointing to a file containing X.509 certificates
• "system"for the pre-installed system CA certificates
• "user"for user-added CA certificates
The CA certificates trusted by the app can be a system trusted CA as well as a user CA. Usually you will have added the certificate of your interception proxy already as additional CA in Android.
Therefore we will focus on the “user” setting, which allows you to force the Android app to trust this certificate with the following Network Security Configuration below:
<network-security-config>
<base-config>
<trust-anchors>
<certificatessrc="system"/>
<certificatessrc="user"/>
</trust-anchors>
</base-config>
</network-security-config>
To implement this new setting you must follow the steps below:
• Decompile the app using a decompilation tool like apktool:
apktool d<filename>.apk
• Make the application trust user certificates by creating a Network Security Configuration that includes<certificates src="user" />as explained above
• Go into the directory created by apktool when decompiling the app and rebuild the app using apktool. The new apk will be in thedistdirectory.
apktool b
• You need to repackage the app, as explained in the “Repackaging” section of the “Reverse Engineering and Tampering” chapter. For more details on the repackaging process you can also consult the Android developer documentation, that explains the process as a whole.
Note that even if this method is quite simple its major drawback is that you have to apply this operation for each application you want to evaluate which is additional overhead for testing.
Bear in mind that if the app you are testing has additional hardening measures, like verifi- cation of the app signature you might not be able to start the app anymore. As part of the repackaging you will sign the app with your own key and therefore the signature changes will result in triggering such checks that might lead to immediate termination of the app. You would need to identify and disable such checks either by patching them during repackaging of the app or dynamic instrumentation through Frida.
There is a python script available that automates the steps described above called Android- CertKiller. This Python script can extract the APK from an installed Android app, decompile it, make it debuggable, add a new Network Security Configuration that allows user certificates, builds and signs the new APK and installs the new APK with the SSL Bypass.
python main.py-w
***************************************
Android CertKiller(v0.1)
***************************************
CertKiller Wizard Mode --- List of devices attached 4200dc72f27bc44d device ---
Enter Application Package Name: nsc.android.mstg.owasp.org.android_nsc Package: /data/app/nsc.android.mstg.owasp.org.android_nsc-1/base.apk
I. Initiating APK extraction from device complete
--- I. Decompiling
complete
--- I. Applying SSL bypass
complete
--- I. Building New APK
complete
--- I. Signing APK
complete
---
Would you like to install the APK on your device(y/N): y ---
Installing Unpinned APK --- Finished
Adding the Proxy’s certificate among system trusted CAs using Magisk
In order to avoid the obligation of configuring the Network Security Configuration for each appli- cation, we must force the device to accept the proxy’s certificate as one of the systems trusted certificates.
There is aMagisk modulethat will automatically add all user-installed CA certificates to the list of system trusted CAs.
Download the latest version of the module at the Github Release page, push the downloaded file over to the device and import it in the Magisk Manager’s “Module” view by clicking on the+ button. Finally, a restart is required by Magisk Manager to let changes take effect.
From now on, any CA certificate that is installed by the user via “Settings”, “Security & location”,
“Encryption & credentials”, “Install from storage” (location may differ) is automatically pushed into the system’s trust store by this Magisk module. Reboot and verify that the CA certificate is listed in “Settings”, “Security & location”, “Encryption & credentials”, “Trusted credentials”
(location may differ).
Manually adding the Proxy’s certificate among system trusted CAs
Alternatively, you can follow the following steps manually in order to achieve the same result:
• Make the /system partition writable, which is only possible on a rooted device. Run the
‘mount’ command to make sure the /system is writable: mount -o rw,remount /system.
If this command fails, try running the following command mount -o rw,remount -t ext4 /system
• Prepare the proxy’s CA certificates to match system certificates format. Export the proxy’s certificates in der format (this is the default format in Burp Suite) then run the following commands:
$ openssl x509-informDER-incacert.der-outcacert.pem
$ openssl x509-informPEM-subject_hash_old -incacert.pem|head-1 mv cacert.pem<hash>.0
• Finally, copy the<hash>.0 file into the directory /system/etc/security/cacerts and then run the following command:
chmod 644<hash>.0
By following the steps described above you allow any application to trust the proxy’s certificate, which allows you to intercept its traffic, unless of course the application uses SSL pinning.
Potential Obstacles
Applications often implement security controls that make it more difficult to perform a security review of the application, such as root detection and certificate pinning. Ideally, you would acquire both a version of the application that has these controls enabled, and one where the controls are disabled. This allows you to analyze the proper implementation of the controls, after which you can continue with the less-secure version for further tests.
Of course, this is not always possible, and you may need to perform a black-box assessment on an application where all security controls are enabled. The section below shows you how you can circumvent certificate pinning for different applications.
Client Isolation in Wireless Networks
Once you have setup an interception proxy and have a MITM position you might still not be able to see anything. This might be due to restrictions in the app (see next section) but can also be due to so called client isolation in the Wi-Fi that you are connected to.
Wireless Client Isolationis a security feature that prevents wireless clients from communicating with one another. This feature is useful for guest and BYOD SSIDs adding a level of security to limit attacks and threats between devices connected to the wireless networks.
What to do if the Wi-Fi we need for testing has client isolation?
You can configure the proxy on your Android device to point to 127.0.0.1:8080, connect your phone via USB to your host computer and use adb to make a reverse port forwarding:
adb reverse tcp:8080 tcp:8080
Once you have done this all proxy traffic on your Android phone will be going to port 8080 on 127.0.0.1 and it will be redirected via adb to 127.0.0.1:8080 on your host computer and you will see now the traffic in your Burp. With this trick you are able to test and intercept traffic also in Wi-Fis that have client isolation.
Non-Proxy Aware Apps
Once you have setup an interception proxy and have a MITM position you might still not be able to see anything. This is mainly due to the following reasons:
• The app is using a framework like Xamarin that simply is not using the proxy settings of the Android OS or
• The app you are testing is verifying if a proxy is set and is not allowing now any communica- tion.
In both scenarios you would need additional steps to finally being able to see the traffic. In the sections below we are describing two different solutions, bettercap and iptables.
You could also use an access point that is under your control to redirect the traffic, but this would require additional hardware and we focus for now on software solutions.
For both solutions you need to activate “Support invisible proxying” in Burp, in Proxy Tab/Options/Edit Interface.
iptables
You can use iptables on the Android device to redirect all traffic to your interception proxy. The following command would redirect port 80 to your proxy running on port 8080
iptables-tnat-AOUTPUT-ptcp--dport80-jDNAT--to-destination<Your-Proxy-IP>:8080
Verify the iptables settings and check the IP and port.