DVWA Content Security Policy (CSP) Bypass

前言

CSP(Content Security Policy,内容安全策略)是一种用来防止XSS攻击的手段,通过在头部Content-Security-Policy 的相关参数,来限制未知(不信任)来源的JavaScript脚本的执行,从而达到防止xss攻击的目的。

一般的xss攻击,主要是通过利用函数过滤/转义输入中的特殊字符、标签、文本来应对攻击。

CSP则是另外一种常用的应对XSS攻击的策略。其实质就是白名单机制,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。

CSP启动方式

  1. 通过 HTTP 响应头信息的Content-Security-Policy字段

    1
    content-security-policy:script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';  
    • ‘none’:代表空集;即不匹配任何 URL。两侧单引号是必须的。
    • ‘self’:代表和文档同源,包括相同的 URL 协议和端口号。两侧单引号是必须的。
    • ‘unsafe-inline’:允许使用内联资源,如内联的 <script> 元素、javascript:URL、内联的事件处理函数和内联的 <style> 元素。两侧单引号是必须的。
    • ‘unsafe-eval’:允许使用 eval() 等通过字符串创建代码的方法。两侧单引号是必须的。
  2. 通过网页的标签

    1
    <meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none';	style-src example.org third-party.org; child-src https:">
    • script-src:脚本:只信任当前域名。
    • object-src:不信任任何URL,即不加载任何资源。
    • style-src样式表:只信任example.org和third-party.org。
    • child-src:必须使用HTTPS协议加载。这个已从Web标准中删除,新版本浏览器可能不支持。

LOW

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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>
';

分析:

允许的脚本来源:selfhttps://pastebin.comexample.comcode.jquery.comhttps://ssl.google-analytics.com

在pastebin网站上写一个JavaScript代码alert(document.cookie);,链接为https://pastebin.com/WpR2dJxB,在界面中输入这个链接,理论上可以弹出cookie值,但是实际操作过程中无法弹出cookie,目前还未找到原因;

MIEDIUM

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 <?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>
';

分析:

只允许selfunsafe-inline的js脚本。
'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA='指的是,允许内联的脚本,并且必须带有nonce值,比如<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(document.cookie)</script>,就会弹出弹框。

HIGH

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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>
';

分析:

允许self的脚本执行,self是指本页面加载的脚本。

可以使用用post方式提交如下脚本:

1
include=<script src="source/jsonp.php?callback=alert(document.cookie);"></script>

IMPOSSIBLE

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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>
';

分析:

直接把执行的js代码写在了php文件中。

参考

https://blog.csdn.net/weixin_40950781/article/details/99991677

https://www.jianshu.com/p/59b748f0f046