Blogs & Stories

SpiderLabs Blog

Attracting more than a half-million annual readers, this is the security community's go-to destination for technical breakdowns of the latest threats, critical vulnerability disclosures and cutting-edge research.

The Grey Line Between Feature and Vulnerability, iOS edition

I do a lot of Mobile Application Penetration testing for some of our largest clients. Mobile is the new sexiness and everybody wants in. This means that there is a lot of misunderstanding of how some of the technology works and with misunderstanding, usually comes security flaws and vulnerabilities.

It was with this in mind that I was taken by surprised a few weeks ago by one of these clients, who, in a panicy phone call to me, asked if I had heard of this new iOS vulnerability floating around. It was horrible, they said, and could allow attackers to intercept and steal any data - ANY DATA - on or passing through any iOS device. Why, it could even be done via a drive by download.

Now, I follow the jailbreak and iOS security community pretty closely, and I had never heard of this. My client said they heard about it at DEF CON and it was causing a riot internally.

The vulnerability? Method Swizzling.

This was a classic case of broken telephone combined with not quite understanding the underlying technology. So, as I did with my client, let me se the record straight:

Method Swizzling is not a vulnerability, but a feature of the Objective C runtime.

What is Method Swizzling?

Method Swizzling is the ability to swap the implementation of a method for an alternate implementation at runtime, using a set of Objective C's reflective API calls. That is, if I have a method foo:withString, I can swap out the implementation of that method to one I wrote, say myFoo:withString. This means instead of the original method being run, mine is. I can then choose to return, or run the roginal method implementation after mine is run.

The effect if similar to method detouring on Windows (think DLL injection with MS Detours), except much easier to do.

It is a nice feature for instrumenting any public API call (and in Objective C, that's almost all of them, even in Apple's core libs) for logging, performance, adding or augmenting features. In the jailbreak community, this is how UI Tweaks are created.

Of course, like any feature, it can be misused. Method detouring on Windows is one of the most common vectors for method hooking and snooping. Reflection on Java is being misused by the current exploit on Java 7 in the wild.

But none of that means swizzling is a vulnerability.

The real issue is the threat model and whether abusing method swizzling is a viable attack vector.

One of the most important things to remember about method swizzling on iOS, is that you can't do it unless you jailbreak the device. The first step in abusing this on the platform is to jailbreak, then install your hooks. The jailbreak can be done by the user or surreptitiously by the attacker, but it must be done to defeat Apple's Codesigning checks (code not signed by Apple will not run on a stock device. Period). Jailbreaking also curretly requires physical access to a device. The jailbreakme.com remote exploit does not work on iOS devices above 4.2 nor does it work on A5 based devices such as the iPad2. Its not been a viable attack vector for remotely jailbreaking iOS devices for about a year.

For some apps, such as banking apps ironically, this means method swizzling is not likely to be a vector of attack. An attacker would have to jailbreak hundreds or thousands of phones to get at only one individual's banking info per device. It would be much easier to just ARP spoof your local coffee shop, SSLStrip a connections and harvest credentials going across the wire. No need to touch a single device and you can get dozens of credentials at a time.

Retail Point of Sale apps are a different story, for example. I have done a penetration test for a client that was planning to use iOS based handheld devices as point of sale terminals. This presents a whole different threat model. First, jailbreaking a single device is likely to expose the card holder data for possibly hundreds of cards per day. Surreptitiously jailbreaking a device, adding the swizzle code and replacing the device without the retailer's knowledge can take mere minutes. This is an attack where the abuse of method swizzling is a real danger (or course, using a card reader that encrypts at the head will defeat this attack, but not all card readers do this).

This is why threat modeling is important. Method swizzling can be mitigated by ensuring any method that handles or processes sensitive data is written in C not Objective C. Objective C is a superset of C and can call C methods without issue, but C methods cannot be swizzled by the Objective C runtime. This might be overkill for the banking app, but makes perfect sense for the retail POS app (especially if the card reader does't encrypt at the head).

Method Swizzling is not a vulnerability, but, like any other reflective language feature, it can be abused. The real issue in iOS mobile development is not that swizzling is possible, but whether the threat model of your application makes it a danger. If it is, write your method in C.