Midnight Flag - Black Box Writeup

この大会は2023/4/16 5:00(JST)~2023/4/16 17:00(JST)に開催されました。
今回もチームで参戦。結果は1147点で358チーム中52位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (Misc)

ルールのページにフラグが書いてあった。

MCTF{W3lc0me_t0_m1dn1ght_ctf_bl4ck_b0x}

Time Traveler 1/3 (OSINT)

Internet Archivehttps://twitter.com/ibm_5100_ を検索する。2023/4/13 14:28:53のものを見てみると、フラグが書いてあった。

MCTF{t1M€_7r4v3L_O}

Xd33r 1/5 (Web)

HTMLソースを見ると、以下のコメントがあることがわかる。

<!-- TODO: Add a script to detect if the user is logged, if he is, redirect him to: /operator/home -->

http://xd33r.web.midnightflag.fr:31080/operator/loginにアクセスすると、フラグが書いてあった。

MCTF{h1dd3n_4cc3ss!!}

Xd33r 2/5 (Web)

http://xd33r.web.midnightflag.fr:31080/operator/loginでUsernameに「' or 1=1 --」を入力してログインする。
2FA code入力画面になるが、JWTにフラグがありそうなメッセージが表示されている。クッキーにはJWTは見当たらない。リロードして関係するアクセス先を見てみる。
http://xd33r.web.midnightflag.fr:31081/api/meへのリクエストヘッダに以下のJWTが設定されている。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI4MjNkZjRlNi04MWQ1LTQzZDAtOWZiNi1kY2U0MDMwNWJlNmYiLCJsb2dnZWQiOmZhbHNlLCJmbGFnIjoiTUNURntnMHRfMW5qM2N0M2QmYjFwNCQzZH4hfSIsImlhdCI6MTY4MTYyMTQxMCwiZXhwIjoxNjgxNjI1MDEwfQ.JuWBjg_EB10OcgSEZYqAeKuKZiXvEfibUT-rGOBEXgM

https://jwt.io/でこのJWTの情報を見てみると、フラグが書いてあった。

MCTF{g0t_1nj3ct3d&b1p4$3d~!}

Xd33r 3/5 (Web)

2FA codeに適当に入力し、CONFIRMすると、レスポンスに正しいcodeが返ってくる。

返ってきた正しいcodeをすぐに入力すると、ログインできた。
今回も、JWTにフラグがありそうなメッセージが表示されている。リロードして関係するアクセス先を見てみる。
http://xd33r.web.midnightflag.fr:31081/api/meへのリクエストヘッダに以下のJWTが設定されている。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI4MjNkZjRlNi04MWQ1LTQzZDAtOWZiNi1kY2U0MDMwNWJlNmYiLCJsb2dnZWQiOnRydWUsImZsYWciOiJNQ1RGezJGQV9jMGRlX3NoMHVsZF9yM200MW5fczNjcjN0PyF9IiwiaWF0IjoxNjgxNjIzMzQ3LCJleHAiOjE2ODE2MjY5NDd9.dStOaNR7__9TLul9i-KCcfKRsV2fhBI1m2btZgzTOO8

https://jwt.io/でこのJWTの情報を見てみると、フラグが書いてあった。

MCTF{2FA_c0de_sh0uld_r3m41n_s3cr3t?!}

M4giC (Cryptography)

XOR鍵12バイトで暗号化されている。jpgのヘッダが以下のようになっていると推測し、鍵を求め、復号する。

\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01
#!/usr/bin/env python3
with open('flag.jpg.lock', 'rb') as f:
    enc = f.read()

jpg_head = b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01'
key = b''
for i in range(len(jpg_head)):
    key += bytes([jpg_head[i] ^ enc[i]])

dec = b''
for i in range(len(enc)):
    dec += bytes([enc[i] ^ key[i % len(key)]])

with open('flag.jpg', 'wb') as f:
    f.write(dec)

復号した画像にフラグが書いてあった。

MCTF{L3s_By73s_M4g1qU3ssssss_763afe}

Silent Whisper (Cryptography)

サーバの処理概要は以下の通り。

・key: ランダム16バイト配列
・10回以下繰り返し
 ・choice: '1'~'3'入力
 ・choiceが'1'の場合
  ・username: 入力
  ・usernameの長さが32バイトより長い場合、先頭32バイトで切る。
  ・payload = "host:127.0.01,flag:MCTF{REDACTED},garbage:AAAAAAAAAAAAAAAAAAAA,username:" + username
  ・data = payload.encode()
  ・cipherText: dataをパディングし、AES-ECB暗号化
  ・cipherTextを16進数文字列で表示
 ・choiceが'2'の場合
  ・cipherText: 入力
  ・cipherText: cipherTextをhexデコード
  ・clear: cipherTextをAES-ECB復号
  ・unpadClear: clearをアンパッド
  ・recoveredUsername: unpadClearの末尾32バイト
  ・recoveredUsernameを表示
 ・choiceが'3'の場合、終了

payloadをブロックで考える。フラグの長さを見るために、usernameの長さを変え、暗号文の長さを見る。

$ nc silentwhisper.crypto.midnightflag.fr 18000
Choice : 1
enter your username : aaaa
the cipher text is : 8927ee331f022a34ef3878d8429d4c214d2d25a0b60f1ab9001cec7c74bfdb568398f10183c97b91085569751a8fcbf741a294e1916fa2bc772dc5ae66b8f8ea678a5a423bf5662fe73761e82a824e038bb44a2d68893cacd65c962313c8deacae304008d3be45385f7bb664d1e294facd6da8736d54ede250cf83297e530984
Choice : 1
enter your username : aaaaaaaa
the cipher text is : 8927ee331f022a34ef3878d8429d4c214d2d25a0b60f1ab9001cec7c74bfdb568398f10183c97b91085569751a8fcbf741a294e1916fa2bc772dc5ae66b8f8ea678a5a423bf5662fe73761e82a824e038bb44a2d68893cacd65c962313c8deacae304008d3be45385f7bb664d1e294fafe071d499c31d1811c4a70c86d5b2eb0
Choice : 1
enter your username : aaaaaaaaaaaa
the cipher text is : 8927ee331f022a34ef3878d8429d4c214d2d25a0b60f1ab9001cec7c74bfdb568398f10183c97b91085569751a8fcbf741a294e1916fa2bc772dc5ae66b8f8ea678a5a423bf5662fe73761e82a824e038bb44a2d68893cacd65c962313c8deacae304008d3be45385f7bb664d1e294fa327471ed6f280c0bd6e1b8e2310be8fd
Choice : 1
enter your username : aaaaaaaaaaaaaa
the cipher text is : 8927ee331f022a34ef3878d8429d4c214d2d25a0b60f1ab9001cec7c74bfdb568398f10183c97b91085569751a8fcbf741a294e1916fa2bc772dc5ae66b8f8ea678a5a423bf5662fe73761e82a824e038bb44a2d68893cacd65c962313c8deacae304008d3be45385f7bb664d1e294fa07492d5b5095f98739ac009faa40cb6e16c339ba61598291acf651f8974f4c70
Choice : 1
enter your username : aaaaaaaaaaaaa
the cipher text is : 8927ee331f022a34ef3878d8429d4c214d2d25a0b60f1ab9001cec7c74bfdb568398f10183c97b91085569751a8fcbf741a294e1916fa2bc772dc5ae66b8f8ea678a5a423bf5662fe73761e82a824e038bb44a2d68893cacd65c962313c8deacae304008d3be45385f7bb664d1e294faf55c17121bc0f19f92abe825f1d2d293

14バイト入力したときに144バイトで9ブロック分になる。

0123456789abcdef
host:127.0.01,fl
ag:MCTF{XXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXX},garb
age:AAAAAAAAAAAA
AAAAAAAA,usernam
e:aaaaaaaaaaaaaa
PPPPPPPPPPPPPPPP

ECBモードなので、最後のブロックの暗号はパディングデータの暗号になっている。この最後のブロックの暗号を必ず使い、前のブロックの暗号を結合して復号する。

$ nc silentwhisper.crypto.midnightflag.fr 18000
Choice : 1
enter your username : aaaaaaaaaaaaaa
the cipher text is : 51972797f82189f95bd4d61eb4004dfd58f279d7dd228df33b4f85cd09b0858943546b02145c4cd3eba0a96038991489406ff50ba7c2c2c9695bd362e4d894647c16eb41b3ce3e0308b6bfd68adbdb0f2ab417e09b1c9b0da42cf7d962fd9a3543249c396f6a04462d873c16fc1de6ddc8d2190a04ff37440041a47294aaf81b768fbd103e97c8b14add511f065bc5a3
Choice : 

ブロックごとに改行して分割する。

51972797f82189f95bd4d61eb4004dfd
58f279d7dd228df33b4f85cd09b08589
43546b02145c4cd3eba0a96038991489
406ff50ba7c2c2c9695bd362e4d89464
7c16eb41b3ce3e0308b6bfd68adbdb0f
2ab417e09b1c9b0da42cf7d962fd9a35
43249c396f6a04462d873c16fc1de6dd
c8d2190a04ff37440041a47294aaf81b
768fbd103e97c8b14add511f065bc5a3

1ブロック目+2ブロック目+最終ブロックの復号、3ブロック目+4ブロック目+最終ブロックの復号、5ブロック目+6ブロック目+最終ブロックの復号、7ブロック目+8ブロック目+最終ブロックの復号の順に行う。

$ nc silentwhisper.crypto.midnightflag.fr 18000
Choice : 1
enter your username : aaaaaaaaaaaaaa
the cipher text is : 51972797f82189f95bd4d61eb4004dfd58f279d7dd228df33b4f85cd09b0858943546b02145c4cd3eba0a96038991489406ff50ba7c2c2c9695bd362e4d894647c16eb41b3ce3e0308b6bfd68adbdb0f2ab417e09b1c9b0da42cf7d962fd9a3543249c396f6a04462d873c16fc1de6ddc8d2190a04ff37440041a47294aaf81b768fbd103e97c8b14add511f065bc5a3
Choice : 2
enter cipherText : 51972797f82189f95bd4d61eb4004dfd58f279d7dd228df33b4f85cd09b08589768fbd103e97c8b14add511f065bc5a3
your username is : b'host:127.0.01,flag:MCTF{Th1s_1s_'
Choice : 2
enter cipherText : 43546b02145c4cd3eba0a96038991489406ff50ba7c2c2c9695bd362e4d89464768fbd103e97c8b14add511f065bc5a3
your username is : b'n0t_g0Od_I_sHou1D_Be_cAuTi0us_w1'
Choice : 2
enter cipherText : 7c16eb41b3ce3e0308b6bfd68adbdb0f2ab417e09b1c9b0da42cf7d962fd9a35768fbd103e97c8b14add511f065bc5a3
your username is : b'Th_Padd1nG},garbage:AAAAAAAAAAAA'
Choice : 2
enter cipherText : 43249c396f6a04462d873c16fc1de6ddc8d2190a04ff37440041a47294aaf81b768fbd103e97c8b14add511f065bc5a3
your username is : b'AAAAAAAA,username:aaaaaaaaaaaaaa'
Choice : 

フラグ部分を結合すれば、フラグになる。

MCTF{Th1s_1s_n0t_g0Od_I_sHou1D_Be_cAuTi0us_w1Th_Padd1nG}

ZiPP0 (Cryptography)

zipファイルはパスワードがかかっている。

$ zipinfo zipp0.zip 
Archive:  zipp0.zip
Zip file size: 3624 bytes, number of entries: 3
-rwxr-x---  3.0 unx    10701 TX defN 23-Jan-12 02:02 index.html
-rw-r--r--  3.0 unx        0 BX stor 23-Jan-12 03:12 style.css
-rw-r--r--  3.0 unx       57 TX stor 23-Jan-12 03:22 flag.txt
3 files, 10758 bytes uncompressed, 3080 bytes compressed:  71.4%

このindex.htmlと同じ平文ファイルを見つけることができれば、既知平文攻撃ができる。Kali Linuxに入っているindex.htmlのサイズを見てみる。

$ ls -l /var/www/html/index.html
-rw-r--r-- 1 root root 10701 125 22:42 /var/www/html/index.html

おそらく同じものと推測できる。bkcrackでクラックする。

$ zip index.zip ./index.html
  adding: index.html (deflated 72%)
$ ./bkcrack -C zipp0.zip -c index.html -p index.html -P index.zip
bkcrack 1.5.0 - 2022-07-07
[08:07:27] Z reduction using 3016 bytes of known plaintext
100.0 % (3016 / 3016)
[08:07:27] Attack on 2681 Z values at index 180
Keys: a2cdbaab f8204097 5aa74d61
70.5 % (1889 / 2681)
[08:07:33] Keys
a2cdbaab f8204097 5aa74d61
$ ./bkcrack -C zipp0.zip -c flag.txt -k a2cdbaab f8204097 5aa74d61 -d flag.txt
bkcrack 1.5.0 - 2022-07-07
[08:08:54] Writing deciphered data flag.txt (maybe compressed)
Wrote deciphered data.
$ cat flag.txt
MCTF{N0t_S/0_S3cur3d}

(use it for the second archive ;)
MCTF{N0t_S/0_S3cur3d}