Tips for Mobile Bug Bounty Hunting

My good friend Pete Yaworski encouraged me to join the bug bounty scene for a long time before I decided to jump in and start using my mobile app sec knowledge to ethically hack on mobile apps from public bug bounty programs. Pete, who literally wrote the book on web hacking, told me how platforms like HackerOne and Bugcrowd help by bringing together ethical hackers and companies that care a lot about their systems and products' security.

On September 2017, I started hacking on a cryptocurrency-wallet iOS app on a pubic program. After about two weeks of doing some static and dynamic analysis, I found some "issues" with the way they were performing cryptographic operations. For example, upon installation they'd generate a UUID and use it as a symmetric encryption key and salt, which is not recommended. After this they'd use this key and salt to encrypt most of their data, reusing the [key | salt] pair on every operation, which is also a bad idea. Finally, their encryption scheme was a simple 128-AES-CBC operation with no authentication tag.

With all this information, I prepared a very detailed report including my recommendations on how to handle the cryptographic operations and submitted it. I was very happy, this was my very first bug bounty report. I was helping a company make their product better for their users and potentially earning some money in the process. Based on the time invested doing this research (reading ARM assembly and analyzing the app's runtime) and the level of detail of the report, I was expecting a very positive response, but what I received instead was the following message:

Hello,

Can you show a proof of concept on how you can exploit this issue?

What I realized in that moment was that even though these were absolutely valid issues, they are theoretical issues. Even though probably any cryptographer would agree that at least the lack of authentication tags and key/salt reuse were, in fact, issues. Most (all?) of the bug bounty programs want real scenarios with real proof of concepts, basically PoC || GTFO. I was not able to provide a real PoC and after a few months the report was closed with the painful Not applicable.

It took me a full year before I could summon some courage and start hacking again, but this time I had a different mindset. Based on my previous experience I started to search for issues I could actually exploit myself. This definitely worked since I've received a few bounties from my latest submissions and even though I can't post writeups about my findings (because all the programs are private), I'm going to share some tips about what I've learned through this fantastic journey. As you probably know, I focus on iOS Apps research, so these tips are going to be most helpful for iOS but some of the core concepts might work on Android as well. I'll also be updating the list regularly with new information as I learn more:

Static Analysis

After you've downloaded and decrypted the app, load it on a disassembler (for example Hopper).

  • Many developers hardcode encryption keys or client credentials on iOS apps: Select the Strings tab and search for these terms secret, crypt, private, token.

  • Many apps use 3rd party backend systems, for this the apps need some credentials or configuration files. Sometimes developers expose credentials or private keys in these files: In the app's bundle search for all the .plist, .json or .conf files you can find. Common ones AirshipConfig.plist, GoogleService-Info.plist and definitely the app's own Info.plist.

  • There are a lot of apps that have development/debugging classes or methods that show more information than a regular user should see or put the app in a debugging mode that will help gather extra information: Select the Procedures tab and search for these terms develop, debug, fake, test.

  • More often than not, developers forget to remove testing data/files from the Xcode project and they end up bundled within the app: Search the app's bundle directory for files that are not images or .xib/.storyboardc, for example .json.

  • Search the binary for hardcoded encryption keys using the strings command:

    • Alphanumeric strings with 64 characters:
      strings <binary> | grep -E '^[[:alnum:]]{64,64}$'
    • UUIDs:
      strings <binary> | grep -E '^[-[:alnum:]]{36,36}$'
  • Inspect the files the application is storing, including data from 3rd party libraries imported by the main app: SSH into your device and change directories to /private/var/mobile/Containers/Data/Application/{UUID}.

  • Dump the classes, methods and instant variables of the app: class-dump <binary> > dump.txt.

  • Almost every mobile app uses at least one 3rd party library. Dig into these 3rd party libraries and check their versions, many of them are open source and you can search their public repository for issues and check whether the current version of the library is/isn't affected. All the libraries are inside the Frameworks/ folder in the app's bundle.

Dynamic Analysis

With some of the information gathered from the static analysis you can start performing some dynamic hacking.

  • Use a dynamic analysis tool to inspect the app's behaviour at runtime: Use cycript, frida or even gdb.

  • If you've found any classes/methods with developer, development, test, fake, debug funtionality, try to enable them by calling these methods. For example there was one app that had a class called InternalSettingsViewController, when presented, this controller would show a lot of debugging information.

  • Proxy the app's traffic to identify information being sent from and received on the device: I wrote a post on how to proxy this traffic.

  • If the app is not loading or immidately crashing when launching, try to search the class dump (or in your disassembler) for methods like isJailbroken, jailbreak, rooted, because chances are they have a jailbreak detection. Most of these detections can be bypassed with cydia tweaks like xCon, NoSub or tsProtector. If these don't work you might have to patch the app (I'm currently drafting a post on how to do this).

  • After you've run the app and maybe registerd or played around with it for a while, check the iOS Keychain for data generated from the app. Some developers would store AWS/GCP credentials there: Use Keychain-Dumper to dump the keychain items.

  • Also, after using the app for a while, check the UserDefaults file, which is a .plist configuration file that some developers use to store sensitive information: The file is located at /private/var/mobile/Containers/Data/Application/{uuid}/Library/Preferences and is commonly named as the app's bundle identifier .plist.

  • Bypass App Store TLS traffic, open Burp, select Proxy, then Options, scroll down to TLS Pass Through and add:

    • ^.*?apple\..*$
    • ^.*?icloud\..*$
    • ^.*?mzstatic\..*$

General

  • Read other people's writeups. For example I find Allyson's posts very helpful.

  • Read disclosed reports from HackerOne and Bugcrowd, sometimes the fix introducess new bugs or might have not completely solved the issue.

  • Reverse engineer as many apps as you can to get as much experience as you can. You'll also gain some knowledge around how developers commonly do/code apps.

That's it. Hope this helps you and if you have any suggestions/comments feel free to reach out on twitter @ivRodriguezCA.

Photo by Victoria Heath on Unsplash