スマートフォン解析 top

TOP > タイガーチームセキュリティレポート > DEF CON CTF Qualsにチャレンジ!―その3― 3dub 5 Writeup

タイガーチームセキュリティレポート

DEF CON CTF Qualsにチャレンジ!―その3― 3dub 5 Writeup

3dubの問題の続きです!
今回は、3dub 5 worsemedicineの解き方をご紹介します!


DEF CON CTF 2013 Quals 3dub 5 Writeup

問題文はこちら http://worsemedicine.shallweplayaga.me/
上記のURLにブラウザでアクセスすると、ログイン画面が表示されます。
とりあえずはadminユーザでログインを試みます。
ログイン失敗…予想通りw ログイン失敗時に表示されたエラー画面にはBACKTRACEが表示されています。
ソースコードを見ると「username」に「admin」を指定すると例外が発生する仕様になっていることがわかります。
「admin」ユーザでの正面突破は難しそうですので、今度は「foobar」さんでログインを試みます。
画面には素敵なお兄さんの画像とユーザ名が表示されました。ログイン成功か!? 「admin」でのログイン以外は、認証処理なんてしていない(「log in」ボタンを押せばユーザ/パスワードなしでもナイスガイの画像を拝めるw)ようですが、とりあえず、ログイン処理(リクエストとレスポンスの流れ)を詳しく見てみることにします。

まずは、ログイン画面で「log in」ボタンを押した際のリクエストです。
「username」と「password」の他に「_utf8」や「verification」などのパラメータが送信されています。
次に、レスポンスです。
「iv」「ciphertext」「verification」などの値がSet-Cookieされています。ここでSet-Cookieされる「verification」の値はリクエストで送信した「verification」の値と同じになるようです。
このあとのリダイレクト先となる http://worsemedicine.shallweplayaga.me/key には、先ほどSet-CookieされたCookieが送信されて、サーバはそのCookieの値をもとにユーザ名を表示しているようです。 どうやら http://worsemedicine.shallweplayaga.me/key に送信するCookieを上手く改ざんできれば「admin」ユーザでログイン成功となりそうですね(^^)
とは言え、名前からしてCookieのciphertextの値は暗号化されていてどのように改ざんすれば良いのか一目ではわかりません…
う~みゅ・・・・・・・・・(○ ̄ ~  ̄○;)
何度か実験を繰り返しているとある事に気がつきます。
ciphertexturl decodeした値のバイト数はログイン画面で「log in」ボタンを押した際に送信されるPostリクエストのbodyのバイト数とかならず一致しています。
このことからciphertextはbodyをstream暗号で暗号化したものと想像できます。
つまり
body xor k = ciphertext ※k…key stream です。
「iv」の値はわかっているので暗号化鍵の値がわかれば自力で「k」すなわち「key stream」を生成できそうですが、エラー画面などをいくら探してみても暗号化鍵らしきものは見つかりません。そこで、暗号化鍵を探すことはあきらめてstream暗号の性質(m xor k xor k = m)を利用することを考えます。
ログイン画面で「log in」ボタンを押した際のPostリクエストを書き換えてbodyを「username=」だけにして送信します。
レスポンスのciphertextの値をurl decodeして見ると、値のバイト数は9バイトでした。つまり"username="と同一です。
よって、"username="自体を暗号化したものではないかと想像できます。
という事は、http://worsemedicine.shallweplayaga.me/key に送信されるciphertextの値に「admin」を追加したリクエストに対するレスポンスの「You're xxxxx」のxxxxx(ユーザ名)に相当する部分のデータは、「admin」を暗号化したデータ(admin xor k)であるはずです。
さっそく試してみます。http://worsemedicine.shallweplayaga.me/key のレスポンスデータをhexで確認するとユーザ名に相当する部分のバイト列が0x61, 0xb1, 0x27, 0x79, 0x58になっています。これが暗号化されたadmin(admin xor k)です。
これをurl encodeして先ほどのリクエストで追加した「admin」の代わりに格納して送信すれば 、ciphertextの値は「username=admin」を暗号化したものになるはずです(admin xor k xor k = admin)。

リクエスト(ciphertextの値に"admin"を追加) レスポンスデータ(hex) 実際に先ほどのリクエストの「admin」を%61%B1%27%79%58に書き換えて送信すると、レスポンスになにやら答えらしき文字が!
「computers downtime and computers up in harlem」

これが正解!

この問題はciphertextstream暗号が利用されているということとその性質を利用すれば暗号化鍵そのものを手に入れる必要はないということに気がつくことがポイントですね。
とまとめましたが、この問題を解いたT氏も「ここだ!」ってポイントにたどり着くのに実際には、何時間も暗号化鍵を探しまわったり実験を繰り返したようです。まぁ、それがCTFの醍醐味なんでしょうけど(笑)


これまで、全3回にわたってCTFのWriteupをご覧いただきました。他にもいくつかの問題が解けていますので、公開できるようであればコソッとアップしておきます(笑)


タイガーチームメンバー(広報w) 白谷 宗大