3

I'm new to reverse engineering, I've never developed an android application before and I'm trying to extract from an android application the certificate it's using to authenticate to the server.

One of the answers to this post mentions that extracting a private key from an apk file is indeed a possible thing.

This post says that unlesss we have the original keystore file of the application we won't be able to extract the private key. Is it possible to get the original keystore file? Most of the posts seem to agree on the fact that this is impossible!

I've decompiled the application I'm interested in, and I retrieved the CERT.RSA from it, but I don't know if this can help me extract the certificate and the private key from the application. What can we do with the CERT.RSA file anyways?

I know that an android application is accessible to anyone from the google play store, so if what I'm trying to do is possible anyone could extract the certificate and private key and hack any application, but I just want to know if there were some specific tips/hacks, a good tutorial or just an indication of where to start off?

Here is the pcap I get when I send a request to the server that the app communicates with: enter image description here

10.0.0.1 is the client IP address and 192.168.10.211 is the server's IP address, and we can see that the client is sending 2 certificates to the server during the handshake session, so where do these certificates come from? are they hardcoded in the application?

UPDATE

As you can see on the pcap file, the client does send a certificate to the server during the handshake session, so I spent the last few days trying to retrieve it and use it to forward a request to my server.

I've finally managed to retrieve the certificate, the problem is I don't know how can I use it to get the job done.

Here is exactly what I did:

This is the java code that logs the certificate and the password that the client uses during the handshake protocol:

    public static native byte[] getCplusPKCS12Cert();

    public static native byte[] getCplusPKCS12Pass();

    static {
        System.loadLibrary("cplusnative");
    }

    public static SSLSocketFactory a() {
        SSLSocketFactory sSLSocketFactory = null;
        SSLContext instance = SSLContext.getInstance("TLS");
        byte[] cplusPKCS12Cert = getCplusPKCS12Cert();
        String s = Base64.getEncoder().encodeToString(cplusPKCS12Cert);
        Log.d('certificate',s);
        byte[] cplusPKCS12Pass = getCplusPKCS12Pass();
        Log.d('password',cplusPKCS12Pass);        
        return sSLSocketFactory;
    }

This allows me to get the certificate which is a PKCS12 certificate that's secured with a password which is logged to the terminal too when I launch:$ adb logcat

This is what I get:

certificate:

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
wCFEL+hYAgIIAA==

password: S0xXYUY4QWtSdW9mYW5VAA==

I put the certificate in a .p12 file, but I can't open it.

To overcome this issue I print the certificate to android storage: storage/emulated/0/output.p12 which created a file containing hexadecimal data. When I use this file to forward a request to my server using python:

$ python3

> from requests_pkcs12 import get
> r = get(url, pkcs12_filename='theOutput.p12', pkcs12_password='S0xXYUY4QWtSdW9mYW5VAA==')

I get the following error:

Error: [('asn1 encoding routines', 'ASN1_get_object', 'header too long')]

I feel that I have all the pieces of the puzzle and I only need to put them together, so my question is: How can I use the resources (certificate/password) I have retrieved to forward requests to the server?

Thank you.

yosra
  • 702
  • 1
  • 11
  • 24
  • 1
    You are confusing different keys altogether. Very few apps authenticate to a server with a certificate. Mostly the server is authenticated by the app, which only requires a public key. APK sare also signed using an APK signing key, but that's not bundled with the app. The app only contains public keys. Tutorials are off-topic on stackoverflow. – President James K. Polk Jun 14 '19 at 14:59
  • @JamesKPolk thank you for your response, but when I send a POST request to the server using postman, and intercept what was sent to the server using wireshark, I can see that during the handshake session the client do send 2 certificates to the server (certificate chain), so how did the client find those certificates? Do you want me to include screenshots of the pcap file I got? – yosra Jun 14 '19 at 15:03
  • Yes, I think screenshots would help in this case. – President James K. Polk Jun 14 '19 at 15:06
  • @JamesKPolk I've updated my post, can you please check it again? – yosra Jun 14 '19 at 15:12
  • 1
    Ok, with that update it does appear that this particular client is doing SSL/TLS client authentication, which means that, yes, somewhere in this app is a private key. The easiest place to store this for the programmer is in a keystore file, but that's also makes it the easiest to find for the reverse engineer. So it may be obfuscated, and there are a myriad of possibilities there. – President James K. Polk Jun 14 '19 at 15:21
  • @JamesKPolk Thank you a lot, at least now I know that the certificate and the private key are somewhere in the apk file. But can you please tell me what kind of information I can get from the CERT.SF and the CERT.RSA; when I convert CERT.RSA to pem format using `$ openssl pkcs7 -inform DER -in CERT.RSA -out CERT.pem -outform PEM -print_certs` I get a file whom the header and footer are -----BEGIN CERTIFICATE----- , -----END CERTIFICATE----- isn't it the certificate I am looking for? – yosra Jun 14 '19 at 15:29
  • 1
    Those files contain only public keys and are not relevant to your task, those are used to "sign" the APK. The keys are certificates for the SSL aspect are somewhere else. – President James K. Polk Jun 14 '19 at 15:32
  • @JamesKPolk Thanks a lot for your answers. – yosra Jun 14 '19 at 15:36
  • @JamesKPolk I've finally retrieved the certificate from the application, but I can't use it. I've updated my post, can you please check the update section on my post? maybe you could have some new ideas. Thank you – yosra Jun 24 '19 at 10:52
  • 1
    I can't get the pkcs12 file to read either, yet. There's a good chance the password is "KLWaF8AkRuofanU", but that didn't work either. I'm still trying a few things. – President James K. Polk Jun 24 '19 at 16:12
  • @JamesKPolk Thanks a lot I really appreciate – yosra Jun 24 '19 at 19:32
  • 1
    Unfortunately it appears the pkcs12 file is missing a substantial part from the end. Perhaps it was too large to list through logcat or perhaps it is in different pieces. – President James K. Polk Jun 24 '19 at 21:16
  • @JamesKPolk Thank you a lot for your time again. You're right, I've found out that `adb logcat` cannot print more than 4000 characters, while the length of the certificate is 5792 bytes. I will update the certificate. – yosra Jun 25 '19 at 14:29
  • 1
    haha, closer, but it still appears to be 50 bytes too short. If I'm not mistaken it should end in '=='. – President James K. Polk Jun 25 '19 at 15:36
  • @JamesKPolk I think it's good right now =D I've updated it – yosra Jun 25 '19 at 15:47
  • @JamesKPolk I can't thank you enough, Thanks a lot. I've managed to get the certificate the client is using. I've used the password you mentioned above. Can you please tell me how you got it? – yosra Jun 25 '19 at 16:06
  • 1
    Ok, it now loads correctly using password `KLWaF8AkRuofanU`. I got it by base64 decoding the string `S0xXYUY4QWtSdW9mYW5VAA==` and noticing that it ends with a null (0) byte, which is consistent with a C-style null terminated string. – President James K. Polk Jun 25 '19 at 18:45

0 Answers0