The Proxy Fight, or How to Pentest an iOS App's Backend through an Existing VPN Connection

Have you ever been wondering how to pentest a mobile App backend that is only available through an existing VPN connection? This is often the case when it comes to assess the security of in-house developed enterprise Apps. Usually, company-owned devices first need to establish a VPN connection to the company’s intranet in order to access data from internal backend systems. While this is a good design decision from a security perspective, it makes a penter’s life a misery: As soon as a VPN connection is established, local LAN access is restricted. As a consequence, it is not as trivial as just configuring an HTTP proxy in your WiFi settings to man-in-the-middle between your App and the target web service.

To not waste too much time travelling in order to assess those web backends on site, the following steps provide you with a quick and comfortable solution to pentest iOS App’s web services easily from remote locations, although an existing VPN connection is required.

  1. Step 1 (on your host machine): Start your favorite intercepting proxy like Watobo, Burp, ZAP or the like (Port: 8080).

  2. Step 2 (on your host machine): Configure your intercepting proxy to forward outgoing requests to an upstream HTTP proxy server using the following settings: Server: 127.0.0.1. Port: 3128. In Burp e.g. these settings are defined within Options -> Connections -> Upstream Proxy Servers.

  3. Step 3 (on your iDevice): Go to Cydia and install the package 3proxy.

  4. Step 4 (on your iDevice): SSH into your iDevice and prepare a 3proxy configuration file:

    iDevice:~ root# cat /var/root/3proxy.cfg
    log /var/root/3proxy.log D
    logformat "%d-%m-%Y %H:%M:%S %U %C:%c %R:%r %O %I %T"
    proxy -p3128 -n
    
  5. Step 5 (on your iDevice): Run 3proxy on your iDevice:

    iDevice:~ root# 3proxy /var/root/3proxy.cfg &
    [1] 11755
    
  6. Step 6 (on your iDevice): Select your VPN configuration profile from the iOS Settings App (General -> VPN), scroll down to the Proxy settings and press “Manual”. Here we need to fill in the following configuration: Server: 127.0.0.1. Port: 8080 (this is the port on your host machine where your intercepting proxy is listening, see Step 1).

  7. Step 7 (on your host machine): Now comes the most critical stage. As access to the local network is restricted whenever a VPN connection is established, we need to SSH into the iDevice over USB using usbmuxd. For this, get the usbmuxd source package, unpack and run tcprelay.py.

    $ chmod +x ./usbmuxd-1.0.8/python-client/tcprelay.py
    $ ./usbmuxd-1.0.8/python-client/tcprelay.py -t 22:2222
    
  8. Finally, run the following command to establish a SSH connection to your iDevice over USB and to setup all required SSH port forwardings:

    $ ssh -p 2222 -L 3128:127.0.0.1:3128 -R 8080:127.0.0.1:8080 root@127.0.0.1
    

Overview of the proxy chaining setup.

Using this setup, every HTTP request originating from your iDevice is sent to the configured VPN proxy server first. The proxy server is nothing else than the intercepting proxy running on your host machine, just made accessible via the SSH tunnel over USB. After intercepting those HTTP requests, your intercepting proxy forwards them to the actual backend via the VPN connection using the 3proxy service running on your iDevice. From this point, you can proceed with your basic pentesting procedures and behave as if no VPN is present at all.

Please note that you might not be able to modify VPN proxy settings on your device, when the VPN profile was issued by a Mobile Device Management (MDM) solution. In this case, you need to adjust the VPN proxy configuration via the MDM interface. But beware of some MDM solutions that won’t accept “localhost” (or 127.0.0.1) as a valid proxy server setting.

Some MDM solutions like MobileIron are more restrictive on proxy server settings than iOS itself.

Figure 2 shows the related error message, when localhost is used as a VPN proxy setting within MobileIron. This restriction can easily be bypassed by setting up an alias for localhost in your iDevice’s /etc/hosts and by pointing your MDM to that alias.