SECCON2016決勝大会と同時開催された「CTF for ビギナーズ 2016 FINAL @東京」(通称ctf4b)に参加したので、解いた問題の解説(writeup)を載せます。
SECCONというのは、情報セキュリティをテーマに多様な競技を開催する情報セキュリティコンテストイベントです。(http://2016.seccon.jp/about/ より引用)
CTFは「Capture The Flag」の略で、情報セキュリティ技術を活かした競技のことです。
詳しくはキャプチャー・ザ・フラッグ - Wikipediaを参照してください。
以下の各見出しは「問題名 (ポイント数, ジャンル)」で書いています。
Welcome (100, Misc)
問題文
Welcome to CTF fo r Beginners to Tokyo Final
flag : ctf4b{CTF_for_Beginners_to_Tokyo_Final}
解説
練習用問題。
問題文にあるフラグが答え。
CountUp Game (200, Misc)
問題文
交互にカウントアップしていこう
ただし,21を言ってはいけません
次のコマンドを実行してゲームに接続してください.
linux: “nc 172.20.1.30 10001”
解説
上記コマンドをLinuxで実行すると、カウントアップゲームが始まる。
ルールは下記の通り。
(子供のころに皆遊んだことがあるであろう「30言ったら負けゲーム」とほぼ同じ)
- 1から順に相手(プログラム)と交互に数字を言って、21を言ったほうが負け
- 1回につき3つまで数字を言っていい
- 常に相手が先攻
画面には「0/10」という表示があり、1戦勝つと「1/10」となったので、
10戦勝てばフラグがゲットできると予想した。
このゲームで必ず勝つには、言ってはいけない数字の直前の数字(今回の場合は 20)から4の倍数を引いた数(今回の場合は 20,16,12,8,4)で自分のターンが終わるようにすればいい。
例えば、相手が「1」と言ったら、自分は「2,3,4」と言う。
10戦程度なら地道に上記の必勝法で10戦勝つほうが早いと判断し、10戦勝って無事にフラグゲット
(スマートな解き方ではないですね笑)
Classical Injection (100, Web)
問題文
http://172.20.1.60/100_1/
解説
うろ覚えだが、ブラウザで上記URLにアクセスすると、入力フォームがあって、
単純なSQLインジェクション ' or 1=1 --
を入れると、フラグゲット
(かなり記憶があいまいです。。。)
May the extensions be with you. (100, Web)
問題文
http://172.20.1.60/100_2/
解説
ブラウザで上記URLにアクセスすると、ページが表示された。
(何か文が書いてあったけど覚えていない。。。)
問題名を手掛かりに、講義で習ったChrome ExtensionのEditThisCookieを使うと、
false
という値が入ったCookieが存在することが分かった。
この値をtrue
に書き換えて、ページ再読み込みすると、フラグゲット
(これも記憶があいまい。。。)
あけてみよう (200, Forensics)
問題文
http://172.20.1.1/ctf/forensics/for200-1.pcap
解説
上記ファイルをWiresharkで開いて、とりあえずhttpでフィルタをかける。
すると、以下のHTTPリクエストとそれに対するレスポンスが見つかった。
GET /transfer.zip HTTP/1.1
HTTPレスポンスのパケットを選択し、メニューバーのFile -> Export Objects -> HTTP で、transfer.zip
を抽出。
fileコマンドでzipファイルであることを確認し、unzipで展開すると2.pcap
が出てきた。
ctf4b@ctf4b-vm:~/Downloads/ctf/aketemiyou$ file transfer.zip
transfer.zip: Zip archive data, at least v2.0 to extract
ctf4b@ctf4b-vm:~/Downloads/ctf/aketemiyou$ unzip transfer.zip
Archive: transfer.zip
inflating: 2.pcap
ctf4b@ctf4b-vm:~/Downloads/ctf/aketemiyou$ ll
合計 60
drwxrwxr-x 2 ctf4b ctf4b 4096 1月 29 23:47 ./
drwxrwxr-x 9 ctf4b ctf4b 4096 1月 29 22:20 ../
-rw-rw-r-- 1 ctf4b ctf4b 16967 10月 20 00:23 2.pcap
-rw-rw-r-- 1 ctf4b ctf4b 13173 1月 29 14:14 for200-1.pcap
-rw-r--r-- 1 ctf4b ctf4b 9088 1月 29 23:44 transfer.zip
2.pcap
をWiresharkで開き、メニューバーのStatistics -> Protocol Hierarchyで見てみると、
FTPのデータ転送が行われていることがわかる。
明らかに怪しいので、FTP-DATAでフィルタすると、パケットが3つ見つかった。
その中で一番サイズが大きいパケットを右クリック -> Follow -> TCP Stream を開く。
Show data as
をUTF-8
にすると、先頭にPK
の文字があるので、zipファイルと判断。
Show data as
をraw
にして、hoge.zip
という名前で保存。
hoge.zip
を展開すると、secret
ディレクトリとその下にflag.png
がある。
ctf4b@ctf4b-vm:~/Downloads/ctf/aketemiyou$ ll
合計 68
drwxrwxr-x 2 ctf4b ctf4b 4096 1月 29 23:49 ./
drwxrwxr-x 9 ctf4b ctf4b 4096 1月 29 22:20 ../
-rw-rw-r-- 1 ctf4b ctf4b 16967 10月 20 00:23 2.pcap
-rw-rw-r-- 1 ctf4b ctf4b 13173 1月 29 14:14 for200-1.pcap
-rw-rw-r-- 1 ctf4b ctf4b 6065 1月 29 23:49 hoge.zip
-rw-r--r-- 1 ctf4b ctf4b 9088 1月 29 23:44 transfer.zip
ctf4b@ctf4b-vm:~/Downloads/ctf/aketemiyou$ file hoge.zip
hoge.zip: Zip archive data, at least v1.0 to extract
ctf4b@ctf4b-vm:~/Downloads/ctf/aketemiyou$ unzip hoge.zip
Archive: hoge.zip
creating: secret/
inflating: secret/flag.png
ctf4b@ctf4b-vm:~/Downloads/ctf/aketemiyou$ ll
合計 72
drwxrwxr-x 3 ctf4b ctf4b 4096 1月 29 23:49 ./
drwxrwxr-x 9 ctf4b ctf4b 4096 1月 29 22:20 ../
-rw-rw-r-- 1 ctf4b ctf4b 16967 10月 20 00:23 2.pcap
-rw-rw-r-- 1 ctf4b ctf4b 13173 1月 29 14:14 for200-1.pcap
-rw-rw-r-- 1 ctf4b ctf4b 6065 1月 29 23:49 hoge.zip
drwxr-xr-x 2 ctf4b ctf4b 4096 10月 20 00:09 secret/
-rw-r--r-- 1 ctf4b ctf4b 9088 1月 29 23:44 transfer.zip
ctf4b@ctf4b-vm:~/Downloads/ctf/aketemiyou$
このflag.png
を画像ビュワーで開くと、以下のフラグゲット
ctf4b{f0ll0w7cp57r34m}
(follow tcp streamですね)
HiddenFlag (100, Binary)
問題文
フラグが何処かに隠れている・・・
問題バイナリ:http://172.20.1.1/ctf/binary/bin100_1
解説
上記バイナリファイルをDownloadして、fileコマンドで見ると、Linuxの実行ファイルであることがわかる。
ctf4b@ctf4b-vm:~/Downloads/ctf/HiddenFlag$ file bin100_1
bin100_1: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=d36321b101c8d2681dbf919de7e09f69f1c15304, stripped
とりあえずstringsコマンドを実行すると、フラグゲット
ctf4b@ctf4b-vm:~/Downloads/ctf/HiddenFlag$ strings bin100_1 | grep ctf4b
ctf4b{fl4g_1n_d474_53gm3n7}
(flag_in_data_segmentですかね)
復習 (200, Binary)
問題文
講義の内容を覚えているかな?
思い出しながら,計算してみよう!
逆アセンブル結果:http://172.20.1.1/ctf/binary/bin200_1_objdump.txt
flag形式:ctf4b{Stage1の答え_Stage2の答え} (例:ctf4b{10_20})
解説
上記ファイルの中身は下記
0804865f <Stage1>:
804865f: 55 push ebp
8048660: 89 e5 mov ebp,esp
8048662: 83 ec 10 sub esp,0x10
8048665: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
8048668: c7 00 0a 88 04 08 mov DWORD PTR [eax],0x804880a
804866e: 90 nop
804866f: 90 nop
8048670: c7 45 f8 03 00 00 00 mov DWORD PTR [ebp-0x8],0x3
8048677: 8b 55 f8 mov edx,DWORD PTR [ebp-0x8]
804867a: 89 d0 mov eax,edx
804867c: c1 e0 03 shl eax,0x3
804867f: 29 d0 sub eax,edx
8048681: 89 45 fc mov DWORD PTR [ebp-0x4],eax
8048684: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
8048687: 83 c0 02 add eax,0x2
804868a: 89 45 f8 mov DWORD PTR [ebp-0x8],eax
804868d: 90 nop
804868e: 90 nop
804868f: 8b 45 f8 mov eax,DWORD PTR [ebp-0x8]
8048692: c9 leave
8048693: c3 ret
08048694 <Stage2>:
8048694: 55 push ebp
8048695: 89 e5 mov ebp,esp
8048697: 83 ec 10 sub esp,0x10
804869a: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
804869d: c7 00 11 88 04 08 mov DWORD PTR [eax],0x8048811
80486a3: 90 nop
80486a4: 90 nop
80486a5: c7 45 f8 01 00 00 00 mov DWORD PTR [ebp-0x8],0x1
80486ac: c7 45 fc 01 00 00 00 mov DWORD PTR [ebp-0x4],0x1
80486b3: eb 0e jmp 80486c3 <Stage2+0x2f>
80486b5: 8b 45 f8 mov eax,DWORD PTR [ebp-0x8]
80486b8: 0f af 45 fc imul eax,DWORD PTR [ebp-0x4]
80486bc: 89 45 f8 mov DWORD PTR [ebp-0x8],eax
80486bf: 83 45 fc 01 add DWORD PTR [ebp-0x4],0x1
80486c3: 83 7d fc 05 cmp DWORD PTR [ebp-0x4],0x5
80486c7: 7e ec jle 80486b5 <Stage2+0x21>
80486c9: 90 nop
80486ca: 90 nop
80486cb: 8b 45 f8 mov eax,DWORD PTR [ebp-0x8]
80486ce: c9 leave
80486cf: c3 ret
Stage1とStage2でeaxレジスタに最後に入る値を地道に計算すると、フラグゲット
Stage2は講義でやったやつ(1から5の総和を求める処理)と処理内容がかなり似てたのと、imul命令があることから、答えは5の階乗だと予想したら見事正解。
UnusedFunction (200, Binary)
問題文
使われていない関数があるぞ
問題バイナリ:http://172.20.1.1/ctf/binary/bin200_2
解説
上記ファイルをDownloadして、とりあえずfileコマンドで確認
ctf4b@ctf4b-vm:~/Downloads/ctf/UnusedFunction$ file bin200_2
bin200_2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=89e81238c140040714f5eeabeb2c9c2f8c380ddf, not stripped
Linuxの実行ファイルであることがわかるので、とりあえず実行する。
ctf4b@ctf4b-vm:~/Downloads/ctf/UnusedFunction$ ./bin200_2
How can I generate flag ??
ctf4b@ctf4b-vm:~/Downloads/ctf/UnusedFunction$
flagを生成する方法を尋ねられた。。。
次にobjdumpしてみる。
ctf4b@ctf4b-vm:~/Downloads/ctf/UnusedFunction$ objdump -M intel -d bin200_2 > dump.txt
ctf4b@ctf4b-vm:~/Downloads/ctf/UnusedFunction$ ll
合計 36
drwxrwxr-x 2 ctf4b ctf4b 4096 1月 30 22:29 ./
drwxrwxr-x 9 ctf4b ctf4b 4096 1月 29 22:20 ../
-rwxrw-r-- 1 ctf4b ctf4b 7413 1月 29 14:22 bin200_2*
-rw-rw-r-- 1 ctf4b ctf4b 14000 1月 30 22:29 dump.txt
dump.txt
のmain関数付近は以下の通り。
main関数のすぐ下にgenflag
という明らかに怪しい関数がある。
0804849d <main>:
804849d: 55 push ebp
804849e: 89 e5 mov ebp,esp
80484a0: 83 e4 f0 and esp,0xfffffff0
80484a3: 83 ec 10 sub esp,0x10
80484a6: c7 04 24 30 86 04 08 mov DWORD PTR [esp],0x8048630
80484ad: e8 be fe ff ff call 8048370 <puts@plt>
80484b2: c9 leave
80484b3: c3 ret
080484b4 <genflag>:
80484b4: 55 push ebp
80484b5: 89 e5 mov ebp,esp
80484b7: 53 push ebx
80484b8: 83 ec 44 sub esp,0x44
80484bb: 65 a1 14 00 00 00 mov eax,gs:0x14
80484c1: 89 45 f4 mov DWORD PTR [ebp-0xc],eax
80484c4: 31 c0 xor eax,eax
80484c6: c6 45 d5 63 mov BYTE PTR [ebp-0x2b],0x63
80484ca: c6 45 d6 74 mov BYTE PTR [ebp-0x2a],0x74
80484ce: c6 45 d7 66 mov BYTE PTR [ebp-0x29],0x66
80484d2: c6 45 d8 34 mov BYTE PTR [ebp-0x28],0x34
80484d6: c6 45 d9 62 mov BYTE PTR [ebp-0x27],0x62
80484da: c6 45 da 7b mov BYTE PTR [ebp-0x26],0x7b
80484de: c6 45 db 34 mov BYTE PTR [ebp-0x25],0x34
80484e2: c6 45 dc 6e mov BYTE PTR [ebp-0x24],0x6e
80484e6: c6 45 dd 34 mov BYTE PTR [ebp-0x23],0x34
80484ea: c6 45 de 6c mov BYTE PTR [ebp-0x22],0x6c
80484ee: c6 45 df 79 mov BYTE PTR [ebp-0x21],0x79
80484f2: c6 45 e0 7a mov BYTE PTR [ebp-0x20],0x7a
80484f6: c6 45 e1 33 mov BYTE PTR [ebp-0x1f],0x33
80484fa: c6 45 e2 5f mov BYTE PTR [ebp-0x1e],0x5f
80484fe: c6 45 e3 75 mov BYTE PTR [ebp-0x1d],0x75
8048502: c6 45 e4 6e mov BYTE PTR [ebp-0x1c],0x6e
8048506: c6 45 e5 75 mov BYTE PTR [ebp-0x1b],0x75
804850a: c6 45 e6 35 mov BYTE PTR [ebp-0x1a],0x35
804850e: c6 45 e7 33 mov BYTE PTR [ebp-0x19],0x33
8048512: c6 45 e8 64 mov BYTE PTR [ebp-0x18],0x64
8048516: c6 45 e9 5f mov BYTE PTR [ebp-0x17],0x5f
804851a: c6 45 ea 66 mov BYTE PTR [ebp-0x16],0x66
804851e: c6 45 eb 75 mov BYTE PTR [ebp-0x15],0x75
8048522: c6 45 ec 6e mov BYTE PTR [ebp-0x14],0x6e
8048526: c6 45 ed 63 mov BYTE PTR [ebp-0x13],0x63
804852a: c6 45 ee 37 mov BYTE PTR [ebp-0x12],0x37
804852e: c6 45 ef 31 mov BYTE PTR [ebp-0x11],0x31
8048532: c6 45 f0 30 mov BYTE PTR [ebp-0x10],0x30
8048536: c6 45 f1 6e mov BYTE PTR [ebp-0xf],0x6e
804853a: c6 45 f2 7d mov BYTE PTR [ebp-0xe],0x7d
804853e: c6 45 f3 00 mov BYTE PTR [ebp-0xd],0x0
8048542: c7 04 24 07 00 00 00 mov DWORD PTR [esp],0x7
8048549: e8 12 fe ff ff call 8048360 <malloc@plt>
804854e: 89 45 d0 mov DWORD PTR [ebp-0x30],eax
8048551: c7 45 cc 00 00 00 00 mov DWORD PTR [ebp-0x34],0x0
8048558: eb 19 jmp 8048573 <genflag+0xbf>
804855a: 8b 55 cc mov edx,DWORD PTR [ebp-0x34]
804855d: 8b 45 d0 mov eax,DWORD PTR [ebp-0x30]
8048560: 01 c2 add edx,eax
8048562: 8d 4d d5 lea ecx,[ebp-0x2b]
8048565: 8b 45 cc mov eax,DWORD PTR [ebp-0x34]
8048568: 01 c8 add eax,ecx
804856a: 0f b6 00 movzx eax,BYTE PTR [eax]
804856d: 88 02 mov BYTE PTR [edx],al
804856f: 83 45 cc 01 add DWORD PTR [ebp-0x34],0x1
8048573: 8b 45 cc mov eax,DWORD PTR [ebp-0x34]
8048576: 83 f8 06 cmp eax,0x6
8048579: 76 df jbe 804855a <genflag+0xa6>
804857b: 8b 45 d0 mov eax,DWORD PTR [ebp-0x30]
804857e: 8b 5d f4 mov ebx,DWORD PTR [ebp-0xc]
8048581: 65 33 1d 14 00 00 00 xor ebx,DWORD PTR gs:0x14
8048588: 74 05 je 804858f <genflag+0xdb>
804858a: e8 c1 fd ff ff call 8048350 <__stack_chk_fail@plt>
804858f: 83 c4 44 add esp,0x44
8048592: 5b pop ebx
8048593: 5d pop ebp
8048594: c3 ret
8048595: 66 90 xchg ax,ax
8048597: 66 90 xchg ax,ax
8048599: 66 90 xchg ax,ax
804859b: 66 90 xchg ax,ax
804859d: 66 90 xchg ax,ax
804859f: 90 nop
mov BYTE PTR ~
という命令がずらっと続く部分がフラグっぽい匂いがするので、
第2オペランドの16進数値を抜き出して、RubyでASCII文字に変換するとフラグゲット
ctf4b@ctf4b-vm:~/Downloads/ctf/UnusedFunction$ irb
irb(main):001:0> ["63", "74", "66", "34", "62", "7b", "34", "6e", "34", "6c", "79", "7a", "33", "5f", "75", "6e", "75", "35", "33", "64", "5f", "66", "75", "6e", "63", "37", "31", "30", "6e", "7d", "0"].each{|c| print c.hex.chr}; puts
ctf4b{4n4lyz3_unu53d_func710n}
=> nil
感想
約400名中、12位だったので嬉しさもあったけど、簡単な問題(Forensicsの100点問題)を解けなかったり、惜しいところまでいった問題がいくつかあったりしたのが悔しい。
演習前に行われた講義は少しペースが速くて、ついていくので精一杯だったけど、役立つツール(binwalk, flsなど)や問題へのアプローチ方法を学べたので非常に有意義だった。