iOS: Patching security features of mobile app with Ghidra

Every mobile app security researcher faces the day, he will not be delivered with a properly prepared app for testing, or you face another blackbox security assessment. Until now I used Hopper Disassembler for static binary analysis/patching. Since recently Ghidra a new tool by the NSA was released, I decided to give it a try.

I quickly dumped a random protected app as unencrypted .ipa with frida-ios-dump, from a jailbroken phone, and unpacked the content for further analysis. First thing I tried was, to repack, sign and run the app again with my Apple developer certificates, which was possible (anti-repacking protection missing…). Then I started to take a look at the in-place hardening features, such as:

  • Jailbreak detection
  • SSL certificate pinning

As far as I saw, it was possible to run the app on a jailbroken phone. It only showed a generic warning message, but did not prevent the user from entering his precious credentials…

“Unauthorized removal of usage restrictions, bla bla bla…”

Error message in some mobile App

It’s one decision allowing your app to run in an unsafe environment, it’s another to implement weak detection mechanism. So let’s dive into this first.

Defeating jailbreak detection.

I opened the iOS binary with Ghidra, waited until the tool finished it’s magic, and then started analyzing the classes… Ghidra did a great job in finding and sorting the Objective-C classes.

As can be seen on the above screenshot, there is an Objective-C Class called JailbreakDetection with two methods isJailbroken: and jailbroken. I started analyzing the function jailbroken, as you can see in the following screenshot only the kinda standard things are checked…

The app looks for some files, tries to create a file, and tries to open the cydia:// URL scheme. In fact the function returns true (0x1) if any of the jailbreak mechanisms succeeds and false (0x0) if all fail. The responsible instruction moving the boolean true into register w21 can be seen in the following screenshot at address 10001e45c.

Now by right-clicking and selecting Patch Instruction, we will be able to modify the return value. Let’s patch it to 0x0 instead of 0x1.

Wow, that was super easy, let’s see if the SSL certificate pinning challenges us?

Defeating SSL certificate pinning.

Find the responsible method, here pinSSL in SslCertificatePinning:

Find a appropriate place for the patch, here the if check of uVar1 or uVar2:

Apply the patch:

Now as we successfully patched the jailbreak detection and the SSL certificate pinning, we can spit out a new binary with Ghidra, repack and reinstall the trustworthy iOS app on our untrustworthy jailbroken device with an interception proxy in place to analyze the encrypted network traffic.

— Keep Hacking.