Cracking Apple's iOS Passcode

You must have read about MDSec’s Black Box that manages to gain access to iPhones running up to iOS 8.1 by brute-forcing the passcode over a USB connection to simulate keypad entry. These kind of attacks are not very practical because iOS’s protection against bruteforce attacks blocks passcode entry after 10 failed attempts.

I tried to replicate the attack while covering the entire process without using hardware hacks, so the device has to be jailbroken to gain unsigned code execution privilege (or you might as well use your own exploit for that ;p).

TransLock

I wrote the following code that loops through every possible 4-digit passcode, starting from 0000 up to 9999.

Then I made a class-dump of SpringBoard and found a class called SBDeviceLockController with an interesting method:

- (BOOL)attemptDeviceUnlockWithPassword:(NSString *)password
                           appRequested:(BOOL)requested;

After that, I wrote a dynamic library that hooks into the SpringBoard process and runs the above code when SpringBoard did finish launching, including calling the method above for every generated pin.

Once it returns a Boolean value of true, we can assure that it’s the working pin.

I relaunched the SpringBoard process to test my code at runtime, and as expected it worked. Well, for the most part…

When watching syslog, I found that it’s only running the first 10 passcode entry attempts then it’s getting blocked by the operating system and throwing an iPhone is Disabled alert on the lock-screen. I had to find a workaround.

I looked back at the earlier class-dump in a class called SBFDeviceLockController and found those related methods:

- (BOOL)_temporarilyBlocked;
- (BOOL)isPasscodeLockedOrBlocked;
- (BOOL)isBlocked;

I hooked that class and overrided the return value of those methods to false, I then ran my code again… The device no longer disables passcode entry after 10 failed attempts. My code was able to try a pin every 5 seconds, if you do the math, that means it’ll take 14 hours at most to try every single pin possible.

You can find libTransLock on my GitHub.