[网络安全] DVWA之Content Security Policy (CSP) Bypass 攻击姿势及解题详析合集

CSP概念

CSP 是 Content Security Policy(内容安全策略)的缩写,是一种用于增强 Web 应用程序安全性的安全机制。它通过允许网站管理员控制页面中加载内容的来源来减少跨站脚本攻击(XSS)等常见的安全风险。

CSP 的工作原理是通过定义一组策略规则,指定哪些来源可以被信任和允许加载到页面中。这些来源可以是同源的网址、特定的域名、安全连接(如 HTTPS)或者是内联脚本和样式表。 CSP 可以阻止恶意代码、恶意插件或其他不受信任的资源被加载到页面上,从而增加页面的安全性。

CSP 提供了一系列的指令和选项,用于配置安全策略,例如:

  1. default-src 指令:指定默认情况下允许加载的资源来源。
  2. script-src 指令:用于限制可执行脚本的来源。
  3. style-src 指令:用于限制可应用的样式表的来源。
  4. img-src 指令:用于限制可加载的图像的来源。
  5. connect-src 指令:用于限制可建立网络连接的来源。
  6. font-src 指令:用于限制可加载的字体文件的来源。
  7. frame-src 指令:用于限制可以嵌入页面的框架的来源。
  8. report-uri 指令:指定将安全违规报告发送到的 URL。

通过合理配置 CSP,网站管理员可以严格限制哪些资源能被加载,从而减少恶意代码执行的风险。它还可以帮助检测和修复存在的安全漏洞,并提供了一种机制来报告违规行为。

Low level

译文如下:您可以包含来自外部源的脚本,检查内容安全策略,然后在此处输入要包含的URL:

源代码

复制代码
<?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>
';

首先,通过设置 $headerCSP 变量来定义 CSP 的策略规则。

  • script-src 指令被用来限制可执行的脚本的来源。通过设置 'self'https://pastebin.comhastebin.comwww.toptal.comexample.comcode.jquery.comhttps://ssl.google-analytics.com 这些来源,来允许从这些地址加载 JavaScript。

然后,使用 header() 函数将定义好的 CSP 头部发送给浏览器,以告知浏览器采用 CSP 策略。

接着是一个简单的网页表单,允许用户输入一个 URL,并在提交表单时使用 $_POST['include'] 获取用户输入的 URL。如果用户输入了 URL,那么会根据用户输入的 URL 动态生成一个 <script> 标签来加载外部脚本。

姿势

由代码审计得到以下的外部资源可以被响应

复制代码
self
https://pastebin.com
hastebin.com
example.com
code.jquery.com
https://ssl.google-analytics.com

在CSP的规则中,'self'表示当前网站的源。当使用'self'作为脚本来源时,只有同源的脚本才会被加载和执行。

https://pastebin.com 为例

新建Paste并输入脚本:

创建完成后点击raw

复制该网址:

输入URL:

即可在当前页面触发弹窗 1

Medium level

源代码

复制代码
<?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>
';

首先,代码通过设置$headerCSP变量定义了一个内容安全策略的头部。通过"script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA='"指令设置 nonce ,其目的是为了提供额外的安全性,确保只有具有相应 nonce 的脚本能够被执行。这样可以防止未经授权的脚本注入攻击。

然后使用header($headerCSP);将该内容安全策略头部应用于响应头。

接下来,通过header("X-XSS-Protection: 0");这行代码,禁用了浏览器的跨站脚本攻击(XSS)防护机制,以便内联的弹窗警告框能够正常工作。

接下来的代码段是一个表单,允许用户输入内容,并将该内容直接输出到页面中。用户可以在文本框中输入任意内容,这些内容将被添加到页面的主体部分。

姿势

在实际应用中,可以根据需要为每个内联脚本生成唯一的 nonce,并将其与相应的脚本标签一起使用,例如:

复制代码
<script nonce="生成的唯一的nonce值">脚本代码</script>

这样可以确保仅允许具有正确 nonce 值的脚本执行。

综上所述,我们可以构造POC如下:

复制代码
<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert("qiushuo")</script>

其中的nonce也可以从消息头中得到:

输入POC:

回显如下:

High level

源代码

复制代码
//vulnerabilities/csp/source/high.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>
';

复制代码
//vulnerabilities/csp/source/high.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();
    });
}

首先,在文件 high.php 中设置了一个 CSP 头部,规定只允许从同一源的脚本加载,即 script-src 'self'。这样可以防止恶意代码的注入。然后,通过 PHP 的 header 函数将 CSP 头部发送给浏览器。

接下来,在表单提交时,如果存在名为 include 的 POST 参数,将其作为代码包含在页面主体中。

点击按钮时,会执行 JavaScript 函数 clickButton,该函数动态创建一个 script 元素,并设置其 src 属性为 source/jsonp.php?callback=solveSum。这里使用了 JSONP(JSON with Padding)技术,通过指定回调函数名称的方式来获取跨域的数据。当脚本加载完成后,会调用函数 solveSum,将返回的数据展示在页面上。

在文件 high.js 中定义了 clickButton 函数用于创建 script 元素并加载跨域脚本,以及 solveSum 函数用于处理返回的数据。最后,通过事件监听,当按钮被点击时,调用 clickButton 函数。

简单来说

当点击按钮后,以下步骤会依次发生:

  1. 首先,浏览器会执行 JavaScript 函数 clickButton
  2. clickButton 函数中,会动态创建一个 <script> 元素。
  3. <script> 元素的 src 属性被设置为 source/jsonp.php?callback=solveSum,其中 source/jsonp.php 是一个远程脚本的 URL,callback=solveSum 指定了回调函数的名称为 solveSum
  4. 浏览器会开始加载指定的远程脚本文件 source/jsonp.php
  5. 当远程脚本文件加载完成后,返回的数据会通过回调函数 solveSum进行处理。
  6. solveSum 函数中,返回的数据会被展示在页面上。

姿势

由于 include 为可控参数且回调函数的名称solveSum可更改

故构造POC如下:

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

Impossible level

源代码

复制代码
 <?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>
';

vulnerabilities/csp/source/impossible.js
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();
    });
}
  1. 在代码开始处,通过设置 Content-Security-Policy 头部字段,指定了一个 CSP 设置,即 script-src 'self';。这个设置规定只允许从同域名加载 JavaScript 脚本,并且不允许使用内联脚本。

  2. 接下来的条件语句检查是否存在名为 include 的 POST 参数。如果存在该参数,将其内容添加到 $page['body'] 变量中。

  3. 然后创建一个包含说明文本和一个空 <span> 元素的表单,表单的提交方法是 POST。

  4. 表单中有一个按钮元素,点击该按钮会触发一个事件,调用名为 clickButton() 的 JavaScript 函数。

  5. 页面加载了一个名为 source/impossible.js 的 JavaScript 文件,通过 <script> 标签引入。

  6. source/impossible.js 中定义了一个名为 clickButton() 的函数。该函数会创建一个新的 <script> 元素,并将其 src 属性设置为 source/jsonp_impossible.php,然后将该元素添加到页面的 <body> 元素中。

  7. source/impossible.js 中还定义了一个名为 solveSum(obj) 的函数,用于处理异步加载的远程脚本返回的数据。如果返回的数据包含 answer 属性,该函数会将该属性值设置为页面中的 <span id="answer"> 元素的内容。

  8. 最后,通过获取按钮元素并添加点击事件监听器,实现了按钮点击后调用 clickButton() 函数的功能。

总的来说,这段代码使用 Content Security Policy(CSP)限制了 JavaScript 代码的来源和类型,同时对用户输入进行了处理。可以有效地提高了安全性。

总结

以上为DVWA之Content Security Policy (CSP) Bypass 攻击姿势及解题详析合集,结合PHP代码审计Http相关知识考察CSP渗透姿势。

相关推荐
darkb1rd2 小时前
四、PHP文件包含漏洞深度解析
网络·安全·php
哆啦code梦2 小时前
2024 OWASP十大安全威胁解析
安全·系统安全·owasp top 10
网络安全研究所4 小时前
AI安全提示词注入攻击如何操控你的智能助手?
人工智能·安全
海心焱4 小时前
安全之盾:深度解析 MCP 如何缝合企业级 SSO 身份验证体系,构建可信 AI 数据通道
人工智能·安全
程序员哈基耄6 小时前
纯客户端隐私工具集:在浏览器中守护你的数字安全
安全
darkb1rd8 小时前
五、PHP类型转换与类型安全
android·安全·php
中科三方9 小时前
域名转移详细指南:流程、材料、注意事项和常见问题全解析
网络·安全
云小逸12 小时前
【nmap源码学习】 Nmap 源码深度解析:nmap_main 函数详解与 NSE 脚本引擎原理
网络协议·学习·安全
迎仔12 小时前
04-网络安全基础:数字世界的防盗门与守卫
网络·安全·web安全
MicroTech202513 小时前
微算法科技(NASDAQ :MLGO)量子测量区块链共识机制:保障数字资产安全高效存储与交易
科技·安全·区块链