Same-Siteからメインサイトへ
前回のGrafanaの攻撃シナリオに関する投稿では、攻撃者が後続の攻撃を実行するためには、まずSame-Siteのウェブサイトの制御権を取得する必要があると述べました。この記事では、別の視点から考えてみましょう。「Same-Siteのウェブサイトを制御している場合、どのような種類の攻撃を実行できますか?」例えば、CSRFは可能な攻撃方法の1つです。
これはバグバウンティの世界でもよく起こることで、ウェブサイトはバウンティハンターに報奨金を提供し、脆弱性を積極的に発見して報告することを奨励しています。これにより、ウェブサイトは脆弱性が悪意を持って悪用される前にパッチを適用でき、双方に利益をもたらします。これらのバグバウンティプログラムには通常、脆弱性の深刻度レベルごとに金銭的価値を指定する説明ページがあります。
さらに、コアウェブサイトと非コアウェブサイトもあります。例えば、api.huli.tw
APIサーバーで見つかった脆弱性は、2023.campaign.huli.tw
の1回限りのイベントページで見つかった脆弱性よりも価値があります。なぜなら、前者はより大きな影響を与える可能性があるからです。
したがって、バウンティハンターが2023.campaign.huli.tw
で脆弱性を発見した場合、より多くの報酬を得るために、この脆弱性の範囲を拡大する方法、例えばapi.huli.tw
に影響を与える方法があるかどうかをさらに調査しようとするかもしれません。
Same-SiteのウェブサイトでXSSを見つける以外に、サブドメインを制御する別の方法があります。
サブドメイン乗っ取り
名前が示すように、この脆弱性により、攻撃者はサブドメイン全体を乗っ取り、その制御権を得ることができます。
難しそうですよね?サブドメインを乗っ取るには、DNSを制御したり、会社の内部システムに侵入したりする必要があるのでしょうか?実際には、必ずしもそうではありません。さまざまなクラウドサービスの時代には、試してみるべきより簡単な方法があります。
Amazon S3はクラウドストレージサービスで、ファイルをアップロードし、権限を設定して他の人と共有できます。多くの人がAmazon S3を使用して画像やウェブサイト全体をホストしています。なぜなら、ウェブサイトホスティング機能も提供しているからです。S3の各ストレージスペースはバケットと呼ばれ、名前が付いています。これはS3が提供するサブドメインにも対応しています。
例えば、私のバケット名がhulitest
の場合、サブドメインはhttps://hulitest.s3.us-east-1.amazonaws.com
になります。S3は便利で使いやすいため、静的ウェブサイトのホスティングに適しています。例えば、会社のアーキテクチャがフロントエンドとバックエンドを完全に分離し、サーバーサイドレンダリングを必要としない場合、純粋な静的ウェブサイトをS3でホストでき、フロントエンドインフラストラクチャを管理する必要がなくなります。
唯一の問題は、ドメインhttps://hulitest.s3.us-east-1.amazonaws.com
が見栄えが悪いことです。企業は通常、独自のドメイン名を持っており、S3はドメインをカスタマイズする機能を提供しており、これも非常に簡単です。
まず、バケット名を目的のドメイン(例:campaign.huli.tw
)に変更します。
次に、DNSにCNAMEレコードを追加し、campaign.huli.tw
をhulitest.s3.us-east-1.amazonaws.com
にポイントします。これにより、独自のドメインとしてhttps://campaign.huli.tw
を使用できます。
全体のプロセスは問題なく便利そうですが、このウェブページが不要になった場合はどうなるでしょうか?例えば、S3でホストされ、カスタムドメインxmas.huli.tw
を使用するクリスマスイベントページがあるとします。クリスマスとイベントが終了した後、ストレージスペースとトラフィックにもコストがかかるため、S3バケットは削除されます。
しかし、DNSの部分は別の部署が担当している可能性があり、特に削除するように通知されなければ、そのまま残っている可能性があります。
その結果、DNSレコードはまだ存在するが、それが指す宛先は削除されているという状況が発生します。
S3の場合、バケット名が他の誰にも取得されていなければ、その名前を要求できます。xmas.huli.tw
バケットは削除されたので、同じ名前xmas.huli.tw
で新しいバケットを作成できます。これにより、ドメインxmas.huli.tw
はS3バケットを指し、S3バケットには私のコンテンツが含まれているため、事実上xmas.huli.tw
のコンテンツを制御し、サブドメイン乗っ取りを達成します。
S3以外にも、同様の機能を提供し、この問題を抱えているサービスは他にもたくさんあります。詳細なリストはこちらを参照してください:Can I take over XYZ。Azureも、これに対する防御方法を具体的に説明するページを作成しています:ぶら下がり DNS エントリを防止し、サブドメイン乗っ取りを回避する。簡単に言えば、DNSレコードを削除するだけで問題ありません。
サブドメイン制御権取得後にできること
いくつかの例を見てみましょう!
最初の例は、Hacktusが2023年に公開した記事です:Subdomain Takeover leading to Full Account Takeover。ウェブサイトexample.com
のCookieがルートドメインexample.com
に直接書き込まれており、他のサブドメインと共有可能であることが言及されています。
Hacktusは、サブドメインの1つであるtest.example.com
がazurewebsites.net
を指しており、誰も登録していないことを発見しました。そこで、Hacktusはサービスを登録し、ドメインの乗っ取りに成功しました。乗っ取り後、ユーザーがtest.example.com
にアクセスするたびに、ブラウザはexample.com
に保存されているCookieをサーバーに送信し、HacktusがユーザーのCookieを取得できるようにしました。
2番目のケースは、Shockwaveというサイバーセキュリティ企業が公開した記事です:Subdomain Takeover: How a Misconfigured DNS Record Could Lead to a Huge Supply Chain Attack。記事で言及されているケースは、先ほど説明したS3バケットの問題と似ていますが、今回は乗っ取られたドメインはassets.npmjs.com
です。
NPMはNode Package Managerの略で、JavaScriptパッケージを管理するために使用されるサービスです。攻撃者がassets.npmjs.com
の制御権を取得すると、悪意のあるパッケージをアップロードし、開発者を騙して安全であると思わせることができます。開発者はこのドメインに精通しており、非常に信頼性が高いように見えるため、フィッシングが成功する確率も高くなります。
3番目のケースは、2022年末にSmaran Chand氏が発見した脆弱性に関するものです:Taking over the Medium subdomain using Medium。ブログプラットフォームMediumのサブドメインの1つであるplatform.medium.engineering
はMediumを指していますが、ブログとしては存在しません。
攻撃者は独自のMediumブログを作成し、platform.medium.engineering
へのリンクを要求できます。この場合、ウェブページのコンテンツを完全に制御することはできませんが、偽の求人広告を投稿するなど、信頼性の高いように見えるソーシャルエンジニアリング攻撃を行うことは依然として可能です。
これらの実際の例で言及されている適用方法以外にも、実際にはさらに多くの可能性があります。
誤ったセキュリティ前提の悪用
多くのバックエンドプログラムは、誤ったセキュリティ前提を立て、持つべきでないエンティティに過剰な権限を付与しています。
例えば、CORSにおける動的オリジンのケースを考えてみましょう。一部のサーバーは次のチェックを実装しています。
const domain = 'huli.tw'
if (origin === domain || origin.endsWith('.' + domain)) {
res.setHeader('Access-Control-Allow-Origin', origin)
}
オリジンがhuli.tw
であるか、.huli.tw
で終わる場合、それは通過します。大きな問題ではないように見えるかもしれませんが、このチェックのセキュリティは、「攻撃者がhuli.tw
のサブドメインを制御できない」という仮定に基づいています。
しかし、今では、サブドメインの制御権を得ることは想像以上に難しくない可能性があり、リスクは依然として存在することを誰もが理解していると思います。攻撃者がサブドメインを制御できる場合、この誤った仮定を利用してサブドメインから攻撃を開始できます。
したがって、この一見安全に見えるチェックは、実際には十分に安全ではありません。最も安全なチェックは次のようになります。
const allowOrigins = [
'huli.tw',
'blog.huli.tw'
]
if (allowOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin)
}
リストを準備し、リスト内のオリジンのみがチェックを通過できるようにします。新しいドメインごとに手動で追加する必要があるため、より面倒かもしれませんが、サブドメインを盲目的に信頼するのではなく、セキュリティも向上します。
クッキートッシング
サブドメインの制御権を得た後にできるもう1つのことは、クッキートッシングと呼ばれます。
APIサーバーがapi.huli.tw
にあり、認証Cookieがこのドメイン下に保存されているウェブサイトがあるとします。さらに、バックエンドはCSRF保護を実装しており、SameSite=Lax
を追加し、CSRFトークンをチェックして、リクエストボディのcsrf_token
がCookie内のものと一致することを確認します。
さて、s3.huli.tw
というサブドメインを制御しており、そこでXSS攻撃を実行できるとします。次に何をすべきでしょうか?
Cookieを書き込む際、より上位のドメインに書き込むことができます。例えば、a.b.huli.tw
は次の場所にCookieを書き込むことができます。
- a.b.huli.tw
- b.huli.tw
- huli.tw
したがって、s3.huli.tw
にいるとき、huli.tw
にCookieを書き込むことができ、csrf_token
という名前のCookieを書き込むことができます。
api.huli.tw
とhuli.tw
の両方に同じ名前のCookieがあるシナリオでは、ブラウザはどうするでしょうか?両方のCookieを一緒に送信し、Cookieのpath
属性に基づいて、より具体的なものが最初に送信されます。
例えば、api.huli.tw
のCookieにpath
が設定されておらず、huli.tw
のCookieにpath=/users
が設定されている場合、ブラウザがhttps://api.huli.tw/users
にリクエストを送信すると、送信されるCookieはcsrf_token={value_of_huli_tw}&csrf_token={value_of_api_huli_tw}
になります。
通常、バックエンドでCookieの値を取得する際、デフォルトでは最初のものだけが取得されます。したがって、s3.huli.tw
で書き込んだCookieを取得します。
この動作により、攻撃者は他のSame-SiteドメインのCookieを上書きできます。まるでサブドメインから別のドメインにCookieを「投げている」かのようです。これはクッキートッシングとして知られています。
csrf_token
Cookieを上書きすることで、本質的にその値を知り、CSRF攻撃を実行できます。したがって、この状況では、Same-Site Cookieの設定とCSRFトークンのチェックがあっても、攻撃される運命から逃れることはできません。
解決策は、CSRFトークンのCookie名をcsrf_token
から__Host-csrf_token
に変更することです。このプレフィックスを付けると、Cookieを設定する際にpath
属性とdomain
属性を持つことができなくなります。したがって、他のサブドメインはそれを書き込んだり上書きしたりできません。その他の例については、MDNページを参照してください。
具体的な例やその他の応用については、2019年のHITCON CMTでの@filedescriptor氏の講演「The cookie monster in your browsers」またはスライドを参照してください。
まとめ
この記事は、前回の記事で言及したSame-Siteの問題を継続しています。システムを設計する際には、最小権限の原則を遵守し、不必要なセキュリティ上の仮定を避けるべきです。すべてのSame-Siteドメインを信頼するのではなく、より安全なアプローチは、ドメインの固定リストを信頼し、信頼できるすべてのドメインがリストされていることを確認することです。
さらに、この記事から、Same-Siteのウェブサイトは本質的に多くの権限を持っていることがわかります(例えば、Same-Site Cookieを無視するなど)。したがって、多くの企業は実際には、信頼性の低いファイル(例えば、ユーザーがアップロードしたファイル)や重要度の低いウェブサイトをまったく新しいドメインに配置しています。
例えば、メインサイトはwww.huli.tw
にあり、キャンペーンウェブページはcampaign.huli.app
という名前であるとします。こうすれば、キャンペーンウェブページが侵害されたとしても、損害を最小限に抑えることができ、メインサイトには影響しません。