Skip to main content

SSH and libimobiledevice

Two ways of talking to the device under test: SSH (mostly on jailbroken devices) and the libimobiledevice suite over USB. This page covers both and how they combine for USB-tunneled SSH.

libimobiledevice Basics​

libimobiledevice talks to the device over the USB usbmuxd channel without needing iTunes or Xcode pairing GUIs.

# Core utilities (from libimobiledevice / libimobiledevice-utils)
idevice_id -l # list connected devices
ideviceinfo # full device info
idevicedevicebattery # battery state (jailbreak-free)
idevicesyslog # stream device logs

# Pairing
idevicepair validate
idevicepair pair

usbmuxd is the daemon that multiplexes the USB connection. It runs automatically on macOS; on Linux start it with:

sudo systemctl start usbmuxd
sudo usbmuxd --systemd # or foreground for debugging

SSH to a Jailbroken Device​

Jailbroken devices (checkra1n, palera1n, Dopamine, etc.) ship an OpenSSH server on port 22. Two users exist:

  • root — UID 0, full filesystem access. Default password is usually alpine (change it).
  • mobile — the mobile user, runs app processes, most app data lives under /var/mobile.
# Direct over Wi-Fi/LAN (device must be on the same network as the host)
ssh root@<device-ip>

# Over USB using iproxy (no network needed) in another terminal:
iproxy 2222 22
# Then connect via localhost
ssh root@localhost -p 2222
ssh mobile@localhost -p 2222

Managing the SSH key / password​

# First connection will prompt for the password (default: alpine)
ssh root@localhost -p 2222
# Change it immediately
passwd

Practical USB SSH Workflow​

The most common combination for a wired assessment:

# Terminal 1: forward device SSH to localhost:2222
iproxy 2222 22

# Terminal 2: shell into the device
ssh root@localhost -p 2222

# Sanity checks once inside
uname -a
sw_vers # iOS version
id # uid=0(root)
ls /var/mobile/Library # app data, preferences
ls /etc/apt/sources.list.d # Cydia/Sileo sources

File Transfer​

# Copy files to/from the device over the USB tunnel
scp -P 2222 root@localhost:/var/mobile/Containers/Data/Application/<UUID>/Documents/db.sqlite .
scp -P 2222 ./app.ipa root@localhost:/tmp/

# rsync if installed on the device
rsync -avz -e "ssh -p 2222" root@localhost:/var/mobile/Media/ ./media/

Keychain and Sensitive Data​

Over SSH you can read app preferences and, with the right tooling, the keychain.

# Plist preferences for an app
plutil -p /var/mobile/Library/Preferences/com.example.app.plist

# Keychain dump via a jailbreak tool (e.g. keychain_dumper)
/usr/bin/keychain_dumper -a

These dumps only work on jailbroken devices and require the appropriate entitlements/tools.

When You Cannot Use SSH​

Non-jailbroken devices have no SSH. Your options:

  • Use idevicedebug run and idevicesyslog for basic interaction.
  • Use Frida in gadget mode (injected into the IPA) for instrumentation.
  • Use iproxy for generic TCP port forwarding to apps that expose a local service.
  • Extract the IPA with ideviceinstaller/cfgutil for offline static analysis.
# Generic TCP forward to an app's local port without SSH
iproxy 5555 5555 # forward device 5555 -> localhost 5555
# Then connect to the service on localhost:5555

Port Mapping Quick Reference​

DirectionLocalDeviceCommand
SSH over USB222222iproxy 2222 22
App debug / custom service44444444iproxy 4444
Range forward8000-80108000-8010iproxy 8000:8010

Gotchas​

  • Default root password alpine is a finding in itself if left unchanged — note it in reports.
  • usbmuxd must be running or idevice*/iproxy will fail with "No device found".
  • After a device reboot, re-run idevicepair validate; then restart iproxy.
  • iOS 17+ jailbreaks are mostly rootless; paths differ (/var/containers/... vs /var/mobile/...). Confirm with find.