AlexCTFに出て少し問題を解いた話

はじめに

2017/02/03 19:00~2017/02/06 17:00(日本時間)、AlexCTFがアレクサンドリア大学主催で開催されていました。例によってチームEAnbaiの一員として参加し、チームとしては1190ptで215位(/1029?)で終了しました。以下、解いた/取り組んだ問題について簡単に書きます。

解いた問題

Reversing 1 (50pt)

Stringsコマンドで文字列を見るだけで終わり。

1
2
3
4
$ strings gifted
(中略)
ALEXCTF{Y0u_h4v3_45t0n15h1ng_futur3_1n_r3v3r5ing}
(中略)

Flag: ALEXCTF{Y0u_h4v3_45t0n15h1ng_futur3_1n_r3v3r5ing}

Forensic 3 (150pt)

USB通信のキャプチャが渡されるのでWiresharkで確認する。どうやらUSB_BULK outというのが怪しく、データが入ってるっぽい。いくつかあるが、その中にそれらしきものを見つけた。

Wiresharkで開いたところ
1
89:50:4e:47:0d:0a:1a:0a:00:00:00:0d:49:48:44:.....

先頭2byteを見るとどうやらpngっぽいのでファイルにして中身を見る。

1
2
3
4
5
6
7
8
9
10
11
import struct
data = "89504e470d0a1a0a0000000d...(省略)"
raw = []
for i in range(0, len(data), 2):
raw.append(int("0x" + data[i:i + 2], 16))
f = open("fore2.png", "wb")
for x in raw:
f.write(struct.pack("B", x))
f.close()
flag

Flag: ALEXCTF{SN1FF_TH3_FL4G_OV3R_USB}

Trivia 2 (20pt)


問題文
SSL 0day
It lead to memory leakage between servers and clients rending large number of private keys accessible. (one word)

ALEXCTF{Heartbleed}?しかしこれが通らない。ここで問題文末尾の「one word」というのが引っかかる。フラグフォーマットはALEXCTF{[A-Za-z0-9_]*}となっているが、それは問題文で指定されていない時に限るとの記述が…。

Flag: Heartbleed

Trivia 4 (40pt)

AlexCTFのページにロゴにフラグが隠されているので探してね、という問題。
フラグをテキストで保存し、vimで以下の置換を適用。

「随分文字の小さいアスキーアートだなぁ」というフラグは回収された
1
:%s/[^(A-Z0-9a-z|{|})|\n|_]//g

Flag: ALEXCTF{OUR_LOGO_ROCKS}

取り組んだ問題

Reversing 4 (250pt)

pycが渡されてフラグを探す問題。pycdcを用いてPythonソースコードを復元した。

1
2
3
4
sudo apt-get install cmake
cmake
make
./pycdc unvm_me.pyc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Source Generated with Decompyle++
# File: unvm_me.pyc (Python 2.7)
import md5
md5s = [
0x831DAA3C843BA8B087C895F0ED305CE7L,
0x6722F7A07246C6AF20662B855846C2C8L,
0x5F04850FEC81A27AB5FC98BEFA4EB40CL,
0xECF8DCAC7503E63A6A3667C5FB94F610L,
0xC0FD15AE2C3931BC1E140523AE934722L,
0x569F606FD6DA5D612F10CFB95C0BDE6DL,
0x68CB5A1CF54C078BF0E7E89584C1A4EL,
0xC11E2CD82D1F9FBD7E4D6EE9581FF3BDL,
0x1DF4C637D625313720F45706A48FF20FL,
0x3122EF3A001AAECDB8DD9D843C029E06L,
0xADB778A0F729293E7E0B19B96A4C5A61L,
0x938C747C6A051B3E163EB802A325148EL,
0x38543C5E820DD9403B57BEFF6020596DL]
print 'Can you turn me back to python ? ...'
flag = raw_input('well as you wish.. what is the flag: ')
if len(flag) > 69:
print 'nice try'
exit()
if len(flag) % 5 != 0:
print 'nice try'
exit()
for i in range(0, len(flag), 5):
s = flag[i:i + 5]
if int('0x' + md5.new(s).hexdigest(), 16) != md5s[i / 5]:
print 'nice try'
exit()
continue
print 'Congratz now you have the flag'

フラグを5文字ずつに区切ってMD5ハッシュにしたものをソースコード内に保持しているので、ソースコード内のmd5ハッシュを復元すれば終わり。onlineのデコードサイトでdecryptしたものをつなげて投げたものの通らず、何でだろう…と思っていたら7つ目のハッシュが1文字足りていなかった。チームSlackに投げたところ先輩が解いてくれたので結果オーライ(とは言え悔しいので精進します(´・ω・`))。頭に0をつけるだけの発想がどうして出てこなかったんだろう…。

Trivia 3

僕「CA issueって言ってるし何か問題あるんじゃね!?」
sio「issuedだと『発行する』の意になるってよ」
僕「魔剤!?(カチカチ…)letsencrypt」

> フラグだった <

問題文適当に読みすぎた。英語勉強し直したほうが良い。

おわりに

これはCTFに限らず、自分で箱を作ってその中で考えるのではなく、試せるだけの可能性を試すことが大事だと感じました(特にfore3)。
また、暗号系の問題を先輩に任せっきりなので、どうにか来年は暗号系もある程度解けるように真面目に数学勉強し直そうと思いました。
以上です。