BambooFox CTF 2021 Writeup

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

Sanity Check (Welcome)

Discordに入り、#announcementsチャネルのメッセージを見ると、フラグが書いてあった。

flag{W3lc0m3_70_B4mb00F0x_CTF_2021_GLHF!}

Ransomware (Reverse)

uncompyle6でデコンパイルする。

$ uncompyle6 task.pyc
# uncompyle6 version 3.7.4
# Python bytecode 3.8 (3413)
# Decompiled from: Python 2.7.17 (default, Sep 30 2020, 13:38:04) 
# [GCC 7.5.0]
# Warning: this version of Python has problems handling the Python 3 "byte" type in constants properly.

# Embedded file name: task.py
# Compiled at: 2021-01-14 23:13:24
# Size of source mod 2**32: 420 bytes
(lambda data, key, iv: if len(data) != 0:
(lambda key, iv, data, AES: open('flag.enc', 'wb').write(AES.new(key, AES.MODE_CBC, iv).encrypt(lambda x: x + '\x00' * (16 - len(x) % 16)(data))))(data[key:key + 16], data[iv:iv + 16], open('flag.png', 'rb').read(), __import__('Crypto.Cipher.AES').Cipher.AES) # Avoid dead code: lambda fn: __import__('os').remove(fn)('task.py'))(__import__('requests').get('https://ctf.bamboofox.tw/rules').text.encode(), 99, 153)
# okay decompiling task.pyc

理解しやすいように整形する。

(lambda data, key, iv:
    if len(data) != 0:
        (lambda key, iv, data, AES: 
            open('flag.enc', 'wb').write(AES.new(key, AES.MODE_CBC, iv)
            .encrypt(lambda x: x + '\x00' * (16 - len(x) % 16)(data))
            )
        )
        (data[key:key + 16], data[iv:iv + 16],
         open('flag.png', 'rb').read(),
         __import__('Crypto.Cipher.AES').Cipher.AES)

    # Avoid dead code: lambda fn: __import__('os').remove(fn)('task.py')
)
(__import__('requests').get('https://ctf.bamboofox.tw/rules').text.encode(), 99, 153)

AES-CBCで暗号化されている。

dataはhttps://ctf.bamboofox.tw/rulesから取得したデータ。
暗号化鍵はdataのインデックス99から16バイト。
IVはインデックス153から16バイト。

これを元にPNGファイルに復号する。

from Crypto.Cipher import AES
import requests

with open('flag.enc', 'rb') as f:
    enc = f.read()

data = requests.get('https://ctf.bamboofox.tw/rules').text
key = data[99:99+16]
iv = data[153:153+16]

cipher = AES.new(key, AES.MODE_CBC, iv)
flag = cipher.decrypt(enc).rstrip('\x00')

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

f:id:satou-y:20210122230833p:plain
復号した画像には、フラグは書いていなかった。代わりに以下のメッセージがある。

flag is after this picture

バイナリエディタで見ると、PNGの後ろに、またPNGが入っている後半のPNGを切り出し、画像を見ると、フラグが書いてあった。
f:id:satou-y:20210122230901p:plain

flag{345y_l4_h4iy44444444}