How to SSH to a Jailbroken iOS Device over USB
I recently had to set up testing against our Akamai Staging environment which uses a different IP address than production. This required me to get a new MacBookPro that would support the latest version of MacOS, as well as the latest version of Xcode, just so that I could have
sudo access to change add an entry in
/etc/hosts in order to build the application from source and run it in the iOS simulator (since the Simulator doesn’t come packaged with the iOS AppStore). Then I had to carry around another computer in my backpack simply because I refuse to separate from Arch Linux and i3-gaps (which can perfectly emulate the Android version without issues), but I digress…
I quickly realized that since I have a jailbroken iPhone, which is required for SSLKillswitch in order to pentest iOS mobile apps that use HPKP (otherwise known as certificate pinning or SSL pinning), it would be much easier to just carry that device with me and have a hosts entry on that device since it always has access to the iOS AppStore…and iPhones weigh much less than a 17″ MacBookPro. Mind you, I came up with this idea after virtualizing MacOS Mojave on my ESXi host, which stole the majority of the RAM, just so I could run an Appium login script against the simulator remotely over SSH. A great idea in theory, but a pain in the ass in practice.
So finally after charging this iPhone 6 running the vastly-outdated iOS version 9.2, and then after regaining my old Yalu jailbreak via some sort of nasty Mobile Safari workaround, I opened up the iOS Terminal app installed from the BigBoss Cydia repo and realized I didn’t have
nano, or any editor installed, whatsoever. Before realizing I was an idiot and could simply
echo -e the host entry and append it to
/etc/hosts, I decided that “my fingers are to big for this shit,” and decided to SSH into the phone instead. That’s when I remembered that the Yalu jailbreak uses Dropbear or something instead of OpenSSH and for whatever reason only listens on localhost. I had to do something about this, and my thumbs were not prepared for all of the
sed work involved in
/etc/ssh/sshd_config, so I decided to re-figure out how I had SSH’d to my iPhone over USB the last time I decided to do this, and this time, I would document the process. Since I regularly run both Linux and MacOS, I will handily-dandily document the process for using both.
Note: This is not just practical for a stupid implementation of SSH that only listens on localhost — it also comes in handy if your iPhone is not available over the network or you happen to be in a “what happened to the WiFI” situation.
If you don’t have Homebrew installed, what’s wrong with you? Go ahead and install that lifesaver:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
libimobiledevice view Homebrew:
brew install libimobiledevice
Hook your jailbroken iPhone up to your Mac via USB, agree to the popups asking for trusted access to the device, yada-yada, and then open a couple of terminal tabs.
In the first tab, run the following command:
iproxy 2222 22
In the second tab, go ahead and SSH to your device via your newly-accessible localhost port 2222:
ssh -p 2222 root@localhost
If you are feeling like a superuser and want to go to the trouble of killing the
iproxy process later on or just letting that sucker run until the next reboot, the steps above can be achieved by running both commands in a single tab or window like so:
(iproxy 2222 22 >/dev/null 2>&1)& >/dev/null 2>&1 ssh -p 2222 root@localhost
^ Also note that you can never have enough output redirection to
/dev/null if you’re like me and always forget which side of the parenthesis to put that mess on and don’t want the output of the
iproxy command cluttering up your SSH session. Feel free to remind me in the comments since I feel like it would be a valuable waste of Googling time.
Using Linux or Windows
Plug in your iPhone and agree to all the annoying pop-ups.
Install the requirements:
sudo apt-get install libimobiledevice* sudo apt-get install libgcrypt20-doc gnutls-doc gnutls-bin usbmuxd
sudo pacman -Sy libimobiledevice usbmuxd
If you use ActivePython, YMMV. It will work, but you may have to tweak a couple of my instructions below. On most of my Windows machines, I actually maintain separate installations of ActivePython2, ActivePython3, as well as installations of python2 and python3 installed via Cygwin. They all have their special use cases. It helps that you can also install Git via Cygwin, and the syntax below may be slightly different, but I trust you to figure it out. Don’t even talk to me about Windows Subsystem for Linux (WSL). Get out of here with that mess. Cygwin FTW.
Clone the Git repo
The utility you will be using requires Python 2.7. So if you are still living in 2007, that shouldn’t be an issue. Otherwise, you’re going to need to explicitly specify it in your command if your default is Python3. I actually forked the repo and tried to convert the code to Python3, but the strings-to-bytes conversion is ridiculously manual and time-consuming.
Edit: I actually succeeded in resurrecting this decade-old project and now personally maintain the only version (to the best of my knowledge) that is compatible with both Python2 and Python3 and works on all versions of Linux, MacOS, and Windows! You can check out pyusbmux here on GitHub!
git clone https://github.com/phx/pyusbmux.git cd pyusbmux/python-client/ chmod +x * ./tcprelay.py -t 22:2222
In another terminal tab or window, now you can SSH to your USB-connected iOS device:
ssh -p 2222 root@localhost
Actually, that’s really all there is to it. If this is your first time SSH’ing into your iOS device, you’ll obviously want to run
passwd to change the root password from
alpine to whatever you want. Happy SSH’ing in niche situations!