Android application traffic analysis: certificate pinning bypass without reverse engineering

    Sometimes you need to research the backend of a mobile application. It’s good if the creators of the application didn’t bother and all requests go through the "bare" HTTP. But what if the requesting application uses HTTPS and refuses to accept the certificate of your root certification authority, which you carefully implemented in the storage of the operating system? Of course, you can search for requests in a decompiled application or, using reverse engineering, disable encryption altogether, but I would like a simpler way.

    image

    What is certificate pinning?


    Even when using HTTPS, the user is not protected from Man-in-the-Middle attacks, because when the connection is initialized, an attacker can replace the server certificate with his own. Traffic will be accessible to the attacker.

    Certificate pinning will help to cope with such an attack. This protective measure is that the developer "sews" a trusted certificate into the application. When establishing a secure connection, the application verifies that the certificate sent by the server matches (or is signed by) the certificate from the application store.

    Certificate pinning bypass


    As an experimental, choose the Uber application. We will use Burp Suite to analyze HTTP traffic. We will also need the JDK and Android SDK (I use all the latest versions). From the Android SDK, we need only the zipalign utility, so if you want, you can not download the entire SDK, but find it on the Internet.
    Make your life easier in advance by adding the following paths to the necessary utilities in the PATH environment variable:

    C:\path\to\jdk\bin
    %USERPROFILE%\AppData\Local\Android\sdk\build-tools\23.0.2

    Open Burp, go to Proxy - Options - Add and add the Proxy Listener on the interface that will be available to the experimental Android device (or emulator). On the device, in turn, we configure the used Wi-Fi network to use the proxy just turned on.

    Download the apk file via apkpure.com, install the application on the device and try to log in to your account - the application will freeze at the authentication stage.

    image

    In the Burp Suite logs (Alerts tab), we will see multiple reports of unsuccessful SSL handshakes. Pay attention to the first line - it is through the cn-geo1.uber.com server that authentication is carried out in my case, and therefore I can’t enter the application.

    image

    The fact is that Burp Suite when intercepting HTTPS connections (and we remember that all device connections are proxied through it) replaces the web server certificate with its own, which, of course, is not included in the list of trusted ones. In order for the device to trust the certificate, do the following: In Burp, go to Proxy - Options and click Import / export CA certificate. Next, in the dialog, select Export Certificate. We copy the certificate to the device, go to Settings - Security - Install certificates and install our certificate as a certificate for VPN and applications.

    image

    Again, try to enter your account. Now the Uber application will tell us only about a failed authentication attempt - that means there is progress, it remains only to bypass certificate pinning.

    Open the application in your favorite archiver as a zip archive. In the res / raw folder, you can notice a file with the speaking name ssl_pinning_certs_bk146.bks.

    image

    By expanding it, you can understand that Uber uses a key store in the BouncyCastle (BKS) format. Because of this, you cannot just replace the certificate in the application. First you need to generate a BKS repository. To do this, download the jar for working with BKS.

    Now we generate the BKS storage that will contain our certificate:

    keytool -import -v -trustcacerts -alias mybks -file c:/path/to/burp.crt -keystore ssl_pinning_certs_bk146.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath c:/path/to/bcprov-jdk15on-154.jar -storepass spassword

    On the question of trusting the certificate, we answer “yes”. Again, open apk in the archiver and replace the original storage with ours (while maintaining the original name).

    But this does not end there. Each apk must be signed with a developer certificate. Fortunately, this is not done to ensure security, but to identify applications, therefore, for our research purposes, we may well use an untrusted certificate.

    We delete the META-INF folder with the old application signature from apk and proceed to generate a new one.
    Create a keystore and generate a key for signing apk in it:

    keytool -genkey -keystore mykeys.keystore -storepass spassword -alias mykey1 -keypass kpassword1 -dname "CN=ololo O=HackAndroid C=RU" -validity 10000 -sigalg MD5withRSA -keyalg RSA -keysize 1024

    We sign our APK with the newly generated key:

    jarsigner -sigalg MD5withRSA -digestalg SHA1  -keystore mykeys.keystore -storepass spassword -keypass kpassword1 Uber.apk mykey1

    Now it remains to align the data in the archive with a four-byte border:

    zipalign -f 4 Uber.apk Uber.apk_zipal.apk

    Done, uninstall the old application from the device, install the new one and try to log into your account. If earlier the application’s attempt to contact cn-geo1.uber.com was interrupted by a handshake, now you can view and, if desired, modify the traffic.

    image

    Thanks for attention!

    Also popular now: