PicoCTF Writeup – vault-door-1

# Information: 

CTF Name: PicoCTF

CTF Challenge: vault-door-1

Challenge Category: Reverse Engineering

Challenge Points: 100

PicoCTF 2019.

Challenge Description: 

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.

The contents of VaultDoor1.java:

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) == 'a' &&                
             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) == '6' &&                
             password.charAt(30) == 'f' &&                
             password.charAt(25) == '_' &&                
             password.charAt(22) == '3' &&                
             password.charAt(28) == 'd' &&                
             password.charAt(26) == 'f' &&                
             password.charAt(31) == '4';     
      } 
}

# Writeup 

By reading the code we can see on line 10 that if the method checkPassword returns true we have access granted to the vault. After knowing this I analyzed the checkPassword method. It seems that to return true we must ensure that each of the conditions present on the return are true. The conditions are all of the form: password.charAt(i) well the password is the method argument, a String, in this particular case it is the input given by the user. The charAt(i) gets the value in the position i of the given string.

Let’s see the 1st position of the password string, in this case, is verified in line 24: password.charAt(0)  == ‘d’

It is possible to see that this condition is true if the position 0 of the string password equals d.

We now know that the password is something like ‘d…’ with length 32. We that the length as to be 32 because of the 1st condition on the return statement:

password.length() == 32

Knowing this now we can check all the positions and get the full correct password. I decided to do this manually but it is possible to create a script to perform this for us.

And the correct flag is:

Show flag
picoCTF{d35cr4mbl3_tH3_cH4r4cT3r5_f6daf4}

The image source can be found here.

Thank you very much for reading!

Cheers,

MRegra

Leave a Reply

Your email address will not be published. Required fields are marked *