Reverse Engineering the Subway Android App

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:

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:

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:

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.

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.

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: Facebooktwittergoogle_pluslinkedin
  • Nigel Tolley

    Damned if they do, more damned if they don’t.

    You can bypass anything on your own device, so there’s good reason for them to make it that bit harder for people fiddling.
    Hopefully the other end of the app is as well secured, & good luck tweaking the code at the far end.

    But seriously, don’t knock their valid attempts at security. Knock those who don’t even try.

    • Randy Westergren

      Totally agree! The post isn’t meant to knock their attempts at all, rather it’s meant to demonstrate how simply those attempts are bypassed.

      Sometimes, I think there is a false sense of security when employing techniques found in this post, as it can make developers believe that it will keep researchers or attackers from proxying their API requests.

  • Phil

    Well the security is only broken for people who install your version of the app on their phones.

    For everyone else who installed the Google Play store version of the Subway app, the app would alert the user of the proxying attempt.

    Interesting article nevertheless 🙂

    • Randy Westergren

      Thanks!

      Of course, I never claim that this leaves anyone vulnerable. The post only demonstrates how these additional security measures can be reversed, in my case, to proxy the API requests.

  • Timothy Kirk

    Very nice article. Thanks for posting that!

    The reasoning behind the root check is simple. Their security department recommended it. Tells me that they have likely had the app pen tested by someone. In the end, no app developer is going to get around the one that reverse engineers it. But it will stop the “casual” person that hears about rooting their device, and tries it. As Nigel pointed out, I wonder how the back end is secured.

    Again, this was very interesting.

  • Dan

    How were you able to decompile the source code in cleartext? Did the Subway app developer not use Proguard?

    • IfSlashWhen

      Proguard does not slow down the process at all. Proguard just renames the functions, the smali remains completely reversible.

  • The security measures are not there to secure you from seeing the requests, they are there to stop people using the app getting hacked with man in the middle attacks. I think they know they need to also make sure their API is secure as well.

    • Randy Westergren

      I understand what you mean, but an attacker wouldn’t be able to decrypt during a MiTM attack since SSL is being used — regardless of cert pinning. An effect of pinning is losing the ability to perform a self MiTM to decrypt traffic; this post simply demonstrates bypassing that.

      • Actually that isn’t completely true there are a few exploits to do man in the middle attacks even on SSL.

        Here is just one example: http://www.thoughtcrime.org/software/sslsniff/
        Though this was patched these type of exploits happen all the time and phones don’t get patch as quickly as even IE. So it does add a little more security just in case.

        • Randy Westergren

          Interesting exploit. I don’t disagree that it adds a little more security!

          To the point, the intent of the post was not to imply pinning was used for the purpose of stopping me from capturing my requests, it was simply to demonstrate the process of bypassing cert pinning, in my case, in order to perform a self MiTM.

    • renschler

      @JTWebMan:disqus I’m interested in learning about what it means to have a secure API. Do you have recommended reading?

  • Could you consider the root check as a way to help ensure you are not using a modified (hacked) version of the subway app, which, would allow you (or malicious person who rooted your phone and wanted to steal your ccz) to implement the bypass you documented? If so, that would be a fair attempt at a countermeasure for an app developer.

  • redct

    Subway uses Paydiant, a white label mobile wallet / loyalty app service (http://www.paydiant.com/merchants.html). I wouldn’t be surprised if the same security infrastructure is shared across all their apps, which means that similar methods may work for the apps of their other clients.

  • cpluse

    if subway verify signature in .so file,would be more difficult to bypass.

    • Randy Westergren

      Absolutely! Shared object files are a great way to increase the difficulty and skill level required to RE.

  • Rajnish

    How can I bypass ssl pining in Source code of apk file please reply me asap

  • Chintan Patel

    it is possible to get the data before encrypt just before sending http requests