Friday 19 July 2013

Bumpin' Swipe Locks...

An iOS application I use a fair bit has a simple swipe code authentication. The basic idea is you log in every 24 hours with your username and password, then for the next 24hrs you can use a swipe code rather than have to re-type your password each time you want to view the contents of the app. If you get the swipe code wrong more than twice, you also have to enter your password again.

I decided to take a look at how this worked and see if you could fudge the app so that you never had to enter your password (after initial setup) so it wouldn't time out after 24hrs and if I got the swipe wrong (I've not long had my new hands) I could have more than 2 attempts.

First of all I used clutch (lazy way) to decrypt the binary and then class-dump-z to dump out the classes and methods, I'm not going to go into any detail here on these two tools. There is plenty out there if you google it!

Looking through the class-dump-z output I could see a couple of class's that looked interesting one was called XXXSecurity and the other was called XXXSecurityKeys... hmm.

After a little bit of tinkering with theos (a new favourite tool) I was able to get some additional debug on both of these classes as they were being called. If you use logify as below, it will will create you the output to go into your tweak file.

$ /opt/theos/bin/ yourclass.h > Tweak.xm

Once the tweak is installed onto the device it will log all the output into syslog. It logs the class and method as they are called and the values returned, pretty handy.

I started to use the application and could see in syslog that as I swiped across the tiles the application would login and call the following method:

 -[<XXXSecurity: 0x1d8d18d0> canLoginWithSwipe] = 1

Which was then closely followed by:

-[<XXXSecurity: 0x59405c0> loadPasswordWithSwipeCode:147A]

After trying a few more swipes it soon became obvious the swipe pad was laid out as below:

So if I could get [XXXSecurity canLoginWithSwipeCode] to always return true (1) I would be rockin' the dance floor. This was pretty simple and is a lot like the removing simple jailbreak detection post I did perviously. I created the tweak below and installed:

Once compiled and installed this worked a treat I could keep trying my swipe code.

After looking at the syslog output for a while I began to wonder what would happen if I used cycript to call the various methods, would the app just pop open? If I could do this I could then attempt to brute force the swipe code by passing values to cycript to try? Swipe codes are pretty simple, theres not much entropy.

I started to play around with cycript and wasn't really getting anywhere, so I began to google as this is a fairly common technique for hacking apps, Jailbreak tweakers do this a lot. After a short time googling I stumbled across this blog and also this blog from Prateek Gianchandani, it was really useful but I wasn't getting anywhere so I dropped Prateek a mail. Prateek responded and was able to point me in the right direction. My Objective C isn't great, I am at best a n00b (but learning fast). He explained that it looked like the method that was being called (see below) was an instance method and I needed to find the reference to the instance.

-[<XXXSecurity: 0x59405c0> loadPasswordWithSwipeCode:147A]

A few more emails backwards and forwards, and a bit of digging in cycript, I eventually found that by calling the following the app would return the logged in users password...

cy# [[XXXSecurity sharedInstance]loadPasswordWithSwipeCode:@"147A"]

If I supplied the wrong swipe code I got null back

cy# [[XXXSecurity sharedInstance]loadPasswordWithSwipeCode:@"1234"]

So all I had to do was create a little bash script that would loop round a wordlist of swipe codes and when != null was returned I would have my password... simples!

I knocked up the bash script below to brute force the swipe code and it returned the password quite quickly.  Most swipe codes aren't that long so creating an effective wordlist isn't too hard.

The beauty of this attack via cycript is that even though the app has a password attempt limit of 10 attempts set, it's totally ignored when you use cycript to inject code into the runtime. The other methods aren't called so the app doesn't even know it has been abused or how many times the password has been tried.

I decided to reset the swipe code and check that the bash script worked when I tried against a different swipe code, just incase there were any errors.

As I did this I noticed a method being called that looked quite interesting, it looked like there was a specific method for for setting a new swipe code:

-[<XXXSecurity: 0x59405c0> setSwipeCode:0369AB]

If I could call this and set my own swipe code without any verification of the old swipe code or users current passcode, I could then call the method "loadPasswordWithSwipeCode" with the new swipe code I had set and return the logged in users passcode... whoop whoop no more bruteforce required!!

The following worked a charm and I had the users password:

cy# [[XXXSecurity sharedInstance]setSwipeCode:@"0000"]
cy# [[XXXSecurity sharedInstance]loadPasswordWithSwipeCode:@"0000"]

I decided that I should probably disable the swipe code and only use a password from now on, but doing this didn't work. I could still set any swipe code and return the password. In fact this was probably worse as you even wouldn't know the swipe code had been changed.

The only saving grace for this attack is that you need a Jailbreak for it to work else you cannot install cycript, ssh etc. Having said that I'm pretty sure there is probably some jailbreak 0day out there in the wild that hasn't been patched by Apple.

No comments:

Post a Comment