Tags: rev java apk 

Rating: 5.0

We are given an Android app with a login screen. [http://www.javadecompilers.com/](http://www.javadecompilers.com/) is a good website for decompiling the apk (without going through the trouble of installing all the tools).

After decompiling you can see the code in `LoginActivity.java`:

```
public void onClick(View view) {
Toast.makeText(LoginActivity.this.getApplicationContext(), C0046o.m117a(LoginActivity.this.getApplicationContext(), (int) R.raw.prod, this.f1785b.getText().toString(), this.f1786c.getText().toString(), false), 1).show();
}
```

No way to get the username and password from here. Looking around you'll see another interesting file named `TestActivity.java`:

```
public void onClick(View view) {
String str;
try {
MessageDigest instance = MessageDigest.getInstance("SHA-256");
Signature signature = TestActivity.this.getApplicationContext().getPackageManager().getPackageInfo(TestActivity.this.getApplicationContext().getPackageName(), 64).signatures[0];
str = C0046o.m117a(TestActivity.this.getApplicationContext(), (int) R.raw.qa, "token", signature == null ? "" : Base64.getEncoder().encodeToString(instance.digest(signature.toByteArray())), true);
} catch (NameNotFoundException | NoSuchAlgorithmException e) {
e.printStackTrace();
str = null;
}
Toast.makeText(TestActivity.this.getApplicationContext(), str, 1).show();
}
```

Basically, this code uses `token` as username and the SHA256 of the first APK signature (encoded in Base64) as the password. This signature can be extracted from `CERT.RSA` using `keytool`:

```
$ keytool -printcert -file CERT.RSA
Owner: CN=RealGam3, OU=RealGam3, O=RealGam3, L=NA
Issuer: CN=RealGam3, OU=RealGam3, O=RealGam3, L=NA
Serial number: 19e19e40
Valid from: Sun Jun 21 16:27:18 ICT 2020 until: Thu Jun 15 16:27:18 ICT 2045
Certificate fingerprints:
SHA1: 02:32:1C:57:42:D4:68:DC:45:37:25:11:7D:79:1B:2B:A3:C0:C7:1A
SHA256: A7:DF:C1:5E:06:E9:E9:DD:6F:46:D1:C8:70:26:E2:E9:59:BA:7D:A3:40:2D:02:21:63:34:3A:8D:70:A9:52:F9
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
```

Encoded Base64: `p9/BXgbp6d1vRtHIcCbi6Vm6faNALQIhYzQ6jXCpUvk=`

Now we need to see how the username and passwords are sent to the server. This is done in `C0046o.m117a` method. Although the code is not fully decompiled, we can still have an idea of what is going on:

- The code sends a basic authentication request with username and password to [https://certifiedapp.ctf.bsidestlv.com:8003/authenticate](https://certifiedapp.ctf.bsidestlv.com:8003/authenticate)
- Client certificate is used to encrypt the SSL/TLS traffic. Certificate is stored in `res/raw/qa.p12`. Certificate password is `thecakeisalie` (obtained from key `clientCertPassword` in `res/values/strings.xml`)

Full solver code:

```
package bsidesltv;

import java.io.*;
import java.net.ProtocolException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.cert.X509Certificate;
import java.util.Base64;

import javax.net.ssl.*;

public class CertAppSolver {

public static void m125a(HttpsURLConnection httpsURLConnection, String str, String str2) {
StringBuilder sb = new StringBuilder();
sb.append(str);
sb.append(":");
sb.append(str2);
String sb2 = sb.toString();
System.out.println(sb2);
try {
httpsURLConnection.setRequestMethod("POST");
httpsURLConnection.setConnectTimeout(1500);
httpsURLConnection.setReadTimeout(1500);
byte[] encode = java.util.Base64.getEncoder().encode(sb2.getBytes(StandardCharsets.UTF_8));
StringBuilder sb3 = new StringBuilder();
sb3.append("Basic ");
sb3.append(new String(encode));
System.out.println(sb3);
httpsURLConnection.setRequestProperty("Authorization", sb3.toString());
} catch (ProtocolException e) {
e.printStackTrace();
}
}

public static String m118a(InputStream inputStream) throws Exception {
char[] cArr = new char[4096];
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF8");
StringWriter stringWriter = new StringWriter();
while (true) {
int read = inputStreamReader.read(cArr);
if (-1 == read) {
return stringWriter.toString();
}
stringWriter.write(cArr, 0, read);
}
}

public static java.lang.String m117a(java.lang.String r7, java.lang.String r8) throws Exception {
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
}
};
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

java.lang.String clientCertPassword = "thecakeisalie";
java.lang.String certPath = "bsidesltv\\qa.p12";
InputStream stream = new DataInputStream(new FileInputStream(certPath));
java.security.KeyStore r4 = java.security.KeyStore.getInstance("PKCS12");
r4.load(stream, clientCertPassword.toCharArray());
javax.net.ssl.KeyManagerFactory r5 = javax.net.ssl.KeyManagerFactory.getInstance("SunX509");
r5.init(r4, clientCertPassword.toCharArray());
javax.net.ssl.KeyManager[] r50 = r5.getKeyManagers();
javax.net.ssl.SSLContext r6 = javax.net.ssl.SSLContext.getInstance("TLS");
java.security.SecureRandom r9 = new java.security.SecureRandom();
r6.init(r50, trustAllCerts, r9);
java.lang.String r2 = "https://certifiedapp.ctf.bsidestlv.com:8003/authenticate";
java.net.URL r51 = new java.net.URL(r2);
java.net.URLConnection r52 = r51.openConnection();
javax.net.ssl.HttpsURLConnection r53 = (javax.net.ssl.HttpsURLConnection)r52;
javax.net.ssl.SSLSocketFactory r61 = r6.getSocketFactory();
r53.setSSLSocketFactory(r61);
m125a(r53, r7, r8);
int r62 = r53.getResponseCode();
System.out.println(r62);
java.io.InputStream r71 = r53.getInputStream();
java.lang.String r63 = m118a(r71);
r53.disconnect();
return r63;
}

public static void main(String[] args) throws Exception {
String s = m117a("token", "p9/BXgbp6d1vRtHIcCbi6Vm6faNALQIhYzQ6jXCpUvk=");
System.out.println(s);
}
}
```

Flag: `BSidesTLV2020{I_L1k3_B1g_Apps_And_I_cannot_l13}`