IPv6でのWebトラフィックハイジャック手法

2021/10/3-1

IPv6には、昔からよく知られている偽RAの問題があります。

この記事では、ひとつのネットワークインターフェースに複数のIPv6アドレスを追加可能であったり、自分のネットワークインターフェースに設定されていないプレフィックスがon-linkになる場合もあるというIPv6の特徴や、偽RAによって何が起きる可能性があるのかを解説するために、同一リンク上にいるユーザのWebトラフィックがハイジャック可能であるという視点で偽RA問題を解説します。

Router Advertisementの問題

IPv6にはRouter Advertisement(RA)というものがあります。 RAは、IPv6のNeighbor Discoveryで使われる仕組みです。 RAは、ルータが自分の存在を知らせるとともに、MTUなどのリンクに関連する情報や、プレフィックス情報などインターネットに関連する情報を広告するための仕組みです。 IPv6アドレスの自動設定でも使われるので、そのイメージが強いかもしれません。

RAには、rogue RA、いわゆる偽RA(不正RA)の問題があります。 偽RAの問題は、昔から良く知られており、RFCとしては、RFC 3756、RFC 6104、RFC 6105、RFC 7113などが関連するRFCと言えます。

  • RFC 3756 : IPv6 Neighbor Discovery (ND) Trust Models and Threats
  • RFC 6104 : Rogue IPv6 Router Advertisement Problem Statement
  • RFC 6015 : IPv6 Router Advertisement Guard
  • RFC 7113 : Implementation Advice for IPv6 Router Advertisement Guard (RA-Guard)

今回の内容は、主にRFC 3756の「4.1.1 Neighbor Solicitation/Advertisement Spoofing」と「4.2.5 Bogus On-Link Prefix」に書かれた内容を実際に行うとどういうことができてしまうのか、を解説します。

偽RAを利用して同一リンクのWebトラフィックをハイジャック

今回は、RFC 3756に書かれている内容を理解するために、偽RAを使って同一リンクにいる他の機器を使っているユーザを不正Webサイトへ誘導するという例を紹介します。 今回の例では、www.example.comを偽Webサイトへと誘導します。

example.comは、IANAによって予約されているドメイン名です。 RFC 2606やRFC 6761にも記載されている例示用として使われるためのドメイン名です。 example.comは、ドキュメンテーションなどで例示するために予約されていますが、www.example.comというWebサイトも実際に稼働しています。 今回の実験では、偽RAによる問題を紹介するためのURLとして例示用のexample.comを使います。

今回は、IPv6を使ってこのwww.example.comを見ようとするユーザを偽サイトへ誘導します。

この実験ではwww.example.comを例として紹介していますがIPv6でWebサイトを運営している任意のURLに対して同様の誘導が可能となる場合があります。 IPv4のみで運用されているWebサイトに対しては同じ方法で偽サイトに誘導することはできません。

この実験を行うためには偽Webサーバと攻撃対象となるユーザは同じリンクに接続している必要があります。 また、実験を行うリンクはIPv6でインターネットとの通信が可能な状態である必要もあります。

この実験のポイントは本物のWebサーバのIPv6アドレスです。 2021年9月の段階で、私が手元で確認した結果では、www.example.comのIPv6アドレスは「2606:2800:220:1:248:1893:25c8:1946」です。 実験では、このIPv6アドレスをユーザと同一リンクに接続している偽サーバに設定します。 この偽サーバは当然、この偽IPv6アドレスを使ってインターネットと通信はできません。

ユーザを偽サーバに誘導する方法として、偽サーバと攻撃対象であるユーザの両方が、同じリンクに接続しているとユーザに誤認させてしまいます。 ユーザの機器で本物のWebサーバと同じ2606:2800:220:1::/64というプレフィックスが同じリンク上に存在している、IPv6用語で「on-linkである」と認識するような経路がユーザ側機器に設定されてしまえば、ユーザは2606:2800:220:1::/64 が、自分が接続しているリンクであると勘違いして、ルータではなく接続されたリンク宛にパケットを送るようになってしまいます。

この「on-linkである」という判断がIPv6では非常に大きなポイントです。

IPv6では、複数のIPアドレスをひとつのネットワークインターフェースに設定できるので、on-linkという考え方がIPv4とは根本的に異なります。

で、どうやってユーザに2606:2800:220:1::/64がon-linkであると認識させるかですが、偽RAを送りつけることで非常に簡単にできてしまいます。

RAには、プレフィックス情報を格納したPrefix Information Optionというものが含まれますが(RFC 4861参照)、このPrefix Information Optionの中にLフラグがあります。 このLフラグが1である場合、そのPrefix Information Optionが表現しているプレフィックスはon-linkであると解釈されます。

通常の環境では、偽RAを受け取ったユーザは、何も疑わずにLフラグが1になっているプレフィックス情報をon-linkとして覚えてしまいます。

しかも、現在、利用している正しいプレフィックスのIPv6アドレスは維持されたまま偽RAに記載された内容に応じて偽プレフィックスのIPv6アドレスが自動設定されることもあります(victim側の機器でIPv6アドレスが設定されずに経路だけが追加される場合もあります)。

たとえば、ユーザが利用しているリンクで本来利用すべきプレフィックスが2001:db8::/64というもの であったった場合、攻撃前の状態ではユーザが利用するグローバルIPv6アドレスは2001:db8::/64というプレフィックスのIPv6アドレスだけです。

そこに対して、今回の2606:2800:220:1::/64というプレフィックスを広告する偽RAをIPv6アドレス自動設定が行われるようにした状態で渡すと、ユーザ側の機器では既存の2001:db8::/64というプレフィックスのIPv6アドレスに加えて新たに2606:2800:220:1::/64というプレフィックスのIPv6アドレスも追加されます。

IPv6では、ひとつのネットワークインターフェースに対して複数のIPv6アドレスを設定可能ですが、であるという点が、このような状況を可能にしています。 偽RAを掴んでしまって偽プレフィックスをon-linkであると認識してしまったユーザはwww.example.comの名前解決をしますが、このとき、本物のサーバのIPv6アドレスをDNSから取得します。

今回の実験とは違う手法ですが、偽Webサーバへユーザを誘導する手法としてはDNSによる名前解決のところで偽のIPアドレスをユーザに渡すというpharmingという方法が良く知られています。 今回紹介するのは、名前解決の部分は本来のものを使って、本来のIPv6アドレスへの通信を偽Webサーバへと誘導するというものです。 DNSによって得られたIPv6アドレスの値は本物ですが、そのIPv6アドレスを宛先とするパケットはニセモノへ送られてしまうというのが今回の例です。

今回の例では、本物の権威DNSサーバから得られた本物のIPv6アドレスは偽RAによっていまはユーザのリンクでも運用されてしまっています。 2606:2800:220:1::/64は、本物のwww.example.comで運用されていますが、ユーザと偽サーバも2606:2800:220:1::/64は自分たちが直接繋がっているリンクであると認識している状態です。

ユーザは、本物の権威DNSサーバから得た本物のIPv6アドレスとの通信を行うために本来であればインターネットに接続しているルータへパケットを送らなければならないのですが、2606:2800:220:1::/64が自分が接続しているリンクであると勘違いさせられているので、近隣探索プロトコルでNS(Neighbor solicitation)を送ってしまいます。

偽サーバは、ユーザから送られてきたNSを受け取るとNA(Neighbor Advertisement)を返します。 このように、ユーザは本物のIPv6アドレスの値を使って偽Webサーバと繋がるL2でのアドレス解決をしてしまいます。

これにより、偽RAを受け取ったユーザの手元で表示されるwww.example.comは同一リンク上にある偽Webサーバのものになってしまいます。

デモ

今回、攻撃を受けるユーザ側のiphoneを使ってみました。 Windows、macOS、Linux他の環境でも再現可能です。

偽RAを流す前の状態では、正しく本物のwww.example.comが表示されているのがわかります。 その後、iphoneが接続されているWi-Fiに向けて偽RAをひとつ送ってからiphoneのWebブラウザをリロードします。

すると、上記動画(9:56あたり)のように、偽サーバが表示されます。

今回の実験で利用したソフトウェア等

今回の実験の再現方法ですが、偽RAの送信には、radvdというよく使われているオープンソースのソフトを利用しました。 radvdの設定としては、本物のWebサーバと同じIPv6プレフィックスのRAを広告する設定を行うだけです。

この実験では偽Webサーバとしてapacheを使いました。

今回のデモでは偽サーバはhttpsではなく、httpで行っています。 Chrome 94から利用可能になったHTTPS onlyモードでHTTPを表示するときに警告が出るようにするといきなり今回のような攻撃を受けた場合の緩和策になると思われます。

偽Webサーバには本物のWebサーバと同じIPv6アドレスを設定しています。

Happy Eyeballsについて

今回の実験では、本物と同じIPv6アドレスが同一リンクに存在しない場合や、Webサーバが偽サーバ用の機器で稼働していない場合、happy eyeballsの仕組みによってWebブラウザがIPv6での通信が失敗したとみなしてIPv4で通信を行うので、本物のwww.example.comが表示されます。

ここら辺の挙動は、IPv6とIPv4のデュアルスタック環境でのブラウザの挙動を理解するのに良い実験かも知れません。

実験を行う場合の注意点

この実験を行うこと自体はさほど難しくないので、このような感じで、比較的簡単に再現可能です。

ただし、この実験を行うのであれば他の人に迷惑をかけない環境を用意してから行って下さい。 今回のデモは動画作成のために他のユーザがいない環境で行っています。 偽RAによって本来設定すべきではないプレフィックスが設定されてしまうとIPv6での通信が不安定になったり失敗する場合があります。

他人がいるところで偽RAを流すのは絶対に行わないで下さい。

この問題への対策等

IPv6でのセキュリティという話題で、偽RAが解説されることも多いです。 一般的に、このような偽RAの問題を回避するためにはRAをフィルタリングするRA guardを導入することが推奨されています。

RA guardはRFC 6105で規定されています。 また、RAガードの実装方法はRFC 7113で紹介されています。

今回は不正RAに関して紹介しましたが不正なDHCPv6サーバを使うことで似たようなこともできます。不正なDHCPv6サーバに対する対策としてDHCPv6-ShieldがRFC 7610で解説されています。

対策として、ホスト側でRAを受け取って解釈しない設定を行うことも可能です。 たとえば、Linuxでは、accept_raの設定を0にしてあれば今回のような問題は起きません。 LinuxでWebサーバなどを運用する場合、基本的にRAを受け取らないようにaccept_ra=0の設定を行うことが多いです。

偽RA問題に対する根本的な対策はおそらく現時点ではありません。

Secure Neighbor Discovery(SEND)というものもRFC 3971として作られてはいますが、ほぼ使われていません。 Secure NeighborDiscoveryを取り巻く事情は、RFC 6980をご覧ください。

偽RA問題は、昔から課題とされていて根本的な解決策はいまのところなさそうです。

とはいえ、様々な対策が検討されています。 ご興味があるかたはぜひRAに関連する各種対策も調べてみて下さい(この記事では詳細は割愛します)。

以上がIPv6におけるセキュリティで度々話題になる偽RAの紹介でした。 RAの仕組みや、複数のIPv6アドレスが同時に利用可能であるというIPv6の特徴を理解するきっかけになれば幸いです。

最後に

この記事は、YouTubeに投稿した動画を再構成したものです。 IPv6の仕組みをYouTube動画として解説しているので、書籍「プロフェッショナルIPv6」とともにご覧いただければ幸いです。

最近のエントリ

過去記事

過去記事一覧

YouTubeチャンネルやってます!