Our website uses cookies to enhance your browsing experience.


FinSpy Mobile: iOS and Apple UDID leak


Last week, Morgan Marquis-Boire and Bill Marczak from The Citizen Lab published  a fascinating glance at real-world mobile espionage tool created by Gamma International under its  ‘FinFisher’ product line.  The report covers the mobile component of FinFisher dubbed ‘FinSpy Mobile’ which supports iOS, Android, Windows, Blackberry, and Symbian phones.  Gamma International in response to the article, issued a press release stating that FinFisher’s “information was stolen from its sales demonstration server at an unknown time by unknown methods.“CrowdStrike analyzed the iOS version of FinSpy to identify details of any attacks against the iOS platform itself which would facilitate the installation of the FinSpy tool.  The technical overview from The Citizen Lab identifies some notable attributes which imply either a bypass or exploit of the iOS security architecture.

One of the first points to catch our attention was that the applications in the FinSpy package use Ad-hoc distribution.  Ad-hoc distribution is typically used for testing, and one of the three application distribution methods available from Apple, the second being In-House apps and the most well-known distribution method being through the iTunes App Store (which also includes Business-to-Business a.k.a B2B apps).  Ad-hoc distribution requires that the individual target device’s Unique Device Identifier (UDID) must be known when the Ad-hoc distribution profile is created, long before execution/installation time.  This makes Ad-hoc distribution less than ideal for in-the-wild exploitation and would seem to support Gamma International’s statement regarding the sales demonstration server.  That is of course until the recent ‘anti-sec’ leak of over a million UDIDs with customer name/device name correlation.

While the limitation of knowing the UDID in advance points to some other distribution channel, the FinSpy installation mechanism writes to a number of files that are not directly accessible from within the third-party application container.  The third-party application container is a sandbox that is part of iOS which enables the device to run third party applications safely and separately from each other and the operating system, this is a security feature of iOS.  This indicates some form of security bypass or exploit is required to install the package by reaching outside of the sandbox.  Additionally, these files are not writable using the ‘mobile’ user privileges, with which third-party applications execute.  Lastly, these files are located in the read-only portion of the filesystem, the system partition, requiring the remounting of the partition with read/write privileges requiring superuser access.  In essence, the Ad-hoc distributed apps run in the third-party App container and without kernel code execution, there is no way to directly bypass the App sandbox. Even if somehow one managed to get around the filesystem permissions, there would still be no way from the sandbox to directly use system calls to write to those file paths.

The trojan application which exfiltrates data, named ‘SyncData.app’, runs persistently and silently while exfiltrating information from data sources not reachable by third-party Apps.

Payload Expansion

The FinSpy Mobile ‘installation’ begins by instantiating the install_manager.app, which contains a routine which decodes and drops four additional binaries.



Specifically, the application bundle of the install_manager.app contains a ‘data’ file which has been obfuscated with a simple fixed-key XOR loop.  Once decoded, the data file is actually a zip compressed file which expands into four more applications, and a LaunchDaemon configuration.

In the pseudocode that follows throughout this post, “${suid_tmpcache}” refers to a path generated as follows:

On a jailbroken device, running this as the mobile user would result in the path “/var/mobile/Library/Caches”.  On a non-jailbroken device, where the user partition is mounted “nosuid” to ignore setuid executables, this results in “/tmp/” as the destination path, which is writeable from the third-party app container.sdf;lakjasdf;ljksdf

The ‘_im_expandPayload()’ routine which decodes the binaries also marks the executable bit of each of the decompressed App bundle’s binary files and attempts to set their ownership to the root user.  NSFileManager fails gracefully if not running with root privileges and will still mark the files as executable.

Privilege Escalation Mechanism?

So how does the trojan break out of the sandbox?  Is there a kernel exploit inside?  After extraction, the trampoline App is executed, followed by the the execution of the installer App.

The infrastructure points at trampoline as a privilege escalation exploit, specifically the arguments which are supplied to the trampoline.app are redundant and unnecessary unless a privilege escalation is occurring.

Install Manager Running Trampoline






As is turns out, the trampoline in this sample is a no-op ‘placeholder’, there is nothing inside and the App has no effect.  Checking the standard control flow techniques, including clever ones, shows no alternate entry points.  No interposers, no interesting relocation entries, initializers, constructors, destructors, dyld exploits, or other tricks. The following is the pseudocode for the main routine, the argc comparison is off by one, causing a non-exploitable NULL pointer dereference. 




The installer app copies over the payloads to their final paths in “/Applications”, “/System/Library/LaunchDaemons”, and “/System/Library/CoreServices/”. 



Files Copied

…/org.logind.ctp.archive/SyncData.app to  /Applications/SyncData.app

…/org.logind.ctp.archive/com.apple.logind.plist   to    

…/org.logind.ctp.archive/logind.app  to  /System/Library/CoreServices/logind.app

Followed by the execution of the ‘login’ App with “/bin/launchctl”  /System/Library/LaunchDaemons/com.apple.logind.plist

Due to the usage of getuid() and geteuid() in ‘installer’, it seems that ‘installer’ is expected to be run as a setuid root binary.  A weaponized version of the trampoline App would likely exploit the system to make ‘installer’ a setuid root binary.  Supporting evidence for this is mentioned later, which shows how the temporary directory lookup checks if the Caches directory is mounted nosuid.  The /tmp directory is also part of the user partition, and would be also be mounted nosuid on a standard non-jailbroken device.

What’s important to note is that setuid root privileges on ‘installer’ won’t be sufficient.  The exploit must remount the filesystem.  Even then, the sandbox container would prevent the writes to these filepaths, the kernel exploit in trampoline would also need to modify the sandbox container for the already-running ‘Install Manager’ App, or patch the kernel sandboxing code.  On a jailbroken device from the iPhone Dev Team, kernel sandboxing code is already hot-patched so this is not necessary.

Persistence mechanism?

As outlined by The Citizen Lab post, Logind will launch SyncData on every new device boot.  In this manner persistence is established, SyncData will run without any restrictions to data available on the device.  Launchd runs the logind App with full root privileges and the SyncData App will run without a sandbox profile.  No additional exploit is necessary for persistence on a jailbroken device, and Ad-hoc distribution would take care of code-signing on a standard install.



The FinSpy Mobile iOS sample contains no exploit or security bypass of iOS, since ‘trampoline’ is incomplete.  The installation mechanism in this sample is consistent with what would be used in a demonstration.  However portions of it could easily be weaponized with an existing jailbreak for out of date devices or a new kernel exploit.  The architecture of the FinSpy demo package is consistent with a commercial grade implant which supports interchangeable exploits.
Although this sample is not fully weaponized, the exfiltration payloads are dangerous and can be trivially distributed onto a jailbroken or a non-jailbroken ‘paired device’ using Mobile Device Management (MDM).  The missing components would be the command and control and SMS backend, which may have also been on the sales demonstration server, and thus compromised.

In the wild, this demonstration code can already trivially run on a jailbroken device.  A paired jailbroken device can have the logind and SyncData Apps dropped directly on the system to later exfiltrate data, making this sample sufficiently dangerous.

It is entirely likely that FinSpy has been used in support of non-demonstrative exploitation and collection.  CrowdStrike is currently looking for such samples, and will report if any are found, if anyone knows of such samples we would love to hear about them.  It is also noteworthy that with the release of the alleged UDIDs today, if those do prove to be legitimate devices, there are now over one million targets which can be targeted using the FinSpy Ad-Hoc distribution mechanism coupled with an existing or new exploit/jailbreak.

As mentioned previously, annotations are available on CrowdRE.

Update September 4th, 2012 7:43 PST:

Two astute readers correctly point out that NSTask fails inside the third-party sandbox, since NSTask uses the fork system call which is filtered. This is true on both standard installs and jailbroken installs for any Apps that do not have the backgrounding entitlement. Install Manager does not use the entitlement.

install_manager.app entitlements

I will also join George Kurtz and my colleague Georg Wicherski at an upcoming Hacking Exposed: Mobile Targeted Threats webinar held next Wednesday September 12 at 11am PT/ 2pm ET. I will be discussing this threat and mitigation strategies in more detail as a guest speaker. Register for it now at www.hackingexposed7.com

CrowdStrike Falcon Free Trial

Try CrowdStrike Free for 15 Days Get Started with A Free Trial