vault-door-7 (Reverse Engineering)
This vault uses bit shifts to convert a password string into an array of integers. Hurry, agent, we are running out of time to stop Dr. Evil's nefarious plans! The source code for this vault is here: VaultDoor7.java
添付ファイル
・VaultDoor7.java
ソースコードを確認する。
import java.util.*;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
class VaultDoor7 {
public static void main(String args[]) {
VaultDoor7 vaultDoor = new VaultDoor7();
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!");
}
}
// Each character can be represented as a byte value using its
// ASCII encoding. Each byte contains 8 bits, and an int contains
// 32 bits, so we can "pack" 4 bytes into a single int. Here's an
// example: if the hex string is "01ab", then those can be
// represented as the bytes {0x30, 0x31, 0x61, 0x62}. When those
// bytes are represented as binary, they are:
//
// 0x30: 00110000
// 0x31: 00110001
// 0x61: 01100001
// 0x62: 01100010
//
// If we put those 4 binary numbers end to end, we end up with 32
// bits that can be interpreted as an int.
//
// 00110000001100010110000101100010 -> 808542562
//
// Since 4 chars can be represented as 1 int, the 32 character password can
// be represented as an array of 8 ints.
//
// - Minion #7816
public int[] passwordToIntArray(String hex) {
int[] x = new int[8];
byte[] hexBytes = hex.getBytes();
for (int i=0; i<8; i++) {
x[i] = hexBytes[i*4] << 24
| hexBytes[i*4+1] << 16
| hexBytes[i*4+2] << 8
| hexBytes[i*4+3];
}
return x;
}
public boolean checkPassword(String password) {
if (password.length() != 32) {
return false;
}
int[] x = passwordToIntArray(password);
return x[0] == 1096770097
&& x[1] == 1952395366
&& x[2] == 1600270708
&& x[3] == 1601398833
&& x[4] == 1716808014
&& x[5] == 1734304867
&& x[6] == 942695730
&& x[7] == 942748212;
}
}
標準入力を0文字目から順に24bit左シフト、16bit左シフト、8bit左シフト、何もしない、の4つのORをとり、1096770097,1952395366, 1600270708, 1601398833, 1716808014, 1734304867, 942695730, 942748212と比較している。
つまり、ビットの左シフトにより4つの文字がA000、B00、C0、Dのようになっており、さらにOR演算するので、最終的にABCDとなる。
よって、1096770097,1952395366, 1600270708, 1601398833, 1716808014, 1734304867, 942695730, 942748212をbinaryに変換し、4分割して文字に直せばパスワードが分かる。
binaryに変換すると以下のようになる。
01000001 01011111 01100010 00110001
01110100 01011111 00110000 01100110
01011111 01100010 00110001 01110100
01011111 01110011 01101000 00110001
01100110 01010100 01101001 01001110
01100111 01011111 01100100 01100011
00111000 00110000 01100101 00110010
00111000 00110001 00110010 00110100
フラグが得られた。
picoCTF{A_b1t_0f_b1t_sh1fTiNg_dc80e28124}