CBM CTF 2019 Writeup

この大会は2019/4/7 3:30(JST)~2019/4/8 3:30(JST)に開催されました。
今回もチームで参戦。結果は1435点で228チーム中5位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (Misc 5)

Discordの#miscチャネルにフラグが書いてある。

cbmctf{welc0me_7o_CbMcTF_2019}

image Mystry (Misc 85)

PNGファイルの方はPIET用のファイルのようだ。https://www.bertnase.de/npiet/npiet-execute.phpで実行すると、以下の文字列が得られる。

pI37_i5_fUn

steghideのパスワードとして使ってみる。

$ steghide extract -sf flag.jpg
Enter passphrase: ★pI37_i5_fUnを指定
wrote extracted data to "secret.txt".
$ cat secret.txt
cbmctf{p!e7_iS_4rt_0f_CoMput3r5}
cbmctf{p!e7_iS_4rt_0f_CoMput3r5}

Are You Fast (Scripting 40)

B mod Aを答える必要があるが、timeを先の時間に偽る必要がある。

import requests
import re

base_url = 'http://cbmctf2019.cf:3003/'

s = requests.Session()
r = s.get(base_url)
body = r.text
print body

pattern1 = 'A=(.+) and B=(.+)<br> Enter'
m = re.search(pattern1, body)
A = int(m.group(1))
B = int(m.group(2))
ans = B % A

pattern2 = 'name="time" value=(.+)></form>'
m = re.search(pattern2, body)
tm = int(m.group(1)) + 3600

post_url = base_url + 'check'
payload = {'answere': str(ans), 'time': str(tm)}
print payload
r = s.post(post_url, data=payload)
body = r.text
print body

実行結果は以下の通り。

$ python solve.py
<h1>A=45926 and B=53871<br> Enter B mod A <br></h1><form action="/check" method="post"><input type="text" id="answere" name="answere"><div class="button"><button type="submit">check</button></div><input type="hidden" id="time" name="time" value=1554624770375></form>
{'answere': '7945', 'time': '1554624773975'}
congrats!! here is the flag cbmctf{c0Nn3ct_pR0gr4m!7Ic@lLy}
cbmctf{c0Nn3ct_pR0gr4m!7Ic@lLy}

Easy_cipher (Crypto 50)

Rail Fence Cipherと推定。https://www.geocachingtoolbox.com/index.php?lang=en&page=railFenceCipherで復号する。
Base64文字列になっていそうなので、cbmctfをbase64した文字列を参考にレール数を変えてみる。
レール数3で以下のようになる。

Y2JtY3Rme1JAMWxfRmVOYzdfQzFwaGU0XzFzX2MwMGx9
$ echo Y2JtY3Rme1JAMWxfRmVOYzdfQzFwaGU0XzFzX2MwMGx9 | base64 -d
cbmctf{R@1l_FeNc7_C1phe4_1s_c00l}
cbmctf{R@1l_FeNc7_C1phe4_1s_c00l}

Any chess lover!! (Crypto 65)

文字セットと、以下の暗号文とチェス盤の画像が添付されている。

ms1r3uj@fv&!4grw((^m

f:id:satou-y:20190414214938p:plain
暗号文の長さは配置しているチェスの駒の数と同じ。文字列のテーブルも決まっているので、シフトの数を見てみる。

m  s  1  r  3  u  j
c  b  m  c  t  f  { 
10 17 15 15 10 15 15

左上から右に順番に駒ごとにシフト数が決まっていそう。チェスのことを調べていて、各駒の頭文字が関係していそうだと気づいた。文字列のテーブルは以下の通りで、シフトする数にも合致していそう。

          1111111111222222222233333333334444444444555555
01234567890123456789012345678901234567890123456789012345
abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-={}[]<>

K(キング): 10
R(ルーク): 17
P(ポーン): 15
K(ナイト): 10
B(ビショップ): 1
Q(クイーン): 16

以上のことを念頭に復号する。

table = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-={}[]<>'
enc = 'ms1r3uj@fv&!4grw((^m'
key = [10, 17, 15, 15, 10, 15, 15, 1, 15, 10, 16, 15, 1, 16, 15, 15, 15, 15, 10, 17]

flag = ''
for i in range(len(enc)):
    idx = table.index(enc[i]) - key[i]
    flag += table[idx]

print flag
cbmctf{!_l0v3_ch335}