DVWA靶场实战(十三)——CSP Bypass
DVWA靶场实战(十三)
十三、CSP Bypass:
1.漏洞原理:
CSP Bypass全称是Content-Security-Policy,中文叫做绕过内容安全策略。Content-Security-Policy是一个HTTP响应头的名称,现代浏览器使用它来加强文档(或网页)的安全性。 Content-Security-Policy头允许你限制哪些资源(如JavaScript、CSS、图像等)可以被加载,以及它们可以从哪些URL加载。虽然它主要是作为一个HTTP响应头使用,但你也可以通过元标签来应用它。内容安全策略这一术语通常被缩写为CSP。
2.补充:
·Script-src’self’:script-src脚本只信任当前域名;
·Object-src’none’:不信任任何URL,即不加载任何资源;
·Style-src样式表:只信任http://cdn.example.org和http://third-party.org;
·Child-src:必须使用HTTPS协议加载。这个已从Web标准中删除,新版本浏览器可能不支持;
·其他资源:没有限制其他资源。
3.实战:
(1)Low:
代码分析:
<?php
$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com hastebin.com www.toptal.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://www.toptal.com/developers/hastebin/raw/cezaruzeka
?>
<?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>
';
我们可以看见被信任的网站有https://pastebin.com、hastebin.com、www.toptal.com、example.com、code.jquery.com、https://ssl.google-analytics.com。、
我们开始尝试攻击,首先使用的是https://pastebin.com这个网站但是查阅资料后,发现可能这个网站是国外的网站,访问速度比较慢,所以不会出现弹窗。但是原理基本上差不多,所以我们还是按照原计划行事。
首先打开https://pastebin.com,输入“alert(1);”,然后点击“Create New Paste”就可以得到下一步,点击“raw”,复制得到的网址。
然后将这个链接输入DVWA,就可以得到弹窗了,这里我也借用下人家成功的图片。
(2)Medium:
代码分析:
<?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>
';
unsafe-inline:当csp有Unsafe-inline时, 并且受限于csp无法直接引入外部js, 不过当frame-src为self, 或者能引入当前域的资源的时候, 即有一定可能能够引入外部js。nonce-source,仅允许特定的内联脚本块。所以直接输入源码内注释的内容即可。
(3)High:
代码分析:
<?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>
';
source/high.js:代码的主要逻辑还是在这一段,大致的意思就是,点击一个按钮会生成一个script的标签,该标签的src指向source/jsonp.php?callback=solveNum,然后把这个标签加入到DOM中。solveSum()函数传入参数obj,如果obj包含“answer”,远程加载的 solveSum({"answer":"15"}) 当作 js 代码执行,然后这个函数就会在界面适当的位置写入答案。可以看到src指向的source/jsonp.php?callback=solveNum未做任何XSS的过滤,直接F12修改high.js的源代码,可以看到也能成功获取cookie。
(4)Impossible:
代码分析:
<?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>
';
防御模板修复了 callback 参数可被控制问题,就没有 url 中的 callback 了,后台写死了。