DVWA 总结系列之 CSP 篇

前前言

本人的个人博客网址:www.QmSharing.space,所有的文章都可以在里面找到,欢迎各位大佬前来参观并留下宝贵的建议,大家一起学习一起成长 :-)

本题目标

本题好像是 v1.10 版本新加入的, 因此网上的分析文章并不是很多.

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

Low

因为 CSP 主要是客户端进行防御, 所以服务端的核心代码应该是没有变的(除了 CSP 头):

# 主要就是设置 HTTP 头部信息, 后面就不粘代码了, 直接分析头部即可
$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 等网站加载 javascript, 你可以试试从自己的搭建的服务器中加载 javascript, 结果如下:

加载结果

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

那我们就可以在这个粘贴板网站中写入一段恶意 javascript, 比如 alert("hacked"), 然后, 通过该网站的 raw 形式(原生)来显示, 我当时生成的网址是这个 恶意 javascript, 然后你就可以在 URL 栏中输入这个网址, 让浏览器将这个远程加载文本当作 javascript 来执行. Boom! 成功注入, 结果你们自己去试哈.

Medium

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

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=hacked onerror=alert('hacked')> 这类在标签内执行的 javascript, 会得到如下结果:

加载标签 js

错误提示告诉我们, 因为头部指定了 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), 并把它加入到 DOM 中 -> js 中定义了一个 solveNum 的函数 -> 因此 script 标签会把远程加载的 solveSum({"answer":"15"}) 当作 js 代码执行, 而这个形式正好就是调用了 solveSum 函数, 然后这个函数就会在界面适当的位置写入答案.

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

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

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

if (array_key_exists ("callback", $_GET)) {
    $callback = $_GET['callback'];
} else {
    return "";
}

$outp = array ("answer" => "15");
# 这个 callback 可以被控制的
echo $callback . "(".json_encode($outp).")";

这个即使你不看源码, 你做几个测试也会发现, 那个 callback 参数可以被操控以生成任何你想要得到的结果, 比如 alert, 因此可以构造 Payload: <script src="source/jsonp.php?callback=alert('hacked');"></script>, 并把这个当做 include 参数传给界面就 Boom! 注入成功!

Impossible

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

$outp = array ("answer" => "15");
# 写死的话, 就没办法被控制了
echo "solveSum (".json_encode($outp).")";

参考链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,576评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,515评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,017评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,626评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,625评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,255评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,825评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,729评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,271评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,363评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,498评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,183评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,867评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,338评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,458评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,906评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,507评论 2 359