SECUINSIDE CTF 2012 参加記
SECUINSIDE CTF 2012に参加しました。
今回は、友人が泊まりで遊びにきてたので、友人が寝てる間とかにちまちま一人で参戦。w
解いた問題数でのランキング
スコアによるランキング
得点順位 | 解答数順位 | チーム | 解いた問題数 | スコア |
---|---|---|---|---|
3位 | 6位 | sutegoma2 | 10問 | 5040 |
ランク外 | 38位 | 自分とこ | 4問 | 950 |
ランク外 | 75位 | Tachikoma | 1問 | ? |
今回のCTFでは、開催中は問題の得点が公表されない形式でした。
問題の得点は、あらかじめ決められた得点が必ず獲得できるというわけではなく、
多くのチームが解答した問題については、得点が低く計算されるという、少し面白い方式でした。
みんなが解ける問題なら得点は低くていいよね、的な。
問題ファイルはこちらで公開されているようです。
それでは、Writeupの後、感想と考察。
Writeup
zombie(500)
問題文:
http://61.42.25.27/c/a8241dc330c0353ccd8db73244c8bd30/
SQLインジェクションの問題。
PHPのソースが見れるようになっている。
次のように、スペースや一部キーワードが制限されている。
if(eregi("load|union| |\t|/|char|ascii|hex|<|>|infor|\.|challenge2|challenge3|challenge4",$dd)) exit("Access Denied");
$q=mysql_query("select * from challenge1 order by $dd desc");
スペースやタブが使えないので、改行で区切ることにした。
charが使えないので、substringとordでごそごそ。
しかし、ORDER BY の後に WHERE句が置けない。
結局、スマートな解答は結局思いつかず、次のような感じのSQLでBFした。
(CASE ORD(SUBSTRING(password,0,1)) WHEN 50 THEN password ELSE score END)
BFに使ったVB.NETのコード
ASCII文字約100種として、FLAGの文字数が11文字。
1100回なら、だいじょぶだよね・・・?
みんながスコア更新しまくるので、適当なスコアを投げながらBFしたのだけど、
システムの問題か、ひたすらサーバが落ちまくってた。
BFしてもあんまり意味ないよって発言がIRCで見えてたけど、
BFなしの、ちゃんとした解き方が気になるなぁ。
FLAG: 0ldzombieee
それは私です。w
21:16 (aozx) who brute-forcing target score.php
21:16 (aozx) 61.197.xxx.xxx <-
beast(500)
問題文:
http://61.42.25.27/c/f79de6418b66ab6d2717cf2b2cfb37ea/
SQLインジェクションの問題。
PHPのソースが見れるようになっている。
これまたキーワードや文字数が、次のように制限されている。
if(strlen($_POST[phone])>=20) exit("Access Denied");
if(eregi("admin",$_POST[id])) exit("Access Denied");
if(eregi("load|admin|0x|#|hex|char|ascii|ord|from|select|union|infor|challenge",$_POST[phone])) exit("Access Denied");
@mysql_query("insert into challenge4 values('$_POST[id]',$_POST[phone],'guest')");
guest を admin にできれば、OK。
最初、シングルクオーテーションを入れるとうまくいかなくて、
なんでだろーと思ってたけど、多分、conn.phpでmysql_real_escape_stringされてるんだと予想。
だとすると、idでインジェクションすることは無理。
となると、制限の多いphoneでインジェクションするしかない。
3000+3とか、length(id)とかはちゃんと動く。
"1111,id) -- - " も動く。lvがidになった。
adminは入れれないので、idをnimdaにして、"1,reverse(id))-- -"したら通った。
FLAG: 57483f303a55fed3b40a11519abf38f4
yhsj(500)
問題文:
http://61.42.25.29/ca91991084ceda1d22c5f2c8efc52c9e/
SQLインジェクションの問題。
PHPのソースが見れるようになっている。
(あれー、msg.phpsがまだ公開されてない....)
テーブルは、次のような構成。
talk (
id string
pw string
ip string
)talk_msg (
ck
mfrom => $_SESSION[id]: talk.id
mto: talk.id
msg
tm
)
この問題では、tmというUNIX時間を使ってインジェクションしていった。
これまたcharとかは制限されてるけど、ordは使えるので、ord+substring。
talk.id="admin"のpwを知りたいので、次のSQLでBF(またw)。
60*(SELECT CASE ORD(SUBSTRING((SELECT pw FROM talk WHERE LENGTH(id)=5 AND ORD(SUBSTRING(id,1,1))=97 AND ORD(SUBSTRING(id,2,1))=100 AND ORD(SUBSTRING(id,3,1))=109 AND ORD(SUBSTRING(id,4,1))=105 AND ORD(SUBSTRING(id,5,1))=110 LIMIT 0,1),1,1)) WHEN 50 THEN 1 ELSE 2 END)
これで、投稿日時が1分ずれるようになるので、pwを1文字ずつ求めていく。
pwは、"zombie_{パスワード}"のMD5ハッシュなので、
32文字×36文字種=1152回。まぁ、だいじょぶだよね。
BFに使ったVB.NETのコード:
求めたハッシュは、72b302bf297a228a75730123efef7c41。
Backtrackに入ってる辞書でBF。あれ、解けない。
適当に総当たりで攻撃。あれ、解けない。
なんでやー!と思いながら、online hash crackに放り込むと、
"banana"
と表示された。は?w
zombie_{パスワード}
になるはずだから、これじゃ解けない。ちょっと待て。w
とかやってたら、IRCで運営側がこの問題のfixを始めた。
fix後は、adminのパスワードが正しいものに変更され、updateを制限ワードに入れてた。
オイ。変更したの誰だよ。w
追記:
このwriteupを見るに、updateじゃなくて単純にinsertしただけっていう可能性も?
凄く面白い解き方だなぁ。
気を取り直して、もう一度。
今度は、0f38a34e843e84f44ac699ec800cfd52が得られた。
辞書で攻撃してみると、"zombie_rainbow"がヒット。
後は、adminでログインして、フラッグをゲット。
FLAG: f290e59906916ad37852c398cac83433
iu
問題文:
Hints:
1. hex
2. [-3:]
3. inverse.Challenge text:
-
-
-
- -
-
-
the message was decoded:
11111011 11101111 10001110 10000110 00011000 01100001
10000110 00011000 01011000 10100010 11100011 01011010
10111010 00001000 01101101 11001000 00010000 00010010
00010011 10101110 00111110 11111011 10111010 01011110
01100100
-
-
-
- -
-
-
追加ヒント:
http://61.42.25.27/slamdunkhero/desc.txt
One more hint:
\\"inverse\\"
more hints:
1. you have 25 bytes, you work on 22 bytes and 3 bytes separately.
2. flag format = e(22bytes) + e(3bytes)
3. which means d(e(22bytes)) + d(e(3bytes)) must be the same with the binary words. (have you checked this before? ;)
4. it\\\'s base64, there is a possibility that d(x) == d(y)
5. we know you\\\'re confused!
今回のサービス問題かな?
22バイトと3バイトに分けて、base64でエンコードすると、答えが出る。
22bytes: +++OhhhhhhhYouNaughtyBASE64++w==
3bytes: ul5k
ただし、これでは通らない。
追加ヒントにあるように、必ずしも d(x) == d(y) になるとは限らない。
確かに、22バイト×8ビット=176ビットとなり、
176 mod 6 = 2 なので、2ビット余る。
linuxのbase64コマンドだと、勝手に0をパディングして処理してしまう。
今回だと、余った2ビットは11なので、110000 として処理されてしまう。
出てきたキーワードからも、wじゃなくて+だろうという予想はつく。
実際、+は111110なので、それっぽい。
よって、答えは"+++OhhhhhhhYouNaughtyBASE64+++==ul5k"となる。
ちなみに、ずっと "+++OhhhhhhhYouNaughtyBASE64+++ul5k" で試してて、
何がダメなんだろう、inverseってあるから3バイトをinverseすればいいのかなとか
めっちゃ試行錯誤してた↓↓↓。ダメじゃーん。
10111010 01011110 01100100 ul5k
01000101 10100001 10011011 RaGb
01100100 01011110 10111010 ZF16
00100110 01111010 01011101 Jnpd
11011001 10000101 10100010 2YWi
10100010 10000101 11011001 ooXZ
FLAG: +++OhhhhhhhYouNaughtyBASE64+++==ul5k
感想
WEB系について
phpのソースが提示されている分、難易度は易しめなのかなー?とも感じました。
とはいえ、提示されていても結構大変に感じた....
その他
終了時間をちゃんと把握していなかったのと、途中で意識が飛んでしまったことで、
最後に解禁された5問はほとんど手つかず。無念。
Exploit系は全く手が出なかった。。
Web上からExploitっていうのが、初めてすぎて。勉強不足。
もっと、舐めるようにアセンブラを読めるようになりたい。
スタックの積み下ろしとか追うのが、ホントできない。深刻な問題。
Google Document
今回、一人参加だったけども Google Document の SpreadSheet を使ってみた。
既に使ってるよ!というチームは多そうだけど。
- 問題ごとにシートを作成(SpreadSheet自体じゃないよ)
- 問題に関連する情報をメモ
- 問題で試した内容を記録
こうすることで、次のような利点があると思う。
- 関連情報の集約化により、調べる手間が減る
- 他の人がどういうアプローチをしているのかが分かるので、発想の枝分かれができる
- 他の人が既に試した失敗手法を繰り返さない
- (多分)勉強になる
複数人でやるときには、もってこいだなと思った。
情報共有が加速するのと、問題ごとの情報整理がシートごとに勝手に行われるので、非常に良い。
Writeupも、シート見ながら書き起こせる。
変更がリアルタイムで見れるので、オフライン・オンライン問わず、イイ感じ。
さいごに
参加者の方々、お疲れ様でした!
素敵なCTFをありがとう! > SECUINSIDE の中の人たち
sutegoma2、ベスト3 おめでとう!!!
みんなのWriteup
- zombie : http://tasteless.se/2012/06/secuinside-2012-prequals-ctf-web-writeup-batman-zombie/
- zombie : http://devtrixlabs.com/blog/2012/06/secuinside-ctf-write-up-zomebie/
- batman : http://tasteless.se/2012/06/secuinside-2012-prequals-ctf-web-writeup-batman-zombie/
- cliph : http://tasteless.se/2012/06/secuinside-2012-prequals-ctf-web-writeup-cliph-sqlgeek/
- yhsj : http://tasteless.se/2012/06/secuinside-2012-prequals-ctf-web-writeup-beast-yhsj/
- yhsj : Write-up – Secuinside 2012 – yhsj | DDXhunter, Hack 'n Web
- beast : http://tasteless.se/2012/06/secuinside-2012-prequals-ctf-web-writeup-beast-yhsj/
- keilbasa : [Python] t_s = "9"*33 #Trigger off by one overflow at # for ( i = 0; i < strlen(ptr_q - Pastebin.com
- keilbasa : http://pastie.org/private/ed6cplywryme0i5psmvpw
- classico : http://pastie.org/private/0oqlk272ywtnztzm27x2eq
- sqlgeek : Secuinside CTF writeup SQLgeek | Reiners' Weblog
- sqlgeek : [http://tasteless.se/2012/06/secuinside-2012-prequals-ctf-web-writeup-cliph-sqlgeek/