This year, America’s politicians are weighing in on the IMPORTANT issues…! As in, which spooky cereal is best?
President Donald Trump also has a favorite monster cereal, but it is secured by a password. As a test of your hacking mettle, oh great Turbo Tactical nerd, we need you to hack the program and gain access to the flag. Good luck!
Submit the flag as flag{flag_text_here}
Table of contents:
Given File
We are given the following .jar
file:
Debugging
I started by opening the file with Java Decompiler.
We are now able to read the following source code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
public class RE08 {
private static final byte[] encryptedURL = new byte[] {
42, 6, 68, 64, 7, 120, 93, 31, 83, 17,
48, 23, 81, 92, 90, 46, 11, 68, 68, 27,
44, 30, 81, 82, 7, 108, 29, 66, 87, 91,
33, 23, 66, 85, 21, 46, 1, 31, 86, 6,
45, 29, 68, 82, 6, 45, 29, 68, 30, 30,
50, 23, 87 };
private static final String encryptedFlag = "Tj/BJ+45Z45uRCFpuFOHirQI34ZC7bmtpCtJ3OE613fIxqrsZwIoLNSBXSjtPONFqZF3gC+4glh1Gyi2RBKZcuItH8s=";
private static final String ivBase64 = "qHttv1t5TWZLDM4e";
public static void main(String[] paramArrayOfString) {
try {
Scanner scanner = new Scanner(System.in);
System.out.print("President Donald Trump has a favorite cereal. It is great... really great...\n");
System.out.print("The reason it is so great, is because HE likes it... that makes it reall great...\n");
System.out.print("Of course, to maintain utmost secrecy, it is protected with a password that is\n");
System.out.print("HIGHLY secure (and backed up securely on a piece of paper somewhere in Mar Lago...)\n");
System.out.print("Now, you, being a highly trained hacker, should be able to BYPASS this security and\n");
System.out.print("discover what President Trump's favorite monster cereal is.\n");
System.out.print("\n");
System.out.print("Enter password: ");
String str1 = scanner.nextLine();
byte[] arrayOfByte = decryptURL(encryptedURL, str1);
String str2 = new String(arrayOfByte);
if (str2.startsWith("https")) {
System.out.println("Decrypted URL: " + str2);
String str3 = downloadImage(str2);
byte[] arrayOfByte1 = calculateSHA256(str3);
String str4 = decryptFlagWithAESGCM(arrayOfByte1, "Tj/BJ+45Z45uRCFpuFOHirQI34ZC7bmtpCtJ3OE613fIxqrsZwIoLNSBXSjtPONFqZF3gC+4glh1Gyi2RBKZcuItH8s=", "qHttv1t5TWZLDM4e");
System.out.println("Decrypted Flag: " + str4);
} else {
System.out.println("Sorry, that is not the correct password.");
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
private static byte[] decryptURL(byte[] paramArrayOfbyte, String paramString) {
byte[] arrayOfByte = new byte[paramArrayOfbyte.length];
for (byte b = 0; b < paramArrayOfbyte.length; b++)
arrayOfByte[b] = (byte)(paramArrayOfbyte[b] ^ paramString.charAt(b % paramString.length()));
return arrayOfByte;
}
private static String downloadImage(String paramString) throws IOException {
URL uRL = new URL(paramString);
String str = "downloaded_image.jpg";
File file = new File(str);
if (file.exists())
file.delete();
InputStream inputStream = uRL.openStream();
try {
Files.copy(inputStream, Paths.get(str, new String[0]), new java.nio.file.CopyOption[0]);
if (inputStream != null)
inputStream.close();
} catch (Throwable throwable) {
if (inputStream != null)
try {
inputStream.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
return str;
}
private static byte[] calculateSHA256(String paramString) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte[] arrayOfByte = Files.readAllBytes(Paths.get(paramString, new String[0]));
return messageDigest.digest(arrayOfByte);
}
private static String decryptFlagWithAESGCM(byte[] paramArrayOfbyte, String paramString1, String paramString2) throws Exception {
byte[] arrayOfByte1 = Base64.getDecoder().decode(paramString2);
byte[] arrayOfByte2 = Base64.getDecoder().decode(paramString1);
SecretKeySpec secretKeySpec = new SecretKeySpec(paramArrayOfbyte, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec gCMParameterSpec = new GCMParameterSpec(128, arrayOfByte1);
cipher.init(2, secretKeySpec, gCMParameterSpec);
byte[] arrayOfByte3 = cipher.doFinal(arrayOfByte2);
return new String(arrayOfByte3, "UTF-8");
}
}
Overall, the main
function follows a process to decrypt a URL and then a flag. The program asks the user for a password then it uses this password to attempt to decrypt the URL.
If the URL is correct, it downloads an image from that URL. Then it calculates the SHA-256 of the image to use as a key to decrypt the flag with AES-GCM.
We notice that the decryptURL()
method applies a XOR between each byte of the encryptedURL array and the password characters:
1
2
3
4
5
6
private static byte[] decryptURL(byte[] paramArrayOfbyte, String paramString) {
byte[] arrayOfByte = new byte[paramArrayOfbyte.length];
for (byte b = 0; b < paramArrayOfbyte.length; b++)
arrayOfByte[b] = (byte)(paramArrayOfbyte[b] ^ paramString.charAt(b % paramString.length()));
return arrayOfByte;
}
We know that the URL should start with https
. Using this knowledge, we can attempt to recover part of the password from the encrypted URL.
Python Implementation
We know that the URL probably starts with https
, which results in the following ASCII bytes: [104, 116, 116, 112, 115]
. Then, we just have to perform a XOR to try to discover part of the password used.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
encrypted_url = [42, 6, 68, 64, 7, 120, 93, 31, 83, 17,
48, 23, 81, 92, 90, 46, 11, 68, 68, 27,
44, 30, 81, 82, 7, 108, 29, 66, 87, 91,
33, 23, 66, 85, 21, 46, 1, 31, 86, 6,
45, 29, 68, 82, 6, 45, 29, 68, 30, 30,
50, 23, 87]
# "https" as ASCII values
known_pt = [104, 116, 116, 112, 115]
password_guess = []
for i in range(len(known_pt)):
xor_result = encrypted_url[i] ^ known_pt[i]
password_guess.append(xor_result)
password_guess_str = ''.join([chr(p) for p in password_guess])
print(f"Matching password: {password_guess_str}")
Wich gives us the following: Matching password: Br00t
Flag
Now, all we have to do is run the .jar
file and provide the password obtained :
🚩
flag{Fr00t-Br00t-is-the-only-cereal-for-Prez-Trump!}
Thanks for reading !