SECCON Beginners CTF 2019 Writeup

5月25日(土)15:00から24時間開催されたSECCON Beginners CTF 2019に参加しました。チームとしては9問解答することができ、私はそのうち5問(Reversingの[warmup]Seccompare, Leakage, Linear Operation, CryptoのSo Tired, MiscのDump)解いたので、そのWriteupを作成しました。個人的にはpwnの問題が一問も解けなかったのが悲しかったですね。

 

[warmup]Seccompare

適当な引数を見つける問題。ltraceコマンドで解答。

f:id:bankingmalware:20190527094620p:plain

 

・Leakage

同じく適当な引数を見つける問題。GhidraやHooperでソースコードを見ると、1文字ずつ34回フラグと比較していることがわかった。angrで解こうとするもなぜかうまく行かず、結局gdbでブレイクポイントを仕掛け、1文字ずつ確認していくというよくない解き方になりました(スクリプトとかをすぐにかけるスキルを身に付けたいですね)

f:id:bankingmalware:20190527100404p:plain

is_correct関数の様子。1度目のループではRAXに'c'が格納される。2度目は’t’が格納され、ctf4b{フラグ}になると推測。

・Linear Operation

同じく適当な引数を見つける問題。GhidraやHooperでソースコードを見ると、解読する心が折れたので、angrを試みると秒殺でした。

import angr
proj = angr.Project("./linear_operation", load_options={"auto_load_libs": False})
addr_main = 0x40cee1
initial_state = proj.factory.blank_state(addr=addr_main)
path_group = proj.factory.path_group(initial_state)
e = path_group.explore(find=(0x40cf7f,), avoid=(0x40cf7f,))

print('start')
if len(e.found) > 0:
    print('Dump stdin at succeeded():')
    s = e.found[0].state
    print "%r" % s.posix.dumps(0)

 

・So tired

与えられた暗号化されたファイルをみるとbase64エンコードされている。デコードするとzlib形式のファイルが出てきたので、解凍すると再びbase64のファイルが出力され、以下ループする。手動では辛いので、汚いですが上のデコードと解凍を繰り返し行う以下のスクリプトを作成すると、フラグが入ったファイルが出力されました。

#/bin/sh

i=0
j=1
k=2
while [ $i -lt 2000 ]
do
    base64 -D "./temp"$i > "./temp"$j
    zlib --decompress < "./temp"$j > "./temp"$k
    i=`expr $i + 2`
    j=`expr $i + 1` 
    k=`expr $j + 1`

 

・Dump

Pcapを解析する問題。Pcapをみてみると、サーバからFLAGファイルをダウンロードしている通信が確認できた。Follow TCPをすると通信の中身が8進数でみえ、2バイト分のみ8進数を16進数に変換すると、1F 8Bとなったのでzlib形式のファイルだと推測。ここからうまくtsharkでうまく8進数のバイト→16進数のバイトに変換するスクリプトをかければ良いのですが、tsharkを使ったことがなく、断念。結局、Wiresharkで見れた通信をコピー→文字列としてファイルに貼り付け→Pythonで文字列をByteにして出力する下記プログラムを作成して、できたファイルをzlibで解凍すればpngファイルが出力され、そこにフラグがありました。

from struct import *
f = open('Dump','r')
line = f.readline()

with open("data", "wb") as fout:
while line:
splitline = line.split(" ")
for item in splitline:
  i = int(item, 8)
  fout.write(pack('B', i))
line = f.readline()
f.close()

 

今後も定期的にスキルアップの為に参加していこうと思います。