Defeating SSL Pinning in Coin’s Android Application


“Coin is a connected device that holds and behaves like your cards with a magnetic stripe. Use the Coin mobile app to provide key information that we need in order to ship your Coin and to manage the original plastic cards (credit, debit, gift, membership, loyalty and more) that you use with the Coin device.”

This weekend my buddy @_lavalamp and I decided to take a look at his Coin device and its accompanied Androidapplication. The device and the application have an interesting attack surface, which we are still researching, so expect more updates from both of us to follow. In this post we are going to cover how the Coin Android application implements SSL pinning, and the techniques we used to defeat it.


When decompiling the application the first thing we noticed were a handful of Bouncy Castle key stores located within the assets directory.

There was already an assumption the application was probably going to be using a lot of crypto, and rightfully so, considering its sole purpose.

After installing the application, we immediately wanted to start proxying all outbound HTTP and HTTPS, so we setup a global proxy and attempted to log into the application. We were greeted with the following error.


They appeared to have implemented SSL pinning in their application, which was pretty obvious to be the source of this error.

Deep Dive

We needed to defeat this protection mechanism, in order to start understanding how the application was interacting with any api endpoints. It did not take very long to pin point where the SSL Pinning functionality was being implemented.

We found in the class a static method that would return an SSLSocketFactory.


This would simply open a Bouncy Castle key store, load up all of the stored certificates and validate them with the methods checkClientTrusted and checkServerTrusted within the CompositeX509TrustManager class. If the certificate was not inside of the Bouncy Castle key store, the corresponding methods would throw an exception with an error message that gets displayed back in the application’s UI.

We spent quite bit of time trying to figure out how to actually patch out this implementation in order to achieve a bypass, but realized it would be more efficient to use instrumentation instead.


We were able to craft a Frida script that allowed us to hook the method that returned the SSLSocketFactory, and then proceeded working through ideas on how to actually modify the overall control flow, until @_lavalamp had the genius idea of just returning the arguments being passed to the method. This would actually give us the password and the name to the Bouncy Castle key store being used.



We set our script in motion and …

Excellent! Now we had the name of the key store and the password. We could now take our Burpsuite exported certificated and add it to this key store, which would be loaded at runtime and added as a trusted certificate.


First we added our Burpsuite certificate to the coincert.bkskey store.


We then rebuilt the Coin application and deployed it back to device. Now for the moment of truth ..


Success! We had defeated the application’s SSL Pinning.


SSL Pinning provides some level of security for any mobile application, but should not be solely relied upon, and often can be easily defeated.


Apparently I wasn’t explicit enough for the Internet in my conclusion. The application’s SSL Pinning implementation is spot on and there is nothing wrong with it. This post is merely teaching different techniques you can use to reverse engineer and “defeat” said implementation, which allows you to perform things like proxying HTTPS traffic.

转载自:    原文作者:rotlogix