PHP代码审计DVWA[CSP Bypass]

136 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

CSP Bypass

CSP 指的是内容安全策略

为了缓解很大一部分潜在的跨站脚本(XSS) 问题,浏览器的扩展程序系统引入了内容安全策略(CSP)的一般概念。通过引入一些相当严格的策略使扩展程序在默认情况下更加安全,开发者可以创建并强制应用一些规则,管理网站允许加载的内容。

CSP 以白名单的机制对网站加载或执行的资源起作用,在网页中策略通过 HTTP 头信息或者 meta 元素定义。CSP 虽然提供了强大的安全保护,但是它也令 eval() 及相关函数被禁用、内嵌的 JavaScript 代码将不会执行、只能通过白名单来加载远程脚本。如果要使用 CSP 技术保护自己的网站,开发者就不得不花费大量时间分离内嵌的 JavaScript 代码和做一些调整。

今天就是通过DVWA来详细由浅入深学习如何绕过CSP(CSP Bypass)

LOW

代码分析

 <?php
//self是指向类本身,也就是PHP self关键字是不指向任何已经实例化的对象,一般self使用来指向类中的静态变量。
//self可以访问本类中的静态属性和静态方法,可以访问父类中的静态属性和静态方法
     //存放url
     
$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() 函数向客户端发送原始的 HTTP 报头。
//发送$headerCSP的
header($headerCSP);

# https://pastebin.com/raw/R570EE00

?>
<?php
    //if判断
    //非空
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>
';

大致就是

源码定义了一个变量 headerCSP 放置了一些 url,使用 script src 指令指向一个外部 JavaScript 文件,header() 函数以原始形式将 HTTP 标头发送到客户端或浏览器.

根据上面的源码可以被执行的资源,被信任的网站

pastebin.com hastebin.com example.com code.jquery.com ssl.google-analytics.com

这个时候我们打开其中白名单里一个网页:

首先在https://pastebin.com/里边创建一个JavaScript代码alert("hahaha")保存记住链接:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

复制url

去执行

如何F12

成功载进去了

在这里插入图片描述

注意

这里需要说明一下,pastebin.com/这个网址是米国的,访问…

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

他提供了一个给我们

用一下

<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script>

在这里插入图片描述

在这里插入图片描述

非常理智的内容

High

代码分析

<?php
    //没有其他的URL了全部没有了
$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>
';

还要一个js的代码

 function clickButton() {
     //点击按钮,js创建一个script标签
    var s = document.createElement("script");
     //src指向source/jsonp.php?callback=solveNum
    s.src = "source/jsonp.php?callback=solveSum";
     //appendChild(s)函数又将source/jsonp.php?callback=solveNum加入到DOM中
    document.body.appendChild(s);
}

function solveSum(obj) {
    //源码定义了一个solveNum函数,利用obj传参,若answer在obj中将会被执行
    if ("answer" in obj) {
        //document对象可以访问HTML中的内容
        document.getElementById("answer").innerHTML = obj['answer'];
    }
}
//getElementById(id)可返回对拥有指定 ID 的第一个对象的引用
var solve_button = document.getElementById ("solve");

if (solve_button) {
    solve_button.addEventListener("click", function() {
        clickButton();
        //innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML
        //这里的 script 标签会把远程加载的 solveSum({“answer”:“15”}) 当作 js 代码执行, 然后这个函数就会在页面显示答案
    });
}

在这里插入图片描述

这里也没有输入框了

js代码中可以看到

可以看到src指向的source/jsonp.php?callback=solveNum未做任何XSS的过滤,因此可以构造payload
<script src= "source/jsonp.php?callback=alert("xss")";></script>

修改地方是

在这里插入图片描述

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