Home [DeadFace CTF] - Cereal Killer 05
Post
Cancel

[DeadFace CTF] - Cereal Killer 05


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:

2

Debugging

I started by opening the file with Java Decompiler.

2

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 :

2

🚩 flag{Fr00t-Br00t-is-the-only-cereal-for-Prez-Trump!}

Thanks for reading !

This post is licensed under CC BY 4.0 by the author.