During a recent mobile application engagement, the Triskele Labs Penetration Testing team came across an application built with the Xamarin framework. Xamarin is an application platform for building Android and iOS apps with .NET and C#. This differs from traditional mobile applications frameworks where Android applications are usually developed in Java or Kotlin and iOS applications are developed separately in Swift or Objective-C. Even though there are similarities in mobile testing methodologies for these frameworks, Xamarin introduces challenges in certain areas for penetration testers, such as proxying traffic between the application and its backend server. Using a proxy to intercept network traffic to and from the mobile application is a crucial part of any mobile app penetration testing, as network communication and interaction with backend servers is an integral component of any application. In this post, we’ll discuss a method utilised by the Triskele Labs Penetration Testing team to intercept network traffic from applications developed with modern frameworks such as Xamarin, which ignore system proxy settings by default. First, we will give some background for mobile application network traffic interception and the Xamarin framework – if you are only interested in the Xamarin bypass method, skip to the “Bypassing Xamarin Protections” section!
Xamarin, which is a Microsoft product, provides a single platform to develop one application for multiple platforms – iOS and Android in most cases. Additionally, Microsoft has already implemented secure coding practices in the Xamarin framework. As such, applications developed with this framework inherit these security controls. This makes Xamarin–based applications arguably more secure than applications developed from scratch using traditional or no frameworks. Since Xamarin has full access to native APIs and toolkits used by both iOS and Android applications, it not only saves developers time in building and maintaining the application, but also help them in achieving near-native look and performance.
Mobile Apps and APIs
Developers often utilise Application Programming Interfaces (APIs) to facilitate the operation of a mobile app. Most commonly, these APIs operate using HyperText Transfer Protocol Secure (HTTPS), much like a web application. By relying on server-side processing and storage, the developer minimises data storage on the mobile device. This frees up space and processing power on the device and is also more secure because it minimises sensitive information stored on a device. APIs are used for functions such as authentication, authorisation, data transfer and other interactions between the server and the mobile applications. While the use of APIs reduces the attack surface of the mobile device itself, it introduces new attack vectors through the network communication and server processing of information. Additionally, vulnerabilities in the API generally have a higher impact and severity compared to native mobile vulnerabilities as the API handles sensitive data and provides access to many server-side functionalities, often utilised by many users. To discover and exploit these vulnerabilities, an attacker can use a local proxy to intercept communications between the mobile app and the server. A proxy allows the attacker to inspect, modify, repeat and understand how the mobile app communicates with the server, and how the server might react to unexpected or untrusted data.
Most modern frameworks such as Xamarin provide inbuilt solutions to limit an attacker’s ability to intercept communications with a proxy. These protections include Certificate pinning and/or ignoring system proxy settings. As is the case with all client-side mobile app protections however, these protections can be bypassed if an attacker has full control over the device.
Xamarin Proxy Interception Protections
Now that we have an understanding of Xamarin–based mobile apps and how they communicate with APIs, let’s take a look at how Xamarin attempts to prevent this communication and how it can be bypassed.
Traditionally for encrypted communication using HTTPS, trust is established by a server obtaining a certificate from a Certificate Authority (CA), which is an inherently trusted entity. The server then presents this certificate for verification when an encrypted connection is established so that the client knows the server is the intended recipient of any data the client might want to send. The client verifies the server’s certificate by checking it against a local certificate store. For an attacker to intercept this encrypted communication with a local proxy then, it is a simple matter of installing the attacker’s certificate into this trusted local store then changing the device’s network settings to use this proxy.
However, a protection introduced by Xamarin is setting the client app to ignore device proxy settings. As previously mentioned, to route application traffic through an intercepting proxy such as Burp or mitmproxy, a system proxy has to be set on the device. Because Xamarin ignores the mobile device proxy settings by default, it is difficult for an attacker to redirect network traffic in this way.
Bypassing Xamarin Protections
As the device’s proxy settings could not be used, the Triskele Labs Penetration Testing team needed an alternate method of routing and intercepting network traffic. To achieve this, the team utilised an AWS Ubuntu EC2 instance with OpenVPN and mitmproxy installed. This method was successful because it allowed the team to ignore device proxy settings and restrictions, and instead redirect all network traffic for the device to a single location, in which it could be intercepted, decrypted and inspected.
The following steps were performed to accomplish this:
- Launch an Ubuntu EC2 instance on AWS. You may use the cloud platform of your choice, however, ideally the server should have a public IP address.
- Once launched, install OpenVPN on the server and create a .ovpn client configuration file and transfer and install it on the mobile device.
- Install OpenVPN client software was on the mobile device.
- The mitmproxy certificate needs to be installed on the device, with full trust for the root certificate on iOS and Android. The internet is full of great resources on how to achieve this.
- Next, on the VPN server, enable IP forwarding and disable Internet Control Message Protocol (ICMP) redirects. This can be accomplished by executing:
- sysctl -w net.ipv4.ip_forward=1
- sysctl -w net.ipv6.conf.all.forwarding=1
- sysctl -w net.ipv4.conf.all.send_redirects=0
- Followed by setting iptables rules to redirect traffic from the VPN tunnel interface ‘tun0’ to mitmproxy:
- iptables -t nat -A PREROUTING -i tun0 -p tcp –dport 80 -j REDIRECT –to-port 8080
- iptables -t nat -A PREROUTING -i tun0 -p tcp –dport 443 -j REDIRECT –to-port 8080
- Finally, start mitmproxy in transparent mode. By default, mitmproxy runs on port 8080:
- mitmproxy –mode transparent –showhost
You should now be able to observe the application traffic flowing through mitmproxy. Certificate pinning might need to be disabled or bypassed as well if this is implemented. This can be another challenge in itself and may be the topic of a future blog post, but in most cases, can be accomplished using Objection’s sslpinning disable functionality.
Mobile applications have a very restricted attack surface which makes gaining visibility over API calls all the more valuable. In this case, the team was able to go from a few low and medium severity mobile findings to discovering an Insecure Direct Object Reference (IDOR) which disclosed sensitive information about application users. To demonstrate the severity of this type of vulnerability, Paypal recently paid 10,500 USD for an IDOR vulnerability disclosure (https://hackerone.com/reports/415081).
Obfuscation is never a sufficient mechanism and can always be circumvented. Client-side protections for a mobile device can always be bypassed because the attacker can use jailbreaking or device rooting to ultimately control all client-side aspects. As such, code can be decompiled, device stores altered, runtime calls exploited and more. Despite this, it is important for a mobile app to protect itself with as many layers of security as possible, to discourage attackers and to protect users where possible. Furthermore, although these protections can be bypassed by a sophisticated or motivated attacker, they can significantly impede vulnerability discovery and add to the defence-in-depth approach to security employed by the developers.
As such, mobile apps should follow best practices such as certificate pinning, implementing runtime protections and root/jailbreak detections to make traffic interception as difficult as possible for an attacker, to mitigate the risk of intercepting and modifying application traffic and functionality. There are many libraries and frameworks that can be utilised for this purpose – ensure the most appropriate is chosen for your platform and application!
Links & Resources