SENTO NO OBOEGAKI

技術よりのメモやポエムを書いていきます。

MENU

CTF for ビギナーズ 2016 弘前 Write-up

CTF for ビギナーズ 2016 弘前が、私の所属する研究室から徒歩8秒の講義室で開催されたので、参加してきました。結果は1100ptsで4位(同点が結構いましたが)でした(1位は3人で1400ptsでした)。

 

f:id:sentoneibisu:20160912133454p:plain

最後のCTF演習のwrite-upだけ簡単に書きます(※最後のbin300は時間内に解けてません)。

Misc100: README

 問題文に書かれたctf4b{}形式のflagをコピペして終わり。

 

Forensics100: みてみよう

 与えられたpcapファイルをWiresharkで開いてみてみると、HTTPでflag.pngをダウンロードしているのを見つけたのでそのファイルを抽出。開いて見ても真っ白い画像だったので、バイナリエディタで眺めてみたらflagがあった。

 

Forensics200: エクスポートできるかな?

 与えられたpcapファイルを見ると、FTPでPNGデータをやりとりしていたので、エクスポートして開くとflagが書いてた。

 

Forensics200: ICMP?

 与えられたpcapファイルを見ると、ICMPのrequestとreplyがひたすら続いていたので眺めてると、何やら明らかにサイズがでかいICMPパケットがいくつかある。ということでデータ部分をよく見ると、なぜかHTTPリクエストとHTTPレスポンスが入っている。HTTPリクエストでflag.txtを要求しているので、レスポンスのボディを見てみるとbase64っぽい文字列がありデコードするとflagが得られた。

 

Binary100: HiddenFlag

strings bin100_1 | grep ctf4b

でflagが出た。

 

Binary200: 復習

 講義でやった内容(5つのkeyを探す問題)のkeyが3つバージョン。与えられたバイナリ内の3つの関数Stage1~Stage3の戻り値(eax)がそのままkeyになるので、命令を辿っていけば分かる。

 echo -en "23\n945\n-46\n" | ./bin200_1 

でflagが出た。

 

Binary200: ASCII

 とりあえず与えられたバイナリを実行してみるとInput flag>>と出てくる。objdumpで逆アセンブルしてみるとcheck_flagという関数があるので見てみると次のように命令が並んでいる。

mov    BYTE PTR [ebp-0x28],0x63
mov    BYTE PTR [ebp-0x27],0x74
mov    BYTE PTR [ebp-0x26],0x66
mov    BYTE PTR [ebp-0x25],0x34
mov    BYTE PTR [ebp-0x24],0x62
mov    BYTE PTR [ebp-0x23],0x7b
mov    BYTE PTR [ebp-0x22],0x63
mov    BYTE PTR [ebp-0x21],0x30
mov    BYTE PTR [ebp-0x20],0x6d
mov    BYTE PTR [ebp-0x1f],0x70
mov    BYTE PTR [ebp-0x1e],0x34
mov    BYTE PTR [ebp-0x1d],0x72
mov    BYTE PTR [ebp-0x1c],0x31
mov    BYTE PTR [ebp-0x1b],0x6e
mov    BYTE PTR [ebp-0x1a],0x67
mov    BYTE PTR [ebp-0x19],0x5f
mov    BYTE PTR [ebp-0x18],0x77
mov    BYTE PTR [ebp-0x17],0x31
mov    BYTE PTR [ebp-0x16],0x37
mov    BYTE PTR [ebp-0x15],0x68
mov    BYTE PTR [ebp-0x14],0x5f
mov    BYTE PTR [ebp-0x13],0x31
mov    BYTE PTR [ebp-0x12],0x6e
mov    BYTE PTR [ebp-0x11],0x70
mov    BYTE PTR [ebp-0x10],0x75
mov    BYTE PTR [ebp-0xf],0x37
mov    BYTE PTR [ebp-0xe],0x7d
mov    BYTE PTR [ebp-0xd],0x0

ASCIIっぽい値と文字列の終端っぽい0x0を格納しているのでこれをASCIIに直したらflagが出た。

 

Binary300: HiddenFlag -returns-

 とりあえず与えられたバイナリを実行してみると

HiddenFlag returns

You cannot get flag! Haha

と言われる。objdumpで逆アセンブルしてみるとmain関数は文字列をputsで出力するだけで終わっている。しかし、main以外にgenflagという関数が一つあり、関数名からここでflagを生成しているっぽい。

08048514 <genflag>:
 8048514:    55                       push   ebp
 8048515:    89 e5                    mov    ebp,esp
 8048517:    56                       push   esi
 8048518:    53                       push   ebx
 8048519:    83 ec 40                 sub    esp,0x40
 804851c:    65 a1 14 00 00 00        mov    eax,gs:0x14
 8048522:    89 45 f4                 mov    DWORD PTR [ebp-0xc],eax
 8048525:    31 c0                    xor    eax,eax
 8048527:    c6 45 df 04              mov    BYTE PTR [ebp-0x21],0x4
 804852b:    c6 45 e0 b2              mov    BYTE PTR [ebp-0x20],0xb2
 804852f:    c6 45 e1 0f              mov    BYTE PTR [ebp-0x1f],0xf
 8048533:    c6 45 e2 47              mov    BYTE PTR [ebp-0x1e],0x47
 8048537:    c6 45 e3 33              mov    BYTE PTR [ebp-0x1d],0x33
 804853b:    c6 45 e4 84              mov    BYTE PTR [ebp-0x1c],0x84
 804853f:    c6 45 e5 7f              mov    BYTE PTR [ebp-0x1b],0x7f
 8048543:    c6 45 e6 dd              mov    BYTE PTR [ebp-0x1a],0xdd
 8048547:    c6 45 e7 44              mov    BYTE PTR [ebp-0x19],0x44
 804854b:    c6 45 e8 bd              mov    BYTE PTR [ebp-0x18],0xbd
 804854f:    c6 45 e9 d6              mov    BYTE PTR [ebp-0x17],0xd6
 8048553:    c6 45 ea 98              mov    BYTE PTR [ebp-0x16],0x98
 8048557:    c6 45 eb ad              mov    BYTE PTR [ebp-0x15],0xad
 804855b:    c6 45 ec 98              mov    BYTE PTR [ebp-0x14],0x98
 804855f:    c6 45 ed d2              mov    BYTE PTR [ebp-0x13],0xd2
 8048563:    c6 45 ee 36              mov    BYTE PTR [ebp-0x12],0x36
 8048567:    c6 45 ef 14              mov    BYTE PTR [ebp-0x11],0x14
 804856b:    c6 45 f0 f1              mov    BYTE PTR [ebp-0x10],0xf1
 804856f:    c6 45 f1 26              mov    BYTE PTR [ebp-0xf],0x26
 8048573:    c6 45 f2 85              mov    BYTE PTR [ebp-0xe],0x85
 8048577:    c6 45 f3 1b              mov    BYTE PTR [ebp-0xd],0x1b
 804857b:    c7 04 24 00 00 00 00     mov    DWORD PTR [esp],0x0
 8048582:    e8 49 fe ff ff           call   80483d0 <srand@plt>
 8048587:    c7 04 24 16 00 00 00     mov    DWORD PTR [esp],0x16
 804858e:    e8 0d fe ff ff           call   80483a0 <malloc@plt>
 8048593:    89 45 d8                 mov    DWORD PTR [ebp-0x28],eax
 8048596:    c7 45 d4 00 00 00 00     mov    DWORD PTR [ebp-0x2c],0x0
 804859d:    eb 21                    jmp    80485c0 <genflag+0xac>
 804859f:    8b 55 d4                 mov    edx,DWORD PTR [ebp-0x2c]
 80485a2:    8b 45 d8                 mov    eax,DWORD PTR [ebp-0x28]
 80485a5:    8d 1c 02                 lea    ebx,[edx+eax*1]
 80485a8:    8d 55 df                 lea    edx,[ebp-0x21]
 80485ab:    8b 45 d4                 mov    eax,DWORD PTR [ebp-0x2c]
 80485ae:    01 d0                    add    eax,edx
 80485b0:    0f b6 30                 movzx  esi,BYTE PTR [eax]
 80485b3:    e8 38 fe ff ff           call   80483f0 <rand@plt>
 80485b8:    31 f0                    xor    eax,esi
 80485ba:    88 03                    mov    BYTE PTR [ebx],al
 80485bc:    83 45 d4 01              add    DWORD PTR [ebp-0x2c],0x1
 80485c0:    8b 45 d4                 mov    eax,DWORD PTR [ebp-0x2c]
 80485c3:    83 f8 14                 cmp    eax,0x14
 80485c6:    76 d7                    jbe    804859f <genflag+0x8b>
 80485c8:    8b 55 d4                 mov    edx,DWORD PTR [ebp-0x2c]
 80485cb:    8b 45 d8                 mov    eax,DWORD PTR [ebp-0x28]
 80485ce:    01 d0                    add    eax,edx
 80485d0:    c6 00 00                 mov    BYTE PTR [eax],0x0
 80485d3:    8b 45 d8                 mov    eax,DWORD PTR [ebp-0x28]
 80485d6:    8b 4d f4                 mov    ecx,DWORD PTR [ebp-0xc]
 80485d9:    65 33 0d 14 00 00 00     xor    ecx,DWORD PTR gs:0x14
 80485e0:    74 05                    je     80485e7 <genflag+0xd3>
 80485e2:    e8 a9 fd ff ff           call   8048390 <__stack_chk_fail@plt>
 80485e7:    83 c4 40                 add    esp,0x40
 80485ea:    5b                       pop    ebx
 80485eb:    5e                       pop    esi
 80485ec:    5d                       pop    ebp
 80485ed:    c3                       ret    
 80485ee:    66 90                    xchg   ax,ax

さらっと見てみると、先ほどの問題と同じようにmov BYTE PTR [ebp-0xYY],0xZZのような命令が並んでいる。しかし、ASCIIではない。そこでもう少し詳しく見ていくと、どうやらrand()で得られる乱数と1byteずつxorして、malloc()で確保した領域に入れているっぽい。ということで、gdbを使用しmainで実行を止めた後、eipをgenflagのアドレスに書き換えて、ループが終わったあたりまで実行し、malloc()で確保した領域を表示してみたらflagが出た。

$ gdb -q bin300
(gdb) b *main
(gdb) run
(gdb) set $eip=*genflag
(gdb) u *0x80485d6
(gdb) x/s $eax

感想

今回初めて「CTFの講義」を聴きましたが、知らなかったこともいろいろあり勉強になりました。webの講義も受けていたのにweb問を1問も解けなかったのが残念でした。久しぶりのCTFでしたが全体的に難しすぎない良い感じの問題が多かったので楽しめました。同じ大学の同期や後輩も参加していましたが、みんな楽しめたようで良かったです。