Writeup VaultDoor Series

picoCTF 2019

Posted by rmn0x01 on Saturday, November 2, 2019

Rangkaian soal Reversing-VaultDoor picoCTF Setiap challenges terdapat satu file .java yang harus di-reverse untuk didapatkan flag-nya

VaultTraining

VaultDoorTraining.java

import java.util.*;

class VaultDoorTraining {
    public static void main(String args[]) {
        VaultDoorTraining vaultDoor = new VaultDoorTraining();
        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!");
	}
   }

    // The password is below. Is it safe to put the password in the source code?
    // What if somebody stole our source code? Then they would know what our
    // password is. Hmm... I will think of some ways to improve the security
    // on the other doors.
    //
    // -Minion #9567
    public boolean checkPassword(String password) {
        return password.equals("w4rm1ng_Up_w1tH_jAv4_fa9bcc3bcf9");
    }
}

Pretty straightforward FLAG: picoCTF{w4rm1ng_Up_w1tH_jAv4_fa9bcc3bcf9}

VaultDoor 1

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) == '7' &&
               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) == '5' &&
               password.charAt(30) == '0' &&
               password.charAt(25) == '_' &&
               password.charAt(22) == '3' &&
               password.charAt(28) == '8' &&
               password.charAt(26) == '5' &&
               password.charAt(31) == 'd';
    }
}

Susun ulang karakter sesuai posisinya.

solver.py

passwd = ['?' for i in range(32)]

passwd[0]  = 'd' 
passwd[29] = '7' 
passwd[4]  = 'r' 
passwd[2]  = '5' 
passwd[23] = 'r' 
passwd[3]  = 'c' 
passwd[17] = '4' 
passwd[1]  = '3' 
passwd[7]  = 'b' 
passwd[10] = '_' 
passwd[5]  = '4' 
passwd[9]  = '3' 
passwd[11] = 't' 
passwd[15] = 'c' 
passwd[8]  = 'l' 
passwd[12] = 'H' 
passwd[20] = 'c' 
passwd[14] = '_' 
passwd[6]  = 'm' 
passwd[24] = '5' 
passwd[18] = 'r' 
passwd[13] = '3' 
passwd[19] = '4' 
passwd[21] = 'T' 
passwd[16] = 'H' 
passwd[27] = '5' 
passwd[30] = '0' 
passwd[25] = '_' 
passwd[22] = '3' 
passwd[28] = '8' 
passwd[26] = '5' 
passwd[31] = 'd'

print(''.join(passwd))

FLAG: picoCTF{d35cr4mbl3_tH3_cH4r4cT3r5_55870d}

VaultDoor 3

VaultDoor3.java

import java.util.*;

class VaultDoor3 {
    public static void main(String args[]) {
        VaultDoor3 vaultDoor = new VaultDoor3();
        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!");
        }
    }

    // Our security monitoring team has noticed some intrusions on some of the
    // less secure doors. Dr. Evil has asked me specifically to build a stronger
    // vault door to protect his Doomsday plans. I just *know* this door will
    // keep all of those nosy agents out of our business. Mwa ha!
    //
    // -Minion #2671
    public boolean checkPassword(String password) {
        if (password.length() != 32) {
            return false;
        }
        char[] buffer = new char[32];
        int i;
        for (i=0; i<8; i++) {
            buffer[i] = password.charAt(i);
        }
        for (; i<16; i++) {
            buffer[i] = password.charAt(23-i);
        }
        for (; i<32; i+=2) {
            buffer[i] = password.charAt(46-i);
        }
        for (i=31; i>=17; i-=2) {
            buffer[i] = password.charAt(i);
        }
        String s = new String(buffer);
        return s.equals("jU5t_a_sna_3lpm17ga45_u_4_mbrf4c");
    }
}

Mirip dengan soal VaultDoor 1, susun ulang karakternya.

solver.py

s="jU5t_a_sna_3lpm17ga45_u_4_mbrf4c"
pwd=['?' for i in range(32)]

#Rule 1
for i in range(0,8):
    pwd[i] = s[i]
#Rule 2
for i in range(8,16):
    pwd[23-i] = s[i]
#Rule 3
for i in range(16,32,2):
    pwd[46-i] = s[i]
#Rule 4
for i in range(31,16,-2):
    pwd[i] = s[i]
#CheckFlag
print(''.join(pwd))

FLAG: picoCTF{jU5t_a_s1mpl3_an4gr4m_4_u_5baf7c}

VaultDoor 4

VaultDoor4.java

import java.util.*;

class VaultDoor4 {
    public static void main(String args[]) {
        VaultDoor4 vaultDoor = new VaultDoor4();
        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 made myself dizzy converting all of these numbers into different bases,
    // so I just *know* that this vault will be impenetrable. This will make Dr.
    // Evil like me better than all of the other minions--especially Minion
    // #5620--I just know it!
    //
    //  .:::.   .:::.
    // :::::::.:::::::
    // :::::::::::::::
    // ':::::::::::::'
    //   ':::::::::'
    //     ':::::'
    //       ':'
    // -Minion #7781
    public boolean checkPassword(String password) {
        byte[] passBytes = password.getBytes();
        byte[] myBytes = {
            106 , 85  , 53  , 116 , 95  , 52  , 95  , 98  ,
            0x55, 0x6e, 0x43, 0x68, 0x5f, 0x30, 0x66, 0x5f,
            0142, 0131, 0164, 063 , 0163, 0137, 0142, 071 ,
            'e' , '9' , '2' , 'f' , '7' , '6' , 'a' , 'c' ,
        };
        for (int i=0; i<32; i++) {
            if (passBytes[i] != myBytes[i]) {
                return false;
            }
        }
        return true;
    }
}

Decode myBytes sesuai base-nya.

solver.py

p1 = (106,85,53,116,95,52,95,98)
p2 = (0x55,0x6e,0x43,0x68,0x5f,0x30,0x66,0x5f)
p3 = (142,131,164,63,163,137,142,71)
p4 = ('e' , '9' , '2' , 'f' , '7' , '6' , 'a' , 'c')

flag=''
for i in p1:
    flag+=chr(i)
for i in p2:
    flag+=chr(i)
for i in p3:
    flag+=chr(int(str(i),8))
for i in p4:
    flag+=i

print(flag)

FLAG: picoCTF{jU5t_4_bUnCh_0f_bYt3s_b9e92f76ac}

VaultDoor 5

VaultDoor5.java

import java.net.URLDecoder;
import java.util.*;

class VaultDoor5 {
    public static void main(String args[]) {
        VaultDoor5 vaultDoor = new VaultDoor5();
        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!");
        }
    }

    // Minion #7781 used base 8 and base 16, but this is base 64, which is
    // like... eight times stronger, right? Riiigghtt? Well that's what my twin
    // brother Minion #2415 says, anyway.
    //
    // -Minion #2414
    public String base64Encode(byte[] input) {
        return Base64.getEncoder().encodeToString(input);
    }

    // URL encoding is meant for web pages, so any double agent spies who steal
    // our source code will think this is a web site or something, defintely not
    // vault door! Oh wait, should I have not said that in a source code
    // comment?
    //
    // -Minion #2415
    public String urlEncode(byte[] input) {
        StringBuffer buf = new StringBuffer();
        for (int i=0; i<input.length; i++) {
            buf.append(String.format("%%%2x", input[i]));
        }
        return buf.toString();
    }

    public boolean checkPassword(String password) {
        String urlEncoded = urlEncode(password.getBytes());
        String base64Encoded = base64Encode(urlEncoded.getBytes());
        String expected = "JTYzJTMwJTZlJTc2JTMzJTcyJTc0JTMxJTZlJTY3JTVm"
                        + "JTY2JTcyJTMwJTZkJTVmJTYyJTYxJTM1JTY1JTVmJTM2"
                        + "JTM0JTVmJTY0JTYxJTM4JTM4JTMyJTY0JTMwJTMx";
        return base64Encoded.equals(expected);
    }
}

Kombinasi URL-encode dengan Base64-encode

solver.py

import urllib

#Step1
b64d="JTYzJTMwJTZlJTc2JTMzJTcyJTc0JTMxJTZlJTY3JTVmJTY2JTcyJTMwJTZkJTVmJTYyJTYxJTM1JTY1JTVmJTM2JTM0JTVmJTY0JTYxJTM4JTM4JTMyJTY0JTMwJTMx".decode('base64')
#Step2
urld=urllib.unquote(b64d)

print(urld)

FLAG: picoCTF{c0nv3rt1ng_fr0m_ba5e_64_da882d01}

VaultDoor 6

VaultDoor6.java

import java.util.*;

class VaultDoor6 {
    public static void main(String args[]) {
        VaultDoor6 vaultDoor = new VaultDoor6();
        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!");
        }
    }

    // Dr. Evil gave me a book called Applied Cryptography by Bruce Schneier,
    // and I learned this really cool encryption system. This will be the
    // strongest vault door in Dr. Evil's entire evil volcano compound for sure!
    // Well, I didn't exactly read the *whole* book, but I'm sure there's
    // nothing important in the last 750 pages.
    //
    // -Minion #3091
    public boolean checkPassword(String password) {
        if (password.length() != 32) {
            return false;
        }
        byte[] passBytes = password.getBytes();
        byte[] myBytes = {
            0x3b, 0x65, 0x21, 0xa , 0x38, 0x0 , 0x36, 0x1d,
            0xa , 0x3d, 0x61, 0x27, 0x11, 0x66, 0x27, 0xa ,
            0x21, 0x1d, 0x61, 0x3b, 0xa , 0x2d, 0x65, 0x27,
            0xa , 0x63, 0x65, 0x64, 0x67, 0x37, 0x6d, 0x62,
        };
        for (int i=0; i<32; i++) {
            if (((passBytes[i] ^ 0x55) - myBytes[i]) != 0) {
                return false;
            }
        }
        return true;
    }
}

XOR kembali dengan 0x55 untuk dapatkan flag-nya

solver.py

from pwn import xor

pwd= (0x3b, 0x65, 0x21, 0xa , 0x38, 0x0 , 0x36, 0x1d, 0xa , 0x3d, 0x61, 0x27, 0x11, 0x66, 0x27, 0xa ,0x21, 0x1d, 0x61, 0x3b, 0xa , 0x2d, 0x65, 0x27,0xa , 0x63, 0x65, 0x64, 0x67, 0x37, 0x6d, 0x62)
xor_val=0x55
tmp=''
print(xor(xor_val,pwd))

FLAG: picoCTF{n0t_mUcH_h4rD3r_tH4n_x0r_6012b87}

VaultDoor 7

TODO