DNS リバインディングのしくみ、再び 〜Kaigi on Rails 延長戦!

Kaigi on Rails の開催から一週間あまりが経ちました。

初心者から歴戦のベテラン戦士まで楽しめる色彩豊かな発表内容で皆が終始楽しめるイベントとなっており、登壇者としても参加者としても心から楽しませていただきました。また、私が発表した「ActionDispatch::HostAuthorization と学ぶ DNS のしくみ」についても、多くの方にご覧いただけたようでそのフィードバックの多さに驚きました。改めまして、貴重な機会をくださった運営のみなさまには感謝をお伝えしたいです。

…ところで、ここまでの期間でご覧いただいた方々の感想を見ているうち、どうも私が発表で行った説明が要点をおさえきれていなかったために、 DNS リバインディングの攻撃について誤解を招いてしまっているケースがあることに気づきました。たとえば、「攻撃者は DNS の値を、罠サーバの IP アドレスに再設定(リバインディング)する」等というように。(このような誤解が生まれていたことについては、浸透いうな先生にご指摘いただいて気づくことができました。ありがとうございます!)

そこで、発表(の資料)を見てくださった方がたに理解をより深めていただくためと、私自身の知識を深めるため、Kaigi on Rails のときとは違った攻撃ケースを用い改めて DNS リバインディングに関する説明を書いてみようと思い立ちました。

この記事の前提

ふだんは専らアプリケーションコードを書いており、アプリケーションよりも外―こと DNS についてはまだあまり詳しく知らないなという方々に読んでいただくことを想定しています。

また、タイトルどおり Kaigi on Rails の延長戦(線)にあたるものですので、Kaigi on Rails での発表もしくは発表資料1をご覧になった方がお読みになることを前提としています(が、ご覧いただいていなくても説明を理解していただけるように書いたつもりです)。

おさらい: DNS リバインディング攻撃の概要

DNS リバインディングとは、あるブラウザが一度名前解決を行わせたドメイン名の IP アドレスだけを変更することで、ブラウザ経由で特定のコンピュータに攻撃を加える手法のことをいいます。

IP アドレス(もしくはプライベートネットワーク内のホスト名)をリバインディングした後の攻撃の幅はさまざまですが、種類としては大きく以下のふたつに分けることができます。2

  1. ユーザの意図しないリクエストを発行させ、ファイアウォールでアクセスが制御されているイントラネット上のホストに対して攻撃を行う
  2. ユーザの意図しないリクエストを発行させ、インターネット上のホストに対して攻撃を行う

DNS リバインディングのポイントは、攻撃対象のサーバにアクセスしているのはあくまでも「なんの悪意もないユーザが操作しているブラウザ」であるということです。言い換えるなら、攻撃者はそのユーザのブラウザを踏み台にして他者への攻撃を仕掛ける、ということになります。

Kaigi on Rails での発表とこの記事の位置づけ

私の Kaigi on Rails での解説は、上記 2 のケースを具体例として挙げていました。攻撃対象者(Y さん)に攻撃用 JavaScript コードをダウンロードさせ、そのコードから意図しないリクエストを発行させて Piyostagram というインターネット上のサービスに対して「悪いこと」をさせる、というシナリオでした。

しかし、「あるユーザを踏み台にすることにより攻撃者が得られるメリット」を明確にしていなかったために、攻撃の正しいカラクリを理解していただきづらい説明となっていたことに後から気づきました。

そこで、「あるユーザを踏み台にすることにより攻撃者が得られるメリット」が一般的により感じやすいと思われる 1 のパターンを説明することで、DNS リバインディングの理解をより深めていただけるのではないかと思いました。この記事はそれを試みるものです。

DNS リバインディングでファイアウォールを突破する

先程も書いたとおり、ここでは DNS リバインディングのバリエーションとして、1 のケースを解説します。Kaigi on Rails での解説1も思い出しつつ、ご自身で登場人物の絵を描いてみながら話を追っていただけると、より多くのことに気づいていただけるかもしれません 😄


たとえば、Y さんが勤務する会社のネットワークは、外部からの不正なアクセスを阻止するために、インターネットとの境界にファイアウォールを設置していたとしましょう。ファイアウォールがありますので、ネットワーク管理者が許可するよう設定した通信以外は拒否されます。当然、攻撃者は通常の方法ではファイアウォール内部のコンピュータにはアクセスできません。

ここで、Y さんの会社のコンピュータ(ファイアウォールで守られた内側のネットワークにある。ここではコンピュータ A とします)を攻撃対象とした攻撃者が、Y さんに対して DNS リバインディングを仕掛けてきました。さて、攻撃者はどうするのでしょうか?

まず攻撃者は、何らかの方法で Y さんに kougeki.com へのリクエストを発行させます。今回、攻撃者は kougeki.com へのリンクを仕込んだメールを Y さんに送りつけ、Y さんはそれをクリックしてしまいました。

このとき、 kougeki.com が指す先は、攻撃者が用意した罠サイトです。罠サイトは、アクセスしてきた Y さんのブラウザに、攻撃用 JavaScript コードをダウンロードさせます。このコードには、「n 秒後になったら、 kougeki.com というコンピュータへアクセスして情報を取得し、 victim.net(攻撃者がコントロールしているサーバ)へ送信する」と書いてあります。

その後攻撃者は n 秒後の攻撃コード実行開始までに kougeki.com. ゾーンの情報を編集し、 kougeki.com というドメイン名に紐づく値を、自分の罠サーバの IP アドレスから攻撃対象(すなわち Y さんの会社のコンピュータ A)を指す値に変えます3

n 秒経つと Y さんがダウンロードした JavaScript コードは実装通り kougeki.com というコンピュータへとリクエストを発行します。このリクエストも kougeki.com というドメイン名へのリクエストとなるものの、今度は Y さんの会社のコンピュータ A を指す値を使って名前解決をされますので、Y さんのブラウザは結果として Y さんの会社のコンピュータ A へ HTTP リクエストを行うことになります。

繰り返しになりますが、このリクエストは Y さんが意図的に発行しているものではなく、罠サイトからダウンロードさせられた JavaScript コードが発行したものです。しかし、あくまでもアクセスしているのは Y さんになりますので、一見正規のアクセスと見分けがつきません。会社のネットワークに属している Y さんが会社のネットワークにあるコンピュータ A にアクセスすることは通常の業務における用途として考慮されているため、なんの問題もなく実行できてしまいました。

こうして、情報を取得したのち、JavaScript コードはそれを victim.net へと情報を送信します。攻撃成功です。

ここで攻撃者が得られるメリットは、「攻撃者自身ではアクセスできないファイアウォール内のコンピュータに対して(Y さんを踏み台にすることで)攻撃実行が可能となる」こと。DNS リバインディングは、このようにアクセス制限を突破するためにも使われるのです。

対策は?

たとえば、フルリゾルバ側であれば「問い合わせをした権威サーバからの応答の内容が、予め指定したプライベートネットワークを表す IP アドレス(ここでは、自ネットワーク内のホストを指すネットワーク範囲など)であった場合は、それを不正な応答として拒否する」といった設定ができるようです。4

ファイアウォールを突破するケース以外にも対応するものとしては、ブラウザで「権威サーバからの応答に含まれている TTL を無視し、一定時間は同じ IP アドレスを使う」などの対策が取られています(ただし、完全な対策ではありません)。

またこれは AWS EC2 を使っている場合になりますが、EC2 インスタンスメタデータを DNS リバインディングで取得されないようにするための対策として、GuardDuty で DNS リバインディングを検知できるようになっているそうです。5

これらについても学びが盛りだくさんなので、また別のトピックとして記事を書ければと思っています。

おわりに

攻撃が成功するケースは限定的ではありますが、ファイアウォールを使っているからといって慢心せず、ファイアウォール内のコンピュータについても常に最新のセキュリティパッチが適用されているバージョンを使うなど、複合的な観点で対策を行うことが重要といえるでしょう。

DNS リバインディングは DNS のしくみが把握できていないと少しわかりづらいかもしれません。Kaigi on Rails での私の発表も併せて、DNS、そして DNS リバインディングのしくみを正しく理解するお手伝いができていればよいなと思っています。(もし、不明な点、誤った点などがありましたらぜひ @yucao24hours までフィードバックをいただけると助かります!)


  1. yucao24hours: ActionDispatch::HostAuthorization と学ぶ DNS のしくみ https://speakerdeck.com/yucao24hours/understanding-dns-with-actiondispatch-hostauthorization 

  2. Collin Jackson, Adam Barth, Andrew Bortz, Weidong Shao, and Dan Boneh: Protecting Browsers from DNS Rebinding Attacks, https://crypto.stanford.edu/dns/dns-rebinding.pdf,, (2007) 

  3. Kaigi on Rails ではここで「自分の罠サーバの IP アドレスから Piyostagram の IP アドレスに更新する」という話をしましたが、 IP アドレスを使うのではなく、「kougeki.com というのはあくまでもエイリアスで、本当のドメイン名は xxx (たとえば今回なら hr.corp.co.jp とかいかにもありそうなドメイン名)ですよ」という値で更新したりします。このように「とあるドメイン名のエイリアスであること」を DNS のゾーン情報のうえでは CNAME リソースレコードという形をとって表現し、この応答を受け取ったフルリゾルバは改めてまたこのドメイン名の名前解決をしに行く…といったしくみになっているのですが、このあたりの詳しい説明はここでは割愛します。もっと知りたい人は「DNS がよくわかる教科書」を読んでみよう! 

  4. フルリゾルバの機能を提供する Unbound というソフトウェアの例。 https://github.com/NLnetLabs/unbound/blob/b6d04f500bb0f021938d87871f995bc85ca619bf/doc/example.conf.in#L437-L452 

  5. https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-ec2.html#unauthorizedaccess-ec2-metadatadnsrebind および https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html あたりを参考にしてください。