CTF for ビギナーズ 2016 FINAL @東京 writeup

SECCON2016決勝大会と同時開催された「CTF for ビギナーズ 2016 FINAL @東京」（通称ctf4b）に参加したので、解いた問題の解説（writeup）を載せます。

SECCONというのは、情報セキュリティをテーマに多様な競技を開催する情報セキュリティコンテストイベントです。（http://2016.seccon.jp/about/ より引用）

CTFは「Capture The Flag」の略で、情報セキュリティ技術を活かした競技のことです。
詳しくは[キャプチャー・ザ・フラッグ - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3%E3%83%BC%E3%83%BB%E3%82%B6%E3%83%BB%E3%83%95%E3%83%A9%E3%83%83%E3%82%B0)を参照してください。

以下の各見出しは「問題名 (ポイント数, ジャンル)」で書いています。
# 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戦勝って無事にフラグゲット:grinning:
（スマートな解き方ではないですね笑）

# Classical Injection (100, Web)
## 問題文
```
http://172.20.1.60/100_1/
```
## 解説
うろ覚えだが、ブラウザで上記URLにアクセスすると、入力フォームがあって、
単純なSQLインジェクション `' or 1=1 --`を入れると、フラグゲット:grinning:
（かなり記憶があいまいです。。。）
# May the extensions be with you. (100, Web)
## 問題文
```
http://172.20.1.60/100_2/
```
## 解説
ブラウザで上記URLにアクセスすると、ページが表示された。
（何か文が書いてあったけど覚えていない。。。）
問題名を手掛かりに、講義で習ったChrome ExtensionのEditThisCookieを使うと、
`false`という値が入ったCookieが存在することが分かった。
この値を`true`に書き換えて、ページ再読み込みすると、フラグゲット:grinning:
（これも記憶があいまい。。。）

# あけてみよう (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`を画像ビュワーで開くと、以下のフラグゲット:grinning:
`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コマンドを実行すると、フラグゲット:grinning:

```
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}）
```
## 解説
上記ファイルの中身は下記

```:bin200_1_objdump.txt
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レジスタに最後に入る値を地道に計算すると、フラグゲット:grinning:
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`という明らかに怪しい関数がある。

```:dump.txt
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文字に変換するとフラグゲット:grinning:

```
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など）や問題へのアプローチ方法を学べたので非常に有意義だった。