It’s great to see the increasing adoption of certificate pinning in Android apps. When I run into an app that throws connection errors while attempting to proxy requests, I tend to become more interested in diving deeper. Such was the case when I recently used the Subway app. Reversing the APK revealed cert pinning among some other interesting findings.

Starting the app while proxying requests caused this error:

Pinning is simple enough to bypass. I started by decompiling the app and analyzing the source code for pinning keywords. I actually found pinning implementations in two separate classes that implemented X509TrustManager . Here is one of the methods that enforced pinning:

// Code removed at request of Subway leadership

Bypassing this was as simple as adding a return statement in the smali code to skip the pinning code in the method above. Note the addition of the return-void statement below:

// Code removed at request of Subway leadership

After recompiling the App and installing, I was surprised to see this new error:

Subway was using a custom app signature verification process in order to prevent reversing of their APK. Grepping the source for mentions of this process, I traced it back to the following method:

// Code removed at request of Subway leadership

This was an interesting attempt at preventing reverse engineering, though it actually only caused a slight delay. In order to bypass this process, I simply added a line to skip the method’s execution by adding another return-void line, similar to the pinning bypass process above.

// Code removed at request of Subway leadership

After recompiling and installing the app, I was able to successfully proxy requests:

During my research, I stumbled on this Reddit post. Apparently, Subway was also determining whether the user’s device had been rooted. I searched around in the source and confirmed mentions of root detection methods.

// Code removed at request of Subway leadership

This is a great example of an app taking security very seriously, but I’m not quite sure of the reasoning behind the root checking process. Though certificate pinning and signature verification techniques are generally a good idea, they only slightly impede those looking to go more in depth.

Share this: