0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

picoCTF 2019 writeup vault-door-7

Last updated at Posted at 2025-12-06

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}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?