0x01 庐山真面目 —— 何为CSP

看到标题,是否有点疑惑 CSP 是什么东西。简单介绍一下就是浏览器的安全策略,如果 标签,或者是服务器中返回 HTTP 头中有 Content-Security-Policy 标签 ,浏览器会根据标签里面的内容,判断哪些资源可以加载或执行。

为了研究CSP(Content Security Policy)对XSS攻击的防护作用,他们做了对CSP安全模型的首次深入分析,分析了CSP标准中对web缺陷的保护能力,帮助识别常见的CSP策略配置的可能错误,并且展示了三类能使CSP无效化的绕过方法。

这次研究所采用的材料基于从Google搜索的索引文件中所提取到的CSP策略,从语料库中提取了大约1060亿页的页面,其中39亿是受CSP保护的,其中确认了26,011个独立的策略。他们发现,由于策略配置错误和白名单条目不安全,这些策略中至少有94.72%无法缓解XSS攻击。基于这样的研究结果,他们建议在实践中部署CSP时,使用基于nonce的方法而不是传统的白名单。并且,他们提出了名为“strict dynamic”的新特性,这是当前在Chromium浏览器中实现的CSP3规范的一个新特性。以下会详细讲述为何要使用这种策略和特性。

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

简单来说CSP

CSP(Content Security Policy) 是一种用来防止 XSS 攻击的手段, 通过在头部添加 Content-Security-Policy 的相关参数, 来限制未知(不信任)来源的 javascript 的执行从而防止 XSS 攻击. 本题并不是要介绍这种技术有什么漏洞, 而且本题所导致的 XSS 攻击都是因为开发者的不正当配置所致. 所以本题仅仅让你能成功执行一个弹框的 XSS 注入即可.

0x02 DVWA-low

如果不看源码的话。看检查器(F12),也可以知道一些被信任的网站。

首先我们来查看一下源码

<?php$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com  example.com 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>
';

观察头信息,罗列允许JavaScript的网站 当然你也可以从这里开发者工具来看到这个头

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

这个头部信息的具体含义可以参考这个参考文档:https://content-security-policy.com/, 这里直接理解就是能从 https://pastebin.com 等网站加载 javascript, 你可以试试从自己的搭建的服务器中加载 javascript, 结果如下:

可以明显的看到, 这个 javascript 的加载被 blocked 了(估计 Firefox 的插件 No-script 也是基于这个的). 既然不能从未指定的源加载 javascript, 那我可以从它信任的源, 比如 https://pastebin.com 中来加载. 可能有人不知道这个网站是什么, 我开始也不知道的, 但你打开就会发现这就是个共享粘贴板, 允许你粘贴任何文本内容.

那我们就可以在这个粘贴板网站中写入一段恶意 javascript, 比如 alert(123), 然后, 通过该网站的 raw 形式(原生)来显示, 我当时生成的网址是这个:https://pastebin.com/tV3VNjiB, 然后你就可以在 URL 栏中输入这个网址, 让浏览器将这个远程加载文本当作 javascript 来执行

结果如下:


看到嘛,在pastebin上保存的js代码被执行了。那就是因为pastebin网站是被信任的。攻击者可以把恶意代码保存在收信任的网站上,然后把链接发送给用户点击,实现注入。

Medium

通过浏览器或者Burp抓包可以看到:

Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';

这次使用了两个新的参数(self 不算哈). 其中 'unsafe-inline' 代表可以执行诸如 onclick 等事件或 script 标签内的内容这类 javascript, 而后者就是指如果你要使用 script 标签加载 javascript, 你需要指明其 nonce 值, 比如 <script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert('hacked')</script>这个就能正常加载, 从而造成 XSS 注入.

但需要注意的是, 如果你测试 <img src="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=" onerror=alert('hacked')> 这类在标签内执行的 javascript, 会得到如下结果:


即:

错误提示告诉我们, 因为头部指定了 nonce 值, 所以自动忽略了 'unsafe-inline' 这个参数. 因此可以判断这两个参数是不能共存的, 而且如果共存, 后者nonce 值是会覆盖前者'unsafe-inline' 的.

这里还有个有意思的地方, 你看那个 nonce 的值很明显是个 base64 编码, 我就无聊去解码了一下, 嗯... 原文"TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA="转换后是 "Never going to give you up", 还是给出题者 666. 不过呢, 正确的防御方式下的 nonce 值不应该是个固定值, 而是应该是个随机生成的值, 这样才能真正达到防止 XSS 的目的.

High

这个级别已经没有输入框了, 不过题目已经给了足够多的提示. 首先先看一下 CSP 头, 发现只有 script-src 'self';, 看来只允许本界面加载的 javascript 执行. 然后研究了一下这个点击显示答案的逻辑(逻辑在 source/high.js里), 大致如下:

在点击网页的按钮使 js 生成一个 script 标签,src 指向 source/jsonp.php?callback=solveNum。document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问,createElement() 方法通过指定名称创建一个元素,body 属性提供对 <body> 元素的直接访问,对于定义了框架集的文档将引用最外层的 <frameset>。appendChild() 方法可向节点的子节点列表的末尾添加新的子节点,也就是网页会把 “source/jsonp.php?callback=solveNum” 加入到 DOM 中。
源码中定义了 solveNum 的函数,函数传入参数 obj,如果字符串 “answer” 在 obj 中就会执行。getElementById() 方法可返回对拥有指定 ID 的第一个对象的引用,innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML。这里的 script 标签会把远程加载的 solveSum({"answer":"15"}) 当作 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();});
}

本来应该是没办法修改在服务器的 jsonp.php 文件的(除非结合别的漏洞, 拿 shell 后修改). 然而, 我后来在查看服务端源码的时候发现了这个:

if (isset ($_POST['include'])) {
$page[ 'body' ] .= "" . $_POST['include'] . "
";
}
# 剩余的显示代码

666, 竟然还偷偷用POST方式来接收 include 参数的值(不清楚是不是作者复用了之前 Medium 的代码). 总之, 这肯定能作为一个注入点, 我开始打算用简单粗暴的 <script>alert(‘hacked’)</script> 来搞定的, 谁知道, 这种是属于 ‘unsafe-inline’ 形式的, 所以被限制执行了:

既然如此的话, 那我就利用 src 吧,payload在下面。
Payload: POST方式传参include=<script src="source/jsonp.php?callback=alert('xss');"></script>

成功:

这个即使你不看源码, 你做几个测试也会发现, 那个 callback 参数可以被我们所操控而生成任何你想要得到的结果。这就是最后导致CSP被绕过而产生漏洞的原因:

Impossible

该级别主要还是修复了 callback 参数可被控制问题(毕竟这是问题根源):

这个级别是 high 级别的加强,JSONP.php 调用的回调函数callback是硬编码的,CSP 策略被锁定为只允许外部脚本。

服务器

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

参考链接

  • Content Security Policy Reference

xss之CSP bypass相关推荐

  1. PHP代码审计DVWA[CSP Bypass]

    CSP Bypass 靶场搭建可用蓝易云服务器

  2. DVWA 黑客攻防实战(十五) 绕过内容安全策略 Content Security Policy (CSP) Bypass

    看到标题,是否有点疑惑 CPS 是什么东东.简单介绍一下就是浏览器的安全策略,如果 标签,或者是服务器中返回 HTTP 头中有 Content-Security-Policy 标签 ,浏览器会根据标签 ...

  3. XSS 绕过思路 bypass 之日天日地日空气

    前文 Hello,大家好,我是None Sec的C_soon5,今天给大家讲讲XSS Bypass XSS挖掘思路 1:输入点和输出点进行XSS 输入点 URL参数 表单内容 JSONP 输出点 输出 ...

  4. 一步一步学习DVWA渗透测试(CSP Bypass绕过内容安全策略)-第十二次课

    小伙伴们,今天我们继续学习. Content-Security-Policy是指HTTP返回报文头中的标签,浏览器会根据标签中的内容,判断哪些资源可以加载或执行.翻译为中文就是绕过内容安全策略.是为了 ...

  5. DVWA 之 CSP Bypass

    目录 1.级别:Low 2.级别:Medium 3.级别:High 4.级别:Impossible CSP(Content Security Policy):即内容安全策略. 开发者通过约束指定可信的 ...

  6. DVWA指点迷津-CSP Bypass

    CSP 介绍 内容安全策略,实质上是白名单策略,通过限定允许加载哪些外部资源而保证网站的安全性. CSP规定的指令: CSP规定的值 在实际使用中,CSP策略在Content-Security-Pol ...

  7. xss and ssrf bypass 小tips

    javascript:%ef%bb%bfalert(XSS) xss%3CsvG%2Fx%3D%22%3E%22%2FoNloaD%3Dconfirm%28%29%2F%2F xss%C0AE%C0A ...

  8. xss Payload

    来自某牛的网站:http://www.cnblogs.com/b1gstar/p/5783848.html Basic and advanced exploits for XSS proofs and ...

  9. 【干货】XSS知识总结

    公众号:白帽子左一 XSS基础 跨站脚本(英语:Cross-site scripting,通常简称为:XSS)是一种网站应用程序的安全漏洞攻击,是代码注入的一种.它允许恶意用户将代码注入到网页上,其他 ...

  10. XSS Cheat Sheet

    XSS Cheat Sheet XSS 101 <h1>Hello,<script>alert(1)</script>!</h1> 1. With &l ...

最新文章

  1. Centos系统上安装php遇到的错误解决方法集锦
  2. 分析与设计(AD)简介(1)
  3. git中Please enter a commit message to explain why this merge is necessary.
  4. java调用存储过程
  5. 头的各个部位示意图_微观古建—古建筑的墀头(一)
  6. pythonxml解析拿到控件坐标_Python解析xml中dom元素的方法
  7. 全议程来啦!2021数据技术嘉年华,我们周四线上见!
  8. Openssl 嵌入式arm移植笔记
  9. 计算机科学与技术综述文献,计算机科学与技术专业文献综述应该写些什么
  10. 删除苹果自带软件后果_使用adb命令删除手机软件(包括系统自带)
  11. C++ unordered_map 在key为string类型和char*类型时测试时间性能差异
  12. java 单元测试assert_java – 使用assertTrue与其他人进行单元测试
  13. 键盘拆开重新安装步骤_电脑键盘如何维修 电脑键盘常见问题维修技巧【详解】...
  14. matlab绘图坐标显示不全的解决方法
  15. ios人脸照片_iOS人脸识别
  16. 3月编程排行榜来了~有哪些新看点?
  17. python微信加人_python实现微信自动加好友
  18. crmeb安装教程说明
  19. Allegro PCB导入网表后,PCB规则变化怎么办?
  20. 一键禁用windows defender

热门文章

  1. Word一般文章格式
  2. 解谜破案类游戏:夜间呼叫 for Mac
  3. 办公计算机班半学期总结,计算机班的班主任工作总结.docx
  4. 如何关闭Steam的弹出广告
  5. KVM虚拟化进阶--KVM设备高级管理
  6. 如何保存网站上的背景图片
  7. 大连雅思培训百家国际雅思考试词汇量要求与记忆方法是什么
  8. mysql插入微信名称中的特殊字符
  9. pip 使用国内镜像源的介绍
  10. Linux16T以上硬盘分区,centos 2T以上硬盘 或者大于超过16T分区和格式化