11/21/2021

Solution - UnCrackable App for Android Level 2

 See challenge here

Use dex2jar tool to extract source code.

$~/Downloads/dex-tools-2.1-SNAPSHOT/d2j-dex2jar.sh UnCrackable-Level1.apk

Use JD-GUI to review the source code

$java -jar ~/Downloads/jd-gui-1.6.6.jar



Now we know the check is to send string into static library libfoo.so.

Unzip apk to see lib/ folder

$tree lib

lib

├── arm64-v8a

│   └── libfoo.so

├── armeabi-v7a

│   └── libfoo.so

├── x86

│   └── libfoo.so

└── x86_64

    ├── libfoo.so

If you're a lazy person like me, I use strings first to see if anything comes up.

$strings lib/x86_64/libfoo.so

"Thanks for all t" maybe our flag to capture, but didn't pass entering to the App. Looks like the ending part is missing. So, use Ghidra or IDA free or Hopper Diassembler to see the bar function

Java_sg_vantagepoint_uncrackable2_CodeCheck_bar


some ascii code strings were found at the strncpy.

The second parameter is our flag to capture

 "Thanks for all the fish"

Solution - UnCrackable App for Android Level 1

See challenge here

Use dex2jar tool to extract source code.

$~/Downloads/dex-tools-2.1-SNAPSHOT/d2j-dex2jar.sh UnCrackable-Level1.apk

Use JD-GUI to review the source code

$java -jar ~/Downloads/jd-gui-1.6.6.jar


Now we know the check is to check your input String is equal to the hardcoded ciphertext (encrypted by AES).

Write a similar java program copy & paste the function to decrypt the ciphertext without input anything

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import java.util.Base64;

public class UnCrackableLevel1 {

public static void main(String[] args) throws Exception {

System.out.println(a("any"));

}

public static String a(String paramString) {
byte[] arrayOfByte = Base64.getDecoder().decode("5UJiFctbmgbDoLXmpL12mkno8HT4Lv8dlat8FxR2GOc=");
try {
arrayOfByte = decrypt(b("8d127684cbc37c17616d806cf50473cc"), arrayOfByte);
} catch (Exception exception) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("AES error:");
stringBuilder.append(exception.getMessage());
System.out.println("CodeCheck" + stringBuilder.toString());
arrayOfByte = new byte[0];
}
return new String(arrayOfByte);
}

public static byte[] decrypt(byte[] paramArrayOfbyte1, byte[] paramArrayOfbyte2) throws Exception {
// SecretKeySpec secretKeySpec = new SecretKeySpec(paramArrayOfbyte1,
// "AES/ECB/PKCS7Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(paramArrayOfbyte1, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, secretKeySpec);
return cipher.doFinal(paramArrayOfbyte2);
}

public static byte[] b(String paramString) {
int i = paramString.length();
byte[] arrayOfByte = new byte[i / 2];
for (byte b = 0; b < i; b += 2)
arrayOfByte[b / 2] = (byte) (byte) ((Character.digit(paramString.charAt(b), 16) << 4)
+ Character.digit(paramString.charAt(b + 1), 16));
return arrayOfByte;
}

}

$javac UnCrackableLevel1

$java UnCrackableLevel1

The secret is "I want to believe"

*** Note the source code use AES/ECB/PKCS7Padding

but actually using AES