yyy

CTFつよくなりたい

CSAW CTF 2016 Writeup

9/17早朝から9/19早朝までの2日間開催されたCSAW CTF 2016に「wabisabi」で参加しました。結果はチームで8問解いて576pt、1274チーム中252位。にこにー(矢澤にこ)が好きな自分にとってはラッキーな数字でした。自分は4問解いて300pt入れました。今回はその4問について簡単にwriteupを残したいと思います。

Writeup

Forensics 100: Clams Don't Dance

最近、諸事情でforensicsを勉強することになり、今回は何問か解きたいなと思っていたため最初にこれに取り掛かりました。

問題は、まず out.img というファイルを渡されます。

お決まりのfileコマンド

f:id:ywkw1717:20160919173755p:plain

boot sector らしい。

そういえばksnctfでも同じような問題あったなと、とりあえずFTK Imagerで開いてみる。

f:id:ywkw1717:20160919174322p:plain

削除されたものである、clam.pptxというファイルが見つかる。

その他にも怪しげなdance.mp4というファイルがあったが、問題名のClams Don't Danceからこれは違うと予想してスルー。

clam.pptxを取り出して、自分はubuntuなのでLibreOfficeで開こうとするも開けない。(修復を試みますか?とか聞かれるけど無理だった)

どうしようかと思ったが、とりあえずbinwalkに投げてみればいくつか取り出せるんじゃないかと思い、投げてみる。

すると大量のファイルを取り出すことができ、怪しそうなものはないか見ていく。

ppt/mediaにimage0.gifというファイル名で、なにやらQRコードらしきものが見つかる。

f:id:ywkw1717:20160919175220p:plain

なにこれ・・・となったが、困った時のGoogle先生

画像検索してみるとどうやら「MaxiCode」というものらしい。

これを読み取るフリーのツールを探すもなかなか見つからなかったが、最終的に「ByteScout BarCode Reader」というソフトに辿り着く。

f:id:ywkw1717:20160919180359p:plain

読み取ってみたところ綺麗にflagが出てきた。


flag{TH1NK ABOUT 1T B1LL. 1F U D13D, WOULD ANY1 CARE??}

Reversing 50: Gametime

チームでは一応binary担当ということになっている(辛い)ので何問かは解こうと思い、最初に一番簡単なやつをやってみる。

gametime.exeというファイルを渡され、問題文にはflagの形式は↑のようなものじゃないよと書かれていた。

最近Ollydbgを使っていたのでidaではなくOllydbgを使ってみる。

実行してみると、「sが見えたらspace bar押してね」や「xが見えたらxを押す」、「mが見えたらmを押す」というゲーム。(説明が下手)

とりあえず、分岐命令辺りでブレークポイントを設定してみてゲームが終わらないように上手く回避していく。

すると、TURBO TIME!とか始まって、flagがゲットできた。


f:id:ywkw1717:20160919182427p:plain


no5c30416d6cf52638460377995c6a8cf5

Reversing 125: Key

key.exeというファイルが渡されるので、またOllydbgで実行してみる。

What happen?(だったかな?)、まぁそんな英文が表示されて終了するだけのプログラム。

また、分岐命令辺りにブレークポイント設定しながら進めていくが最終的に

=W=r=o=n=g=K=e=y=

とか表示されて、終わってしまう。

ここで、スタック上に積まれた文字列に注目してみた。

まさかな?と思い、とりあえずsubmit(これ大事)してみると通った。

f:id:ywkw1717:20160919183119p:plain

f:id:ywkw1717:20160919183133p:plain



idg_cni~bjbfi|gsxb

(この問題に関してはwriteupになっていない気がするが、許してほしい)

Misc 25: Coinslot

Recon 200 の Fuzyllという問題が途中で詰まってしまい、なにか他の解いたほうが良さそうと思って始めた問題。

nc misc.chal.csaw.io 8000

につないでみると、紙幣などの枚数を求める的な問題。途中でミスるとアウト。

f:id:ywkw1717:20160919192108p:plain

手動で10回ぐらいまでやってみたが、もっともっと回数が必要そう。

今まで、スクリプトを書けば簡単に終わりそうな問題も「面倒くさい」という理由から逃げてきたため、いつもの自分だったら解かなかったと思う。

だけど、今回は何かしら成長したいと思ったのかどうか知らないが、早朝4時過ぎからコードを書き始めた。

結果、くそコードを生み出してしまった。反省はして(ry

以下のスクリプトを回した結果、20分くらい?(400回目)で解けた。

(一応999回で書いたが、途中で1000回までいかないよな・・・?とか思って、少し不安だった)

#!/usr/bin/env python
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('misc.chal.csaw.io', 8000))

for i in range(1, 1000):
    data = s.recv(256)
    print data

    all_data  = data.split('\n')
    num_s     = all_data[0].replace('$', '')
    num       = num_s.split('.')
    big_num_s = num[0]
    sml_num_s = num[1]

    big_num   = int(big_num_s)

    if big_num / 10000 > 0:
        s.sendall(str(big_num/10000) + '\n')
        big_num = big_num % 10000
    else:
        s.sendall('0\n')

    data = s.recv(256)
    print data

    if big_num / 5000 > 0:
        s.sendall(str(big_num/5000) + '\n')
        big_num = big_num % 5000
    else:
        s.sendall('0\n')

    data = s.recv(256)
    print data

    if big_num / 1000 > 0:
        s.sendall(str(big_num/1000) + '\n')
        big_num = big_num % 1000
    else:
        s.sendall('0\n')

    data = s.recv(256)
    print data

    if big_num / 500 > 0:
        s.sendall(str(big_num/500) + '\n')
        big_num = big_num % 500
    else:
        s.sendall('0\n')

    data = s.recv(256)
    print data

    if big_num / 100 > 0:
        s.sendall(str(big_num/100) + '\n')
        big_num = big_num % 100
    else:
        s.sendall('0\n')

    data = s.recv(256)
    print data

    if big_num / 50 > 0:
        s.sendall(str(big_num/50) + '\n')
        big_num = big_num % 50
    else:
        s.sendall('0\n')

    data = s.recv(256)
    print data

    if big_num / 20 > 0:
        s.sendall(str(big_num/20) + '\n')
        big_num = big_num % 20
    else:
        s.sendall('0\n')

    data = s.recv(256)
    print data

    if big_num / 10 > 0:
        s.sendall(str(big_num/10) + '\n')
        big_num = big_num % 10
    else:
        s.sendall('0\n')

    data = s.recv(256)
    print data

    if big_num / 5 > 0:
        s.sendall(str(big_num/5) + '\n')
        big_num = big_num % 5
    else:
        s.sendall('0\n')

    data = s.recv(256)
    print data

    if big_num / 1 > 0:
        s.sendall(str(big_num/1) + '\n')
        big_num = big_num % 1
    else:
        s.sendall('0\n')

    data = s.recv(256)
    print data
    check = sml_num_s[:1]

    if check == '0':
        sml_num = int(sml_num_s[1:])
        for i in range(0, 3):
            s.sendall('0\n')
            s.recv(256)
            print data

        if sml_num / 5 > 0:
            s.sendall(str(sml_num/5) + '\n')
            sml_num = sml_num % 5
        else:
            s.sendall('0\n')

        data = s.recv(256)
        print data

        if sml_num / 1 > 0:
            s.sendall(str(sml_num/1) + '\n')
            sml_num = sml_num % 1
        else:
            s.sendall('0\n')
    else:
        sml_num = int(sml_num_s)
        if sml_num / 50 > 0:
            s.sendall(str(sml_num/50) + '\n')
            sml_num = sml_num % 50
        else:
            s.sendall('0\n')

        data = s.recv(256)
        print data

        if sml_num / 25 > 0:
            s.sendall(str(sml_num/25) + '\n')
            sml_num = sml_num % 25
        else:
            s.sendall('0\n')

        data = s.recv(256)
        print data

        if sml_num / 10 > 0:
            s.sendall(str(sml_num/10) + '\n')
            sml_num = sml_num % 10
        else:
            s.sendall('0\n')

        data = s.recv(256)
        print data

        if sml_num / 5 > 0:
            s.sendall(str(sml_num/5) + '\n')
            sml_num = sml_num % 5
        else:
            s.sendall('0\n')

        data = s.recv(256)
        print data

        if sml_num / 1 > 0:
            s.sendall(str(sml_num/1) + '\n')
            sml_num = sml_num % 1
        else:
            s.sendall('0\n')

    print "Now,",i, " wait...\n"

    data = s.recv(9)
    print data

f:id:ywkw1717:20160919192045p:plain

flag{started-from-the-bottom-now-my-whole-team-fucking-here}

まとめ

Misc 25のCoinslotを解いたのが9/19の早朝5時半頃。

このあと、なぜかあと1日あると思い込んでいて、明日頑張ろうと思い寝てしまった。

起きたら11時半でCTF終わってるし、9時からバイトあったのに思いっきり遅刻したし、散々だった。。。

でも、今回のCTFは割と楽しかった。



pwnが弱すぎるので勉強します・・・

おまけ

Recon 200: Fuzyll

解けなかったが、解けたところまでメモ。

問題文で与えられた、http://fuzyll.com/files/csaw2016/startにアクセスしてみる。

すると、次のような文章。

CSAW 2016 FUZYLL RECON PART 1 OF ?: People actually liked last year's challenge, so CSAW made me do it again... Same format as last year, new stuff you need to look up. The next part is at /csaw2016/the form of colorblindness I have.

色盲の種類について調べてみて、いくつか試したところ、「deuteranomaly」で正解。

http://fuzyll.com/files/csaw2016/deuteranomaly

にアクセスしてみたら、赤ではないいちごの画像が表示された。保存しようとしたところなぜか拡張子がtxt。

とりあえず保存して、先頭4バイト辺りのバイナリを見てみるもやっぱりpngなので拡張子をpngに変えて、開く。

プロパティとか見てみると、

f:id:ywkw1717:20160919194303p:plain

こんな感じで次のhintが見つかる。

とりあえず、Fuzyllさんについて調べる。

どうやら過去のCSAW CTFでも出されている問題らしく、彼のプロフィールも簡単に見つけることができた。

https://ctf.csaw.io/static/archives/2013/judges/index.html

そこにはCTFにどのチームで出場していたか、などが記されていた。さらに、DEF CON finalに出場したチームなどを
CTFtime.org / All about CTF (Capture The Flag)
あたりで調べて絞っていった。

するとDEF CON 19(2011)にて、Fuzyllが所属していたHates Ironyが3位に入賞していた。(すごい)

よって、ctf timeに載っていたDEF CON 19の問題をかたっぱしから試していく。

すると、「tomato」で正解。

http://fuzyll.com/files/csaw2016/tomato

にアクセスしたところ、文字化けした文章が表示された。


テ簔襦@ニ蓚勒モ@ルナテヨユ@ラチル紂昧@oz@ノ@�扶」@��@悼着@」又▲妹「Z@チ物ヲ→k@巳」「延�@昧@テ翦「k@ノ}・�@e�@欄→鴛① �甥@#巳淵@昧@譁剴А昧@諱凖凵�@箕�@」�@浴「」@ィ�僉M腐・�@」�、㊧」@ノ}Аe@「→鴛①」�」@≧」�@テ▲<鐙「婆@う」@�刔@ヲ�@☆�]K@繹�@腐ァ」@浴劵@欧@▲@aΔ※aL畑@煤鴛@譁襦ヨ☆<」�}「@普賠nK

で持ってきて、nkfで調べると「CP932」というやつらしい。

いろいろ調べて、utf-8に直すために

iconv -f cp932 -t utf8 tomato > hoge

とかしてみるも無理。

ここで諦めた。


他の人のwriteupを読ませて頂きます・・・。



f:id:ywkw1717:20160919200545j:plain