Mitm proxy with certificate pinned application

4.6k views Asked by At

I am trying to simulate MITM attack over signal's android messaging application. It's open source, so I put the mitmproxy-ca-cert.pem in android application for pinning and in the mobile trusted certificates too. I am still not getting any query to the server. Error at the client end is

NonSuccessfulResponseCodeException: Bad response: 502 Bad Gateway

1

There are 1 answers

0
Exadra37 On

If i understood well you are trying to attack a mobile that uses certificate pinning to connect with the API server.

If so then adding the mitmproxy-ca-cert.pem to the mobile trusted store is not enough, you need to configure the network security file res/xml/network_security_config.xml as per google docs.

If you still fill lost try to follow the article Hands on Mobile Api Security Pinning to see if it helps you to get back on track.

EDIT

The following instructions are valid for the Android API level 24 and above.

Another Edit

A better approach then using the bash script that I provide below is to use the free Mobile Certificate Pinning Generator online tool to get the public key pin hash and to generate the proper Android network security config file for us: Config tab on the web page for the Mobile Certificate Pinning Generator tool

The Android tab on the web page for the Mobile Certificate Pinning Generator tool

Bash script to generate the hash from the certificate public key:

#!/bin/bash
# Heavily inspired on:
#   * https://medium.com/@appmattus/android-security-ssl-pinning-1db8acb6621e#ecea

set -eu

Main()
{
    local certificate_path="${1? Missing path to certificate.}"

    local certs="$( cat ${certificate_path} )"
    local rest=$certs

    while [[ "$rest" =~ '-----BEGIN CERTIFICATE-----' ]]; do

        cert="${rest%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----"
        rest=${rest#*-----END CERTIFICATE-----}

        local certificate_name="$( echo "$cert" | grep 's:' | sed 's/.*s:\(.*\)/\1/' )"

        if [ -n "${certificate_name}" ]; then
            printf "\nCERTIFICATE NAME: \n ${certificate_name} \n"
        fi

        printf "\nCERTIFICATE PUBLIC KEY HASH:\n\n"

        echo "$cert" |
            openssl x509 -pubkey -noout |
            openssl rsa -pubin -outform der 2>/dev/null |
            openssl dgst -sha256 -binary |
            openssl enc -base64

        echo

        exit 0

    done
}

Main ${@}



Save the above bash script somewhere in your bin path and then use it like:

$ hash-certificate-public-key.sh ~/path/to/mitmproxy-ca-cert.pem

CERTIFICATE PUBLIC KEY HASH:

gsGj6crKw/RebflwkwGIKxngaZaVxP7UsUtuF71VKDw=

Now copy paste the hash and add it into this file src/main/res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>

    <!-- Official Android N API -->
    <!--https://android-developers.googleblog.com/2016/07/changes-to-trusted-certificate.html-->
    <domain-config>
        <domain>the-domain-to-pin.com</domain>
        <trust-anchors>
            <certificates src="user" />
            <!-- <certificates src="system" /> -->
        </trust-anchors>
        <pin-set>
            <!-- THE MITM CERTIFICATE HASH -->
            <pin digest="SHA-256">gsGj6crKw/RebflwkwGIKxngaZaVxP7UsUtuF71VKDw=</pin>
        </pin-set>
    </domain-config>

</network-security-config>

And now include it in the AndroidManifest.xml:

<application
        android:allowBackup="true"
        <!--omitted-->
        android:networkSecurityConfig="@xml/network_security_config">

If not done already add the mitmproxy certificate to the user trusted store in your Android device, then recompile the app, and now you should be able to intercept the requests.

NOTE:

The code examples have been extracted from the Currency Converter Demo App repository, that was used as part of the article Steal that API Key with a Man in the Middle Attack and article Securing HTTPS with Certificate Pinning on Android