Reverse Engineering the Yik Yak Android App

Every once in awhile, I’ll come across an app that implements some hardening techniques that make reversing a little more interesting. This was the case when I recently tried proxying the API requests for Yik Yak, a popular social media application exclusively available for mobile platforms that allows semi-anonymous user communication across a 5-mile radius (typically college areas).

Opening the app while performing a self-MitM attack effectively kills all API communication — typically, an indicator of SSL pinning.

After decompiling the APK and reviewing the Java source code, it was clear that the developers had also used an obfuscation tool to optimize/protect their build. Here’s an example method:

Note that the variables, classes, and methods have been renamed from their original, human-friendly forms. As I looked over more of the code, it also seemed like string constants were obfuscated — a feature found in third party tools like DexGuard. While obfuscators are generally a good practice for several reasons, they only marginally delay the reversing process by making the code harder to follow. In my experience, obfuscators also make Java decompilation less reliable, so I’ll mostly be working with smali (examples are in Java when available).

Next, I began grepping the smali source files for strings relating to common SSL pinning implementations. I quickly found what I thought would be the pinning check:

I bypassed the above method by editing it to immediately return void, but after building, signing, and installing the new APK, I had the same “Internet Connection” error as above. After trying a few different edits/builds with the same result, I began to suspect that Yik Yak was using some tamper detection logic (a package signature check) in an effort to prevent reverse engineering. I confirmed this by installing an unmodified, though resigned, APK that resulted in the same error.

In order to bypass the tamper detection, I changed focus and started searching for its decision point. In Android, developers can access the package’s signatures using the PackageManager class like this:

It was pretty clear that this method was used as a wrapper to fetch the signatures of the current build. Note that on line 12, the value
64 correctly matches the constant value for PackageInfo.GET_SIGNATURES. Searching for usages of this class produced a few results:

Rather than attempt to workaround multiple decision points, I decided to spoof the package signature by altering the above method to return the signature of the official Yik Yak build. In order to do that, I needed to know the signature that the app was looking for. I briefly hunted through the code in the results above, but didn’t find the hard-coded signature (probably due to obfuscation). Instead of further searching (or debugging) the code, I ran a script that extracts the signature from a given APK:

After I had the expected signature, I patched the above smali method to return it:

Now that the package signature check had been bypassed, I installed the new build to test — unfortunately, I had the same error. Since this was likely due to some additional pinning code that I missed, I searched through the sources again and found this method:

The infosec world is full of examples of companies poorly handling software security, but it’s certainly progress to see more efforts to improve such security by organizations like Yik Yak (at least as far as Android is concerned).

Thanks for the feedback. I’ve tried similar modules but haven’t had good results. I’ll give this one a try next time!

globleedev

Nice, but what is the advantage of doing this compared to using something like fiddler? Is this required to read SSL traffic?

Randy Westergren

For YikYak (and other apps that implement pinning), you would need to bypass the pinning logic in order for Fiddler and other proxies to decrypt the SSL traffic.

Ryan Dsouza

At this point, what more could Yik Yak have done?

Ade Firman Triangga

Hey, I’m an security consultant, I found some apps with code like yours,
usually, I found apps with SSL pinning implemented with write up the certificate files / public key in a hardcode manner.

However I found some apps implementing SSL pinning like this app, no harcoded information like certificates or public key, just many word “list” (certificate list, etc). I’m not understand this, can you explain how this method of SSL pinning implementation works?