Userland Details on Evasi0n Jailbreaking Tool Component

The tool created by the Evad3rs hackers supports iOS 6 jailbreak up to iOS 6.1.2. It is called Evasi0n and we can finally learn which exploits it has, how it works and see its userland details. It might be interesting for you to learn more about Evasi0n components because its exploits are completely different from the ones used for JailbreakMe and other tethered jailbreak methods.

This component is exclusive. It is based on the file system. Its name can tell you that the utility doesn’t attack exploit defenses but evades them. Its performance can be described as the three stages. We’ll talk about each of them in this post.

Evasi0n Component

About Evasi0n Userland Component

The tool is based on MobileBackup daemon that is capable of backing up and restoring backups on the Apple gadget. These backups are seen as untrusted data and in order to function the correct way the daemon uses MediaDomain along with a static path that can identify each file and correspond to the domain. The jailbreaking utility’s files are located within /var/mobile/Media.

Here is how the whole thing works.

Evasi0n Functionality: First Stage

At this point the tool creates a fresh backup to restore to Apple devices. It contains just the files listed below withing the MediaDomain.

  • directory: Media/
  • directory: Media/Recordings/
  • symlink: Media/Recordings/.haxx -> /var/mobile
  • directory: Media/Recordings/.haxx/
  • file: Media/Recordings/.haxx/
  • file: Media/Recordings/.haxx/
  • file: Media/Recordings/.haxx/
  • file: Media/Recordings/.haxx/[email protected]
  • file: Media/Recordings/.haxx/
  • file: Media/Recordings/.haxx/[email protected]
  • file: Media/Recordings/.haxx/Library/Caches/
  • The symlink in .haxx to /var/mobile is created to escape the MobileBackup domain’s normal path restriction. When the symlink appears all files in .haxx are restored not in /var/mobile/Media. They appear in /var/mobile and this method was used in different jailbreaking programs in the past.

An iOS program called lands in /var/mobile, complete with icons and other things needed. The plist becomes upgraded. This helps your Springboard to learn where the application lives in order to show it on your iPhone / iPad / iPod touch home screen. Don’t think that is an ordinary program. Unlike other iOS applications it contains a very peculiar main binary that consists of just the following:

  • #!/bin/launchctl submit -l remount -o /var/mobile/Media/mount.stdout -e /var/mobile/Media/mount.stderr — /sbin/mount -v -t hfs -o rw /dev/disk0s1s1

Here is some helpful information for Apple fans who are not familiar with UNIX shell scripts. In the command above, the content of the file tells the kernel to execute launchctl with those specific arguments because in these scripts the kernel looks at the first line of text files to determine the interpreter for the script.

Additionally, contains a peculiar section for, defining an environment variable to set when running it:

  • <key>EnvironmentVariables</key>
  • <dict>
  • <key>LAUNCHD_SOCKET</key>
  • <string>/private/var/tmp/launchd/sock</string>
  • </dict>

This last command tells your iOS gadget to reboot. It is necessary because your Springboard must pick up the program and show this to iPhone / iPod touch / iPad owner.

How evasi0n Works: Second Stage

This stage is long so it can be split up into three parts. Let’s name them Stage 2.1, 2.2 and 2.3. Here is what happens during each stage.


At this point, an empty backup is created. Your gadget gets more files restored.

  • directory: Media/
  • directory: Media/Recordings/
  • symlink: Media/Recordings/.haxx -> /var/db
  • symlink: Media/Recordings/.haxx/timezone -> /var/tmp/launchd
  • A new symlink is created. It is called /var/db/timezone that points to /var/tmp/launchd.
  • The normal permissions on /var/tmp/launchd are:
  • drwx—— 2 root   wheel  102 Feb  4 12:17 launchd

Such permissions usually prevent apps running as user mobile from descending into this directory.

What happens next? The jailbreaking tool tells the user it is stroking lockdownd. In other words, Evasi0n sends a malformed PairRequest command to lockdownd, the main daemon that operates on commands received over USB, and is used to start/stop other services, such as MobileBackup and AFC. Most jailbreaking programs use lockdownd because users are able to “talk” to it while it runs as root and abuses to do unplanned tasks.

The 1st vulnerability is lockdownd, framework or an underlying library. It’s hard to say for sure. We just know that sending lockdownd a malformed PairRequest command, causes lockdownd to chmod 777 /var/db/timezone so that it is accessible to the device and its owners.


This stage drills down further into /var/tmp/launchd modifying the permissions in the system so that users can access the launchd socket. What happens here? The timezone symlink is changed as described below:

  • Symlink:  Media/Recordings/.haxx/timezone -> /var/tmp/launchd
  • To
  • Symlink:  Media/Recordings/.haxx/timezone -> /var/tmp/launchd/sock
  • Then evasi0n sends another malformed PairRequest packet to lockdownd, causing /var/tmp/launchd/sock to become accessible to the mobile user.


At the beginning of this stage, your device gets a Cydia and packagelist tarfile uploaded to it. Whoever is jailbreaking his or her device is asked to launch the Jailbreak app which did this:

  • #!/bin/launchctl submit -l remount -o /var/mobile/Media/mount.stdout -e /var/mobile/Media/mount.stderr — /sbin/mount -v -t hfs -o rw /dev/disk0s1s1
  • With the environment variable
  • LAUNCHD_SOCKET = /private/var/tmp/launchd/sock

If you read main launchctl, you will see that the submit command is described like this:

submit -l label [-p executable] [-o path] [-e path] — command [args]

A simple way of submitting a program to run without a configuration file. This mechanism also tells launchd to keep the program alive in the event of failure.

  • -l label
  • What unique label to assign this job to launchd
  • -p program
  • What program to really execute, regardless of what follows the — in the submit sub-command.
  • -o path
  • Where to send the stdout of the program.
  • -e path
  • Where to send the stderr of the program.

Users who take a look at the manpage for launchd, see this variable:


It is exported when invoking a command via the launchd command line. It tells launchctl how to find the correct launchd socket for communications.

Launchd’s IPC mechanism operates through unix domain sockets. There are also multiple launchd processes, for example, there is one running as root and one running as mobile on iOS platform. So the user, as mobile, is executing launchctl via However, launchctl is not communicating to the device user’s launchd. It is communicating directly to the root user’s launchd, via the launchd socket that was exposed via UNIX permissions using the /var/db/timezone vulnerability.

The root user’s launchd runs as root. Thus the job remaps the system partition as read-write. It also lets the exploit to make persistent changes on the system partition that will execute as root in the early boot environment.

How Evasi0n Jailbreak Components Work: Third Stage

This is the last part of the article that explains how Evasi0n tool operates. It starts with jailbreak accessing the system partition through MobileBackup:

  • directory: Media/
  • directory: Media/Recordings/
  • symlink: Media/Recordings/.haxx -> /
  • symlink: Media/Recordings/.haxx/private/etc/launchd.conf -> /private/var/evasi0n/launchd.conf
  • directory: Media/Recordings/.haxx/var/evasi0n
  • file: Media/Recordings/.haxx/var/evasi0n/evasi0n
  • file: Media/Recordings/.haxx/var/evasi0n/amfi.dylib
  • file: Media/Recordings/.haxx/var/evasi0n/udid
  • file: Media/Recordings/.haxx/var/evasi0n/launchd.conf

It might look confusing because push files are used through symlinks. But the whole thing above leads to a directory creation at /var/evasi0n that contains an executable, library, and new launchd.conf described as:


launchd.conf contains a list of subcommands (load, unload, etc.) to run via launchctl(1) when launchd(8) starts.

The replacement launchd.conf, which will run at each boot, contains:

  • bsexec .. /sbin/mount -u -o rw,suid,dev /
  • setenv DYLD_INSERT_LIBRARIES /private/var/evasi0n/amfi.dylib
  • load /System/Library/LaunchDaemons/
  • bsexec .. /private/var/evasi0n/evasi0n
  • bsexec .. /bin/rm -f /private/var/evasi0n/sock
  • bsexec .. /bin/ln -f /var/tmp/launchd/sock /private/var/evasi0n/sock
  • Here’s what that does, line by line:
  • bsexec .. /sbin/mount -u -o rw,suid,dev /
  • Mount system partition read-write again
  • setenv DYLD_INSERT_LIBRARIES /private/var/evasi0n/amfi.dylib
  • Insert amfi.dylib into any executable that launches after this point
  • load /System/Library/LaunchDaemons/
  • Load the MobileFileIntegrity daemon
  • bsexec .. /private/var/evasi0n/evasi0n
  • Execute the malicious code, previously dropped in /var/evasi0n/evasi0n
  • Unset DYLD_INSERT_LIBRARIES, so that amfi.dylib will no longer be inserted into every executable after this point
  • bsexec .. /bin/rm -f /private/var/evasi0n/sock
  • Delete any pre-existing socket file at /private/var/evasi0n/sock
  • bsexec .. /bin/ln -f /var/tmp/launchd/sock /private/var/evasi0n/sock
  • Create a symlink from /var/tmp/launchd/sock to /private/var/evasi0n/sock, allowing other code direct access to the root launchd socket

Now the exploit reboots your handset or tablet and causes this configuration file to get run, line by line, on next boot. You might be curious to learn that amfi.dylib and evasi0n are both not code-signed. If you look at amfi.dylib with otool, you will see that it contains no TEXT/text section, in other words, there is nothing to sign, and therefore, it won’t trip up the code-signing machinery. It just has lazy binding information.

  • $ dyldinfo -export amfi.dylib
  • export information (from trie):
  • [re-export] _kMISValidationOptionValidateSignatureOnly (_kCFUserNotificationTokenKey from CoreFoundation)
  • [re-export] _kMISValidationOptionExpectedHash (_kCFUserNotificationTimeoutKey from CoreFoundation)
  • [re-export] _MISValidateSignature (_CFEqual from CoreFoundation)

This technique is described at this way:

“If we can force MISValidateSignature() to always return 0, any binaries will pass the test. This function is part of libmis.dylib, which is now part of the shared cache, so you can’t binary patch this file. Replacing the implementation of a function is a perfect job with MobileSubstrate, unfortunately, no matter how I tried MS can’t be injected. Therefore I use a trick: create a “proxy dynamic library” that changes only the MISValidateSignature function, and let the rest pass through.”

By clever usage of a codeless dynamic library, existing valid methods (such as CFEqual()) can be re-exported as different methods with the same method signature, such that MISValidateSignature will always return 0, allowing any unsigned binary to run.


The tool developed by the Evad3rs is a great discovery. This utility escalates privileges. It is capable of fully accessing the system partition and it doesn’t corrupt your memory because it can exploit the /var/db/timezone vulnerability in order to get to the root user’s launchd socket. Then it just abuses launchd to load MobileFileIntegrity with an inserted codeless library, which is overriding MISValidateSignature to always return 0. Was it interesting to get to the insides of this exploit? We hope you like it.

Thanks, AccuvantLabs blog for this curious information.