Skip to main content

iOS Local Server

Generally, iOS would not have an app that has an active service (listener) running on it. However, it is possible that an app is running its own web server in order to serve up content by a reverse proxy. This is rare, but does happen. During a penetration testing engagment, you should look to see if the app accepts incoming connections.

Determining if the app is running as a server, check the ports that the device is listening on before the app is launched and then again after.

# netstat -an | grep -iw listen
tcp46 0 0 *.49785 *.* LISTEN
tcp4 0 0 127.0.0.1.27042 *.* LISTEN
tcp4 0 0 *.22 *.* LISTEN
tcp6 0 0 *.22 *.* LISTEN
tcp4 0 0 *.62078 *.* LISTEN
tcp6 0 0 *.62078 *.* LISTEN

Run the same command after starting up the iOS app:

# netstat -an | grep -iw listen
tcp46 0 0 *.8080 *.* LISTEN
tcp4 0 0 *.8080 *.* LISTEN
tcp46 0 0 *.49785 *.* LISTEN
tcp4 0 0 127.0.0.1.27042 *.* LISTEN
tcp4 0 0 *.22 *.* LISTEN
tcp6 0 0 *.22 *.* LISTEN
tcp4 0 0 *.62078 *.* LISTEN
tcp6 0 0 *.62078 *.* LISTEN

We can see from the output after starting the app that there are two new entries (one for TCPv4 & one for TCPv6) running on port 8080.

We can also see that the service listening on port 8080 is bound to all interfaces on the device, as evident by the asterick in front of the port:

*.8080
*.8080

Essentially, anyone on the same network as the device - either Wi-Fi or Cellular - would be able to craft a request to send to the device (app) which would be accepted.

While there is a very good chance this port is from our app (since it showed up after starting it), let's validate that to make sure:

# lsof -i :8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
AppName 2256 mobile 6u IPv4 0xf8555c5c0d2a31b9 0t0 TCP *:http-alt (LISTEN)
AppName 2256 mobile 7u IPv6 0xf8555c5c0d28ef79 0t0 TCP *:http-alt (LISTEN)

From the output, we can see that the service is listed as http-alt and the command is AppName (which we will say is the name of our app).

Next, place the app in the background and see if the listening port goes away or if it is still persistent on the device. You will want to understand how the app behaves and the exposure of that port.


For good measure, let's run an nmap scan on it to verify that it accepts the requests. In the example below, 192.168.0.179 is the IP address of the device on a Wi-Fi network.

% sudo nmap -sS -p8080 192.168.0.179
Starting Nmap 7.93 ( https://nmap.org ) at 2022-09-11 15:38 EDT
Nmap scan report for 192.168.0.179
Host is up (0.081s latency).

PORT STATE SERVICE
8080/tcp open http-proxy
MAC Address: B2:27:89:70:89:89 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 0.19 seconds

Once we are confident that the app we are testing is the source of the listening port, take a look at the frameworks & libraries that the app is using to see if you can determine which package is implementing this behavior.

Typically, these will be in the Bundle/Frameworks directory for the app on the device.

# the app bundle in /private/var/containers/Bundle/Application/{UUID}/AppName.app
cd ${BUNDLE}

cd Frameworks
ls -l


Common Ports

TCP PortService
22sshd
1080socks
1083ansoft-lm
8021intu-ec-client
27042frida-server
49202rapportd