---
# System prepended metadata

title: picoCTF vault-door (1-8)

---

# picoCTF vault-door (1-8) WriteUp

就自己紀錄一下，寫的很爛別太在意.w.


## valut-door-1
 題目標籤: Medium, Reverse Engineering
![vault-door-1](https://hackmd.io/_uploads/BkOSVUMYJe.png)

### 題目解釋
裡面是一個JAVA檔，這部分的內容大概就是在 "picoCTF{" 後面會接一坨東西那就是flag。
![vault-door-1_1](https://hackmd.io/_uploads/H11XBLGt1g.png)

往下看去會看到一個 checkPassword 他會回傳一個32個長度的東東，按順序組起來後會得到 "d35cr4mbl3_tH3_cH4r4cT3r5_f6daf4" 這一串，將其組起來後，就變成 picoCTF{d35cr4mbl3_tH3_cH4r4cT3r5_f6daf4}，這就是最終答案

![vault-door-1_2](https://hackmd.io/_uploads/rke46SDicJx.png)

### FLAG
	picoCTF{d35cr4mbl3_tH3_cH4r4cT3r5_f6daf4}


## vault-door-3
題目標籤: Medium, Reverse Engineering
![vault-door-3](https://hackmd.io/_uploads/BJlRrPi51e.png)

### 題目解釋
前面的部分都大同小異就跳過了，直接看到重點，他是由4個 for 迴圈組成，最後面有一個 "jU5t_a_sna_3lpm18g947\_u\_4\_m9r54f" 共有有32個字元。

##### 第一個 for 迴圈
> 將 buffer 的 0-7 變成 "jU5t\_a\_s" 字串。

##### 第二個 for 迴圈
> 將 burffer 的 8-15 變成倒過來的 "1mpl3\_an" 字串。

##### 第三個 for 迴圈
> 將 16, 18, ... ,30 共8個位置變成 "4, r, m, 4, u, 7, 9, 8 " 這些字。

##### 第四個 for 迴圈
> 將 31, 29, ... ,17 變成 "f, 5, 9, \_, \_, \_, 4, g" 這些字。

##### 合併
最終全部組起來後變成 "picoCTF{jU5t_a_s1mpl3\_an4gr4m_4_u_79958f}"

![vault-door-3_1](https://hackmd.io/_uploads/HJSlLws5kl.png)

### FLAG
	picoCTF{jU5t_a_s1mpl3_an4gr4m_4_u_79958f}


## vault-door-4
題目標籤: Medium, Reverse Engineering
![vault-door-4](https://hackmd.io/_uploads/H11GIPo9Je.png)

### 題目解釋
可以 myBytes 是由4個部分組成

##### 第一部分
> 106 , 85  , 53  , 116 , 95  , 52  , 95  , 98 
> 這一段看起來像是 ascii 碼
> 轉換過後變成 "jU5t_4_b"

##### 第二部分
> 0x55, 0x6e, 0x43, 0x68, 0x5f, 0x30, 0x66, 0x5f
> 這一段是一個[[進制轉換#十六進制|十六進制]] (Hex)
> 轉換過後變成 "UnCh_0f_"

##### 第三部分
> 0142, 0131, 0164, 063 , 0163, 0137, 0143, 061
> 這一段是一個八進制 (Octal)
> 轉換過後變成 "bYt3s_c1"

##### 第四部份
>'9' , '4' , 'f' , '7' , '4' , '5' , '8' , 'e' 
>本身就是文字
>因此合起來變成 "94f7458e"

![vault-door-4_1](https://hackmd.io/_uploads/BksM8Pi5kl.png)

### FLAG
	picoCTF{jU5t_4_bUnCh_0f_bYt3s_c194f7458e}


## vault-door-5
題目標籤: Medium, Reverse Engineering
![vault-door-5](https://hackmd.io/_uploads/SkmQIwscJg.png)

### 題目解釋
可以看到 myBytes 有許多的十六進制，在下面是一個 32 次的 for 迴圈，對每一個與 0x55 做 XOR 運算，因此得到 "n0t_mUcH_h4rD3r_tH4n_x0r_3ce2919" 即為解答

![vault-door-5_1](https://hackmd.io/_uploads/H19Q8wi9kl.png)


### FLAG
	picoCTF{n0t_mUcH_h4rD3r_tH4n_x0r_3ce2919}

## vault-door-7

題目標籤: Hard, Reverse
![vault-door-7](https://hackmd.io/_uploads/ryPiUDjqye.png)

### 題目解釋
打開之後我們可以先偷看一下提示，簡單來說，就是今天有一串數字你可以先將他變成二進制，這時就會剛好符合 int 的長度 32 位元，我們可以將其拆分成四個部分並分別轉換回十進制，再轉換成 ASCII 就會得到 4 個字母。

```
// 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
```

或者也可以從這邊看出來，是將一組 hex 轉換成 8 個 int 的陣列。

![vault-door-7_1](https://hackmd.io/_uploads/SkbnLws5kl.png)

#### 第一步驟

先將圖片內的這八個 x\[0] 至 x\[7] 轉換為二進制，這部分可以用程式也可以手動，我比較懶，就直接手動了。

![vault-door-7_2](https://hackmd.io/_uploads/SkK3Lwj9yg.png)

轉換過後變成這樣，記得要將沒有 32 長度的在最前面補上 0 這樣才會是正確的。

![vault-door-7_3](https://hackmd.io/_uploads/rJIa8Dj5kg.png)

#### 第二步驟

接著根據前面所述，將 8 個分成一組，每個都拆成 4 份，這邊就直接用程式跑，簡單暴力的小程式，最後再自己調整一下就會得到我們的 flag 了。

![vault-door-7_4](https://hackmd.io/_uploads/BJap8DsqJg.png)

### 程式碼

```py
x1 = "01000001010111110110001000110001"
x2 = "01110100010111110011000001100110"
x3 = "01011111011000100011000101110100"
x4 = "01011111011100110110100000110001"
x5 = "01100110010101000110100101001110"
x6 = "01100111010111110110010001100011"
x7 = "00111000001100000110010100110010"
x8 = "00111000001100010011001000110100"
  
words = []  

x = [x1, x2, x3, x4, x5, x6, x7, x8]

for i in x:
    for j in range(0, len(i), 8):
        words.append(chr((int(i[j:j+8], 2))))

print(*words)
```

### FLAG

	picoCTF{A_b1t_0f_b1t_sh1fTiNg_dc80e28124}


## vault-door-8
題目標籤: Hard, Reverse
![vault-door-8](https://hackmd.io/_uploads/HkjAUDiqkl.png)

### 題目解釋

#### 第一步驟

拿到題目後我們發現裡面十分混亂，因此稍微去整理一下讓此程式比較好看懂
![vault-door-8_1](https://hackmd.io/_uploads/HkdyPwjc1l.png)

整理後：
```java
// These pesky special agents keep reverse engineering our source code and then
// breaking into our secret vaults. THIS will teach those sneaky sneaks a
// lesson.
//
// -Minion #0891

import java.util.*; 
import javax.crypto.Cipher; 
import javax.crypto.spec.SecretKeySpec;
import java.security.*; 

class VaultDoor8 {
	public static void main(String args[]) {
	
		Scanner b = new Scanner(System.in); 
		System.out.print("Enter vault password: ");
		String c = b.next(); 
		String f = c.substring(8,c.length()-1); 
		VaultDoor8 a = new VaultDoor8(); 

		if (a.checkPassword(f)) {
			System.out.println("Access granted.");
		}
		else {
			System.out.println("Access denied!"); 
		} 
	} 
		
	public char[] scramble(String password) {
		
		/* Scramble a password by transposing pairs of bits. */
		char[] a = password.toCharArray(); 
		
		for (int b=0; b<a.length; b++) {
			char c = a[b]; 
			
			c = switchBits(c,1,2); 
			c = switchBits(c,0,3); 
			/* 
			c = switchBits(c,14,3); 
			c = switchBits(c, 2, 0); 
			*/ 
			c = switchBits(c,5,6); 
			c = switchBits(c,4,7);
			c = switchBits(c,0,1); 
			/* 
			d = switchBits(d, 4, 5); 
			e = switchBits(e, 5, 6); 
			*/ 
			c = switchBits(c,3,4); 
			c = switchBits(c,2,5); 
			c = switchBits(c,6,7); 
			
			a[b] = c; 
		
		} 
	return a;

} 

public char switchBits(char c, int p1, int p2) {

	/* Move the bit in position p1 to position p2, and move the bit
	that was in position p2 to position p1. Precondition: p1 < p2 */ 
	char mask1 = (char)(1 << p1);
	char mask2 = (char)(1 << p2);

	/* char mask3 = (char)(1<<p1<<p2); 
	mask1++; mask1--; */ 

	char bit1 = (char)(c & mask1); 
	char bit2 = (char)(c & mask2); 
	
	/* System.out.println("bit1 " + Integer.toBinaryString(bit1));
	System.out.println("bit2 " + Integer.toBinaryString(bit2)); */ 

	char rest = (char)(c & ~(mask1 | mask2)); 
	char shift = (char)(p2 - p1); 
	char result = (char)((bit1<<shift) | (bit2>>shift) | rest); 
	
	return result;
} 

public boolean checkPassword(String password) {
	char[] scrambled = scramble(password); 
	char[] expected = {
		0xF4, 0xC0, 0x97, 0xF0, 0x77, 0x97, 0xC0, 0xE4,
		0xF0, 0x77, 0xA4, 0xD0, 0xC5, 0x77, 0xF4, 0x86,
		0xD0, 0xA5, 0x45, 0x96, 0x27, 0xB5, 0x77, 0xE0,
		0x95, 0xF1, 0xE1, 0xE0, 0xA4, 0xC0, 0x94, 0xA4 
		}; 
	
	return Arrays.equals(scrambled, expected); } 
}

```

#### 第二步驟

先了解整個流程，在 checkPassword 的時候會將輸入值做 scramble 這個函數，也就是將每個字元做 8 次 switchBits 後，與 checkPassword 內的答案做對比，如果相同就是正確。

因此我們看到 swtichBits 的部分，一開始先對 1 進行左移 p1, p2 位，再存放在 mask 內。接著做 c & mask 也就是抓取 c 的第 mask 位的數值，並存放在 bit 內。最後三個 rest, shift, result 分別是，將 c 在 p1 和 p2 的位置清掉；接著藉由 p2 - p1 計算偏移量；講了那麼多廢話，其實就是將 p1 跟 p2 的位置調換，對就是那麼直白。

![vault-door-8_2](https://hackmd.io/_uploads/BJI7PvsqJx.png)

#### 第三步驟

因此看回去到 scramble 的部分，我們稍微整理一下這 8 次交換，可以發現是在做下圖的事情，不過要注意的是在逆推時需要將其順序反過來，不然答案會是錯的。

![vault-door-8_3](https://hackmd.io/_uploads/ry2XPPi5ke.png)

透過程式，我們就可以將裡面的內容寫成程式運行，就可以得到我們的 flag 了。

### 程式碼
```py
word = [0xF4, 0xC0, 0x97, 0xF0, 0x77, 0x97, 0xC0, 0xE4,
        0xF0, 0x77, 0xA4, 0xD0, 0xC5, 0x77, 0xF4, 0x86,
        0xD0, 0xA5, 0x45, 0x96, 0x27, 0xB5, 0x77, 0xE0,
        0x95, 0xF1, 0xE1, 0xE0, 0xA4, 0xC0, 0x94, 0xA4]

bin_word = [str(bin(i)[2:].zfill(8)) for i in word]
ans = []

for i in bin_word:
    ans.append(chr(int((i[4:6] + i[0:2] + i[6:8] + i[2:4]), 2)))

print(*ans)
```
### FLAG
	picoCTF{s0m3_m0r3_b1t_sh1fTiNg_2e762b0ab}