Author: PinkNoize
Reverse Engineering - 100
This vault uses some complicated arrays! I hope you can make sense of it, special agent. The source code for this vault is here: VaultDoor1.java
This challenge consists of a Java source file with a obfuscated hardcoded password. Map string indices to characters to recover the flag.
This challenge provides us with similar source code to vault-door-training.
import java.util.*;
class VaultDoor1 {
public static void main(String args[]) {
VaultDoor1 vaultDoor = new VaultDoor1();
Scanner scanner = new Scanner(System.in);
System.out.print("Enter vault password: ");
String userInput = scanner.next();
String input = userInput.substring("picoCTF{".length(),userInput.length()-1);
if (vaultDoor.checkPassword(input)) {
System.out.println("Access granted.");
} else {
System.out.println("Access denied!");
}
}
// I came up with a more secure way to check the password without putting
// the password itself in the source code. I think this is going to be
// UNHACKABLE!! I hope Dr. Evil agrees...
//
// -Minion #8728
public boolean checkPassword(String password) {
return password.length() == 32 &&
password.charAt(0) == 'd' &&
password.charAt(29) == '8' &&
password.charAt(4) == 'r' &&
password.charAt(2) == '5' &&
password.charAt(23) == 'r' &&
password.charAt(3) == 'c' &&
password.charAt(17) == '4' &&
password.charAt(1) == '3' &&
password.charAt(7) == 'b' &&
password.charAt(10) == '_' &&
password.charAt(5) == '4' &&
password.charAt(9) == '3' &&
password.charAt(11) == 't' &&
password.charAt(15) == 'c' &&
password.charAt(8) == 'l' &&
password.charAt(12) == 'H' &&
password.charAt(20) == 'c' &&
password.charAt(14) == '_' &&
password.charAt(6) == 'm' &&
password.charAt(24) == '5' &&
password.charAt(18) == 'r' &&
password.charAt(13) == '3' &&
password.charAt(19) == '4' &&
password.charAt(21) == 'T' &&
password.charAt(16) == 'H' &&
password.charAt(27) == '3' &&
password.charAt(30) == '4' &&
password.charAt(25) == '_' &&
password.charAt(22) == '3' &&
password.charAt(28) == 'f' &&
password.charAt(26) == '0' &&
password.charAt(31) == '1';
}
}
Just like the previous challenge, the password is hardcoded but this time it is no longer in the form of a string. In the first line of checkPassword()
we see that the password is 32 characters long. The lines that follow compare characters of the input at the corresponding index to constants. To recover the flag we just have to put the characters on the right in order from least index to greatest. I chose to do this by reordering the lines of code to reduce errors.
password.charAt(0) == 'd' &&
password.charAt(1) == '3' &&
password.charAt(2) == '5' &&
password.charAt(3) == 'c' &&
password.charAt(4) == 'r' &&
password.charAt(5) == '4' &&
password.charAt(6) == 'm' &&
password.charAt(7) == 'b' &&
password.charAt(8) == 'l' &&
password.charAt(9) == '3' &&
password.charAt(10) == '_' &&
password.charAt(11) == 't' &&
password.charAt(12) == 'H' &&
password.charAt(13) == '3' &&
password.charAt(14) == '_' &&
password.charAt(15) == 'c' &&
password.charAt(16) == 'H' &&
password.charAt(17) == '4' &&
password.charAt(18) == 'r' &&
password.charAt(19) == '4' &&
password.charAt(20) == 'c' &&
password.charAt(21) == 'T' &&
password.charAt(22) == '3' &&
password.charAt(23) == 'r' &&
password.charAt(24) == '5' &&
password.charAt(25) == '_' &&
password.charAt(26) == '0' &&
password.charAt(27) == '3' &&
password.charAt(28) == 'f' &&
password.charAt(29) == '8' &&
password.charAt(30) == '4' &&
password.charAt(31) == '1';
Now we can write down the characters in the same order to recover part of the flag. d35cr4mbl3_tH3_cH4r4cT3r5_03f841
We can wrap this in the flag prefix to complete the flag. picoCTF{d35cr4mbl3_tH3_cH4r4cT3r5_03f841}