iOS data interception
Network traffic analysis is an important ingredient of a good iOS app pentest. The article covers several common approaches to iOS specific data interception such as network proxying, defeating network encryption, traffic injection and others. It is assumed that you own and control the iOS device so attacks involving rogue data interception (e.g. arp poisoning, rogue access points, etc.) will not be covered here.
The most basic passive data analysis approach involves standard network sniffing tools such as tcpdump or Wireshark. Your exact set up will vary based on the point where the sniffer is set up — on the mobile device itself or somewhere on the network.
Capturing on the iOS Device
In order to sniff on the iOS device itself you will need root privileges which is typically achieved through jailbreaking. The most common tool for data interception is tcpdump which is available as a package from Cydia. This tool can be used it to capture traffic from both WiFi and Cellular interfaces.
root# tcpdump -i en0 -w ios.pcap
The command above illustrates a basic capture of all network traffic on the wireless interface en0 to a file ios.pcap. In order to view captured data in more detail you will have to transfer the file to a computer with a graphical packet capture viewer such as Wireshark.
The above process of capturing and transferring packet captures can be a bit tedious. However, it is possible to greatly simplify this process by piping tcpdump output on the iOS device to a local machine where it can be viewed by Wireshark in realtime. To get this working, you must redirect tcpdump output to a local pipe and use Wireshark in pipe mode to view traffic.
The commands below use netcat as a network intermediary in order to pipe data to Wireshark. You will need to install netcat package from Cydia.
First setup a netcat listener and pipe received data to Wireshark as follows:
$ wireshark -k -i <(nc -l 7777)
Next, on the iOS device itself start tcpdump in pipe output mode and pipe output to LINUXHOST using netcat:
ios:~ root# tcpdump -nn -w - -U -s 0 "not port 7777" | nc LINUXHOST 7777
The Wireshark Wiki discusses yet another approach. You will need to install openssh package on the iOS device and a Linux host for this to work. This technique works by creating a named pipe /tmp/pipe on a Linux host and instructing a remote iOS device to send tcpdump output to that pipe:
$ mkfifo /tmp/pipe
$ ssh root@iOSDEVICE "tcpdump -nn -w - -U -s 0 -w - not port 22" > /tmp/pipe
In another terminal execute Wireshark to read the above named pipe:
$ wireshark -k -i /tmp/pipe
A similar capture can be performed on a Windows host using ADVsock2pipe application as an intermediary between a remote tcpdump session and a locally running Wireshark instance. You will need to install .NET Framework 4 for the tool to work.
Execute ADVsock2pipe application on a Windows host to redirect all incoming data on port 7777 to a local named pipe wireshark:
C:\ADVsock2pipe\ADVsock2pipe.exe --pipe=wireshark --port 7777
Next, start Wireshark and select Local, \.\pipe\wireshark named pipe interface for capture.
With the Wireshark host set up and waiting for data, the following command will start forwarding captured traffic on the mobile device:
ios:~ root# tcpdump -nn -w - -U -s 0 "not port 7777" | nc WINHOST 7777
NOTE: many iOS devices have multiple network interfaces. The most convenient interface for penetration testing is wireless; however, all of the above techniques will work for cellular connections with the exception that you need to worry about how to access the device locally and how to position a host running Wireshark on the Internet.
Capturing on the Network Gateway
In case where packet capturing on the iOS device itself is not an option it is possible to monitor the traffic on a network gateway. Assuming you have full control of the device, you can simply set network gateway as an arbitrary host on the local network which you control. If that’s the case then there is always ARP Spoofing.
Here is a sample configuration which uses 192.168.1.101 as a gateway:
Follow these OS specific configuration steps to enable IP forwarding functionality on the gateway:
On Linux, BSD and OS X gateways you will have to edit /etc/sysctl.conf file and add or uncomment the following line:
Next you can either restart the computer or force the change to be applied:
Alternatively you can enable IP forwarding temporarily with the following command:
sysctl -w net.ipv4.ip_forward=1
On a Windows gateway you will have to set the following registry key to 1 in order to enable the IP forwarding functionality:
All traffic will be forwarded after the Windows host is rebooted.
NOTE: Depending on the configuration you may need to disable or configure the firewall in order for the IP forwarding to work.
With all of the traffic flowing through the network gateway, it should now be possible to monitor all iOS device network data.
Capturing using VPN
If the above method does not work there is yet another approach to intercepting mobile app traffic using iOS’ VPN mechanism. One advantage of this approach over manually configuring LAN gateway is that it is now possible to monitor traffic over cellular connections since gateway IP may not be possible to set.
First let’s install and configure pptpd package on a machine which will be used for the VPN server. On a Debian based system it is sufficient to run the following command:
sudo apt-get install pptpd
After successfully installing pptpd, next step is to configure the service by adding the following two lines to /etc/pptpd.conf:
The above configuration limits the range of IP addresses allotted to VPN clients to 192.168.10.100–254. Notice that these IP ranges are completely arbitrary belonging specifically to the VPN service and not necessarily to the LAN range (192.168.1.0/24). VPN clients are configured to use 192.168.10.1 as their gateway.
Now let’s set some additional pptpd options in the /etc/ppp/pptpd-options:
By adding these two lines we are telling VPN clients which DNS servers to use. An astute reader such as yourself will quickly notice that this option could be used to more precisely intercept data using a rogue DNS server, which will be covered in the section below.
The last option that needs to be configured is the vpn username and password. This can be achieved by editing the /etc/ppp/chap-secrets configuration file:
# Secrets for authentication using CHAP
# client server secret IP addresses
iphelix pptpd password *
Since we want VPN clients to get out beyond local network so we could intercept network data, you will also need to set up IP forwarding and IP masquerading as follows:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
Where eth1 is the WAN interface on the VPN server.
At last restart the vpn service as follows
With the pptpd service up and running we are ready to configure the iOS device to use the service. Since I am experimenting on the local LAN, assume VPN server’s external IP address is 192.168.1.104. However, the configuration would work just as well for external public IP addresses. The screenshot below illustrates a sample VPN configuration and a subsequent connection:
At this point mobile device traffic will flow through the VPN and it can be intercepted on the VPN server.
Intercepting and Modifying Data
After the initial data analysis stage, you should be able to proceed with the next stage of penetration testing involving data tampering. Traditionally data tampering is performed using a proxy application such as Burp Proxy or with a custom application-specific program.
Let’s start with the simplest approach of simply configuring the iOS device to use an HTTP proxy and progress to more involved methods involving dns hijacking, VPNs and firewall black magic.
Wireless HTTP Proxy Configuration
Wireless HTTP proxy configuration is very straightforward. Simply go to Settings -> Wi-Fi -> Select right arrow button next to a preferred Access Point. In the HTTP Proxy section tap on Manual and select IP address and port of the host running proxy application. At this point all HTTP traffic will be routed through the proxy.
Cellular HTTP Proxy Configuration
While it is often easier to use a WiFi connection for penetration testing, you may encounter situations where it is not possible. Setting up an HTTP proxy on a cellular connection is a bit more tricky. As described in the Hacking and Securing iOS Applications book, it involves using the iPhone Configuration Utility (available for Windows and OS X) to create a custom configuration profile including cellular provider specific APN (Access Point Name) settings. One of the APN settings is a Proxy Server and Port which can be used to proxy traffic iOS device traffic. The custom profile can be loaded on the iOS device using the iPhone Configuration Utility or exported and installed on the device through an email attachment or as a downloaded file.
The screenshot below illustrates a sample APN configuration with a proxy IP and port configured to a publicly available proxy server.
The configuration above was confirmed to work for AT&T iOS devices. Unfortunately, I was not able to achieve the same effect on the Verizon network where Proxy settings were simply ignored.
VPN HTTP Proxy Configuration
In cases where you can’t set HTTP proxy or your setting is simply ignored, it is still possible to force an HTTP proxy using a VPN connection. Let’s revisit the iOS VPN configuration screen. On the very bottom of the screen there is a Proxy portion which we will simply configure to an IP address with a MiTM proxy running (in this case it’s the same as the VPN server):
The screenshot above illustrates a sample VPN proxy configuration as well as an intercepting proxy capturing VPN proxy traffic.
SSL and Man in the Middle
It is often the case where a particular iOS application checks the validity of certificates thus defeating the above proxy set up. This issue can be detected by observing the SSL handshake which will show client dropping the connection immediately after the proxy host submits a self-signed server certificate. This issue can be addressed by obtaining a self-signed CA for the proxy application and manually installing it on the device.
Depending on the exact challenge you will have to either generate a new self-signed CA or obtain an already existing one from one of the proxy tools. For example, in case of Burp you can follow instructions on the Server SSL Certificates Help page to obtain PortSwigger CA self-signed certificate.
There are several approaches regarding certificate installation on the iOS device. The easiest one is probably sharing the certificate file on a web server and simply opening it using Safari. You can also email the certificate as an attachment and install it by clicking on the attachment. At last, the iPhone Configuration Utility can be used to install the certificate on the device over a USB connection.
The screenshot below shows a sample iOS notification when attempting to install a self-singed certificate:
With a self-signed certificate installed it may now be possible to intercept SSL connections made by the picky iOS application.
Not all iOS applications honor HTTP proxy settings. In certain situations you may need to rely on the DNS Hijacking approach . The traditional approach of editing /etc/hosts file on the device may not work for you depending on the level of access to the device. However, it is still possible to manually edit the DNS server entry for WiFi connections and point it to a DNS server that you control:
In the case of a PPTPD VPN covered above, it is also possible to supply a rogue DNS server by configuring the /etc/ppp/pptpd-options configuration file on the VPN server:
There are several options regarding which DNS server to choose all depending on the specific application needs. I have developed DNSChef for this purpose.
DNSChef - DNS proxy for Penetration Testers and Malware Analysts - iphelix/dnschef
Here is a sample traffic capture session using this tool where we attempt to fake only responses for google domains to point to 192.168.1.100 for analysis:
# ./dnschef.py --interface 0.0.0.0 --fakeip 192.168.1.100 --fakedomains *.google.com
_ _ __
| | version 0.1 | | / _|
__| |_ __ ___ ___| |__ ___| |_
/ _` | '_ \/ __|/ __| '_ \ / _ \ _|
| (_| | | | \__ \ (__| | | | __/ |
\__,_|_| |_|___/\___|_| |_|\___|_|
[*] DNS Chef started on interface: 0.0.0.0
[*] Using the following nameservers: 220.127.116.11
[*] Cooking replies to point to 192.168.1.100 matching: *.google.com
[00:44:03] 192.168.1.123: proxying the response of type 'A' for ax.init.itunes.apple.com
[00:44:03] 192.168.1.123: proxying the response of type 'A' for p15-buy.itunes.apple.com
[00:44:03] 192.168.1.123: proxying the response of type 'A' for ax.su.itunes.apple.com
[00:44:11] 192.168.1.123: cooking the response of type 'A' for www.google.com to 192.168.1.100
There are several other utilities which may be useful such as Mandiant’s ApateDNS and a Metasploit auxiliary module FakeDNS.
Continuing the above example where we faked the DNS response for the www.google.com, you will now have to set up a proxy server on 192.168.1.100 in order to intercept the request and forward it to the real Google server. The following screenshot illustrates a BURP proxy configuration page which accomplishes just that:
The above configuration shows a new listener on port 80 which will intercept all incoming requests and forward the real www.google.com host also on port 80. As soon as you will try to access that domain on the iOS device, you will see incoming requests on the Burp proxy.
At this point you should be able to capture and analyze most of the applications running on the iOS platform. However, as always there is going to be this one app that resists all of your attempts. In cases like these, you will need to go further down the network stack and intercept application traffic on the network layer.
First, configure the iOS device with an IP address of an intercepting gateway and enable IP forwarding as was discussed in the Capturing on the Network Gateway section above. Alternatively, configure the iOS device to use your VPN server and use the gateway you control to intercept data, as described in the Capturing using VPN section above.
Now let’s intercept all port 80 traffic using the following iptables command:
iptables -t nat -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8888
The above firewall rule will reroute all web traffic to a local port 8888 on the intercepting gateway.
At this point you have to configure some kind of a listener in order to intercept and forward traffic. Once again, Burp is a great tool for the job.
Let’s configure a new Burp proxy:
Notice, the proxy was configured as an invisible proxy setting listening on all interfaces on port 8888. With the proxy running you will now be able to intercept and modify all port 80 traffic whether iOS application supports a proxy or not:
Another excellent gateway proxy tool specifically designed for mobile application pentesting is Mallory. The tool used to be slightly painful to install; however today it is sufficient to download and run installation script from the following location:
NOTE: The installation requires quite a large number of additional packages so you may want to install the tool on a dedicated VM (e.g. Backtrack)
After the installation, execute mallory.py and launchgui.py in separate consoles, select the Interfaces tab in the GUI and apply MiTM configuration as follows:
This will generate and apply iptables rules equivalent to the one documented above with the exception that the rule will capture and redirect all traffic regardless of target host or port. Mallory will be able to dynamically intercept traffic and allow you to edit traffic programmatically through its rules API or visually using GUI:
See Mallory webpage for the complete documentation on this awesome tool.
Where to go from here
At this point you should be equipped with plenty of tools and techniques to intercept most network traffic generated by iOS apps in order to perform deeper security assessments. Be mindful that even though it may seem enticing to set up an intercepting gateway with custom protocol dissectors it is often easier to simply configure a proxy server, so try the easiest approach first.