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

相关推荐
用户9623779544817 小时前
VulnHub DC-3 靶机渗透测试笔记
安全
叶落阁主2 天前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
用户962377954484 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机4 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机4 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954484 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star4 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954484 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
cipher6 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
一次旅行9 天前
网络安全总结
安全·web安全