Browser Extension Pentesting Methodology
Last updated
Last updated
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
ブラウザ拡張機能はJavaScriptで書かれ、ブラウザによってバックグラウンドで読み込まれます。独自のDOMを持っていますが、他のサイトのDOMと相互作用することができます。これは、他のサイトの機密性、完全性、および可用性(CIA)を危険にさらす可能性があることを意味します。
拡張機能のレイアウトは視覚化されると最も良く見え、3つのコンポーネントで構成されています。それぞれのコンポーネントを詳しく見ていきましょう。
各コンテンツスクリプトは単一のウェブページのDOMに直接アクセスでき、潜在的に悪意のある入力にさらされます。ただし、コンテンツスクリプトは拡張機能のコアにメッセージを送信する能力以外の権限を持っていません。
拡張機能コアは、ほとんどの拡張機能の特権/アクセスを含んでいますが、拡張機能コアはXMLHttpRequestおよびコンテンツスクリプトを介してのみウェブコンテンツと相互作用できます。また、拡張機能コアはホストマシンに直接アクセスすることはできません。
拡張機能は、ユーザーの完全な権限でホストマシンにアクセスできるネイティブバイナリを許可します。ネイティブバイナリは、Flashや他のブラウザプラグインで使用される標準のNetscapeプラグインAPI(NPAPI)を介して拡張機能コアと相互作用します。
ユーザーの完全な権限を取得するには、攻撃者は拡張機能に悪意のある入力をコンテンツスクリプトから拡張機能のコアに、そして拡張機能のコアからネイティブバイナリに渡すように説得しなければなりません。
拡張機能の各コンポーネントは、強力な保護境界によって互いに分離されています。各コンポーネントは別々のオペレーティングシステムプロセスで実行されます。コンテンツスクリプトと拡張機能コアは、ほとんどのオペレーティングシステムサービスに利用できないサンドボックスプロセスで実行されます。
さらに、コンテンツスクリプトは別のJavaScriptヒープで実行されることによって、関連するウェブページから分離されています。コンテンツスクリプトとウェブページは同じ基盤となるDOMにアクセスできますが、二つはJavaScriptポインタを交換することは決してありません。これにより、JavaScript機能の漏洩を防ぎます。
manifest.json
Chrome拡張機能は、単に.crxファイル拡張子を持つZIPフォルダーです。拡張機能のコアは、フォルダーのルートにある**manifest.json
**ファイルで、レイアウト、権限、およびその他の設定オプションを指定します。
例:
content_scripts
コンテンツスクリプトは、ユーザーが一致するページに移動するたびに読み込まれ、この場合は**https://example.com/*
** 表現に一致し、*://*/*/business*
正規表現に一致しない任意のページです。これらはページ自身のスクリプトのように実行され、ページのDocument Object Model (DOM)に対して任意のアクセス権を持っています。
より多くのURLを含めたり除外したりするために、include_globs
と exclude_globs
を使用することも可能です。
これは、ストレージAPIを使用して拡張機能のストレージからmessage
値を取得する際に、ページに説明ボタンを追加する例のコンテンツスクリプトです。
このボタンがクリックされると、コンテンツスクリプトによって拡張ページにメッセージが送信されます。これは、runtime.sendMessage() APIを利用するためです。コンテンツスクリプトはAPIへの直接アクセスに制限があり、storage
が数少ない例外の一つです。これらの例外を超える機能については、メッセージが拡張ページに送信され、コンテンツスクリプトが通信できるようになります。
ブラウザによって、コンテンツスクリプトの機能は若干異なる場合があります。Chromiumベースのブラウザの場合、機能リストはChrome Developers documentationで入手可能で、Firefoxの場合はMDNが主な情報源となります。 また、コンテンツスクリプトはバックグラウンドスクリプトと通信する能力があり、これによりアクションを実行し、応答を返すことができる点も注目に値します。
Chromeでコンテンツスクリプトを表示およびデバッグするには、オプション > その他のツール > デベロッパーツールからChromeデベロッパーツールメニューにアクセスするか、Ctrl + Shift + Iを押します。
デベロッパーツールが表示されたら、ソースタブをクリックし、次にコンテンツスクリプトタブをクリックします。これにより、さまざまな拡張機能から実行中のコンテンツスクリプトを観察し、実行フローを追跡するためのブレークポイントを設定できます。
コンテンツスクリプトは必須ではないことに注意してください。動的にスクリプトを注入したり、プログラム的に注入することも可能です。これは実際により詳細な制御を提供します。
コンテンツスクリプトをプログラム的に注入するには、拡張機能がスクリプトを注入するページに対してホスト権限を持っている必要があります。これらの権限は、拡張機能のマニフェスト内で要求するか、activeTabを通じて一時的に取得することができます。
クリック時にJSファイルをインジェクトする:
クリック時に関数を注入する:
より多くのURLを含めたり除外したりするために、include_globs
と exclude_globs
を使用することも可能です。
run_at
run_at
フィールドは JavaScriptファイルがウェブページに注入されるタイミング を制御します。推奨されるデフォルト値は "document_idle"
です。
可能な値は次のとおりです:
document_idle
: 可能な限り
document_start
: css
からのファイルの後、しかし他のDOMが構築される前や他のスクリプトが実行される前。
document_end
: DOMが完了した直後ですが、画像やフレームなどのサブリソースが読み込まれる前。
manifest.json
を介してVia service-worker.js
background
コンテンツスクリプトによって送信されたメッセージは、バックグラウンドページによって受信され、拡張機能のコンポーネントを調整する中心的な役割を果たします。特に、バックグラウンドページは拡張機能のライフタイムを通じて持続し、直接的なユーザーの操作なしに静かに動作します。独自のドキュメントオブジェクトモデル(DOM)を持ち、複雑な相互作用と状態管理を可能にします。
重要なポイント:
バックグラウンドページの役割: 拡張機能の神経中枢として機能し、拡張機能のさまざまな部分間の通信と調整を確保します。
持続性: ユーザーには見えないが、拡張機能の機能に不可欠な常に存在するエンティティです。
自動生成: 明示的に定義されていない場合、ブラウザは自動的にバックグラウンドページを作成します。この自動生成されたページには、拡張機能のマニフェストに指定されたすべてのバックグラウンドスクリプトが含まれ、拡張機能のバックグラウンドタスクのシームレスな操作を確保します。
明示的に宣言されていない場合にブラウザがバックグラウンドページを自動的に生成することによって提供される便利さは、すべての必要なバックグラウンドスクリプトが統合され、動作することを保証し、拡張機能のセットアッププロセスを簡素化します。
Example background script:
It uses runtime.onMessage API to listen to messages. When an "explain"
message is received, it uses tabs API to open a page in a new tab.
To debug the background script you could go to the extension details and inspect the service worker, this will open the developer tools with the background script:
ブラウザ拡張機能にはさまざまな種類のページが含まれることがあります:
アクションページは、拡張機能のアイコンがクリックされたときにドロップダウンで表示されます。
拡張機能が新しいタブで読み込むページ。
オプションページ:このページはクリックすると拡張機能の上に表示されます。前のマニフェストでは、私はこのページにchrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca
でアクセスできました、またはクリックすることで:
これらのページは、必要に応じて動的にコンテンツを読み込むため、バックグラウンドページのように永続的ではないことに注意してください。それにもかかわらず、これらはバックグラウンドページと特定の機能を共有しています:
コンテンツスクリプトとの通信: バックグラウンドページと同様に、これらのページはコンテンツスクリプトからメッセージを受信でき、拡張機能内での相互作用を促進します。
拡張機能固有のAPIへのアクセス: これらのページは、拡張機能に定義された権限に従って、拡張機能固有のAPIへの包括的なアクセスを享受します。
permissions
& host_permissions
permissions
とhost_permissions
は、ブラウザ拡張機能がどの権限(ストレージ、位置情報など)を持っているか、どのウェブページでそれを持っているかを示すmanifest.json
のエントリです。
ブラウザ拡張機能は非常に特権的であるため、悪意のあるものや侵害されたものは、攻撃者に機密情報を盗んだり、ユーザーを監視したりするためのさまざまな手段を提供する可能性があります。
これらの設定がどのように機能し、どのように悪用される可能性があるかを確認してください:
BrowExt - permissions & host_permissionscontent_security_policy
コンテンツセキュリティポリシーは、manifest.json
内でも宣言できます。定義されている場合、それは脆弱である可能性があります。
ブラウザ拡張機能ページのデフォルト設定はかなり制限されています:
CSPや潜在的なバイパスに関する詳細は、以下を確認してください:
Content Security Policy (CSP) Bypassweb_accessible_resources
ウェブページがブラウザ拡張のページ、例えば.html
ページにアクセスするためには、このページがmanifest.json
の**web_accessible_resources
**フィールドに記載されている必要があります。
例えば:
これらのページは、次のようなURLでアクセス可能です:
公共拡張機能では、extension-idがアクセス可能です:
ただし、manifest.json
パラメータ**use_dynamic_url
が使用されている場合、このidは動的**になる可能性があります。
ここにページが記載されていても、Content Security PolicyのおかげでClickJackingから保護されている可能性があることに注意してください。したがって、ClickJacking攻撃が可能かどうかを確認する前に、これをチェックする必要があります(frame-ancestorsセクション)。
これらのページにアクセスできることは、これらのページが潜在的に脆弱なClickJackingであることを意味します:
BrowExt - ClickJackingこれらのページが拡張機能によってのみ読み込まれ、ランダムなURLからは読み込まれないようにすることで、ClickJacking攻撃を防ぐことができます。
web_accessible_resources
からのページや拡張機能の他のページもバックグラウンドスクリプトに連絡することができることに注意してください。したがって、これらのページのいずれかがXSSに対して脆弱である場合、より大きな脆弱性を引き起こす可能性があります。
さらに、**web_accessible_resources
に示されたページはiframe内でのみ開くことができますが、新しいタブからは拡張機能IDを知っていれば拡張機能内の任意のページにアクセスすることが可能です。したがって、同じパラメータを悪用するXSSが見つかった場合、ページがweb_accessible_resources
**に設定されていなくても悪用される可能性があります。
externally_connectable
docsによると、"externally_connectable"
マニフェストプロパティは、どの拡張機能とウェブページがあなたの拡張機能に接続できるかを宣言します。これは、runtime.connectおよびruntime.sendMessageを介して行われます。
externally_connectable
キーが拡張機能のマニフェストに宣言されていない場合、または**"ids": ["*"]
**として宣言されている場合、すべての拡張機能が接続できますが、ウェブページは接続できません。
特定のIDが指定されている場合、例えば"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
のように、そのアプリケーションのみが接続できます。
matchesが指定されている場合、これらのウェブアプリは接続できるようになります:
空として指定されている場合: "externally_connectable": {}
、アプリやウェブは接続できません。
ここで示されている 拡張機能とURLが少ないほど、攻撃面は小さくなります。
もしウェブページが XSSまたはテイクオーバーに脆弱であり、externally_connectable
に示されている場合、攻撃者は バックグラウンドスクリプトに直接メッセージを送信でき、コンテンツスクリプトとそのCSPを完全にバイパスすることができます。
したがって、これは 非常に強力なバイパスです。
さらに、クライアントが不正な拡張機能をインストールした場合、脆弱な拡張機能と通信することが許可されていなくても、許可されたウェブページにXSSデータを注入したり、WebRequest
やDeclarativeNetRequest
APIを悪用して、ターゲットドメインのリクエストを操作し、JavaScriptファイルのリクエストを変更することができます。(ターゲットページのCSPがこれらの攻撃を防ぐ可能性があることに注意してください)。このアイデアはこの書き込みから来ています。
コンテンツスクリプトとウェブページ間で通信するために、通常はポストメッセージが使用されます。したがって、ウェブアプリケーションでは通常、window.postMessage
関数への呼び出しが見られ、コンテンツスクリプトでは window.addEventListener
のようなリスナーが見られます。ただし、拡張機能は ポストメッセージを送信してウェブアプリケーションと通信することもできるため、ウェブはそれを期待する必要があります。または、単にウェブに新しいスクリプトを読み込ませることもできます。
通常、chrome.runtime.sendMessage
関数が拡張機能内でメッセージを送信するために使用され(通常は background
スクリプトによって処理されます)、受信して処理するためにリスナーが chrome.runtime.onMessage.addListener
を呼び出して宣言されます。
chrome.runtime.connect()
を使用して、単一のメッセージを送信する代わりに持続的な接続を持つことも可能で、次の例のように メッセージを送信および受信するために使用できます。
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)