DVWA-13.3 CSP Bypass(绕过浏览器的安全策略)-High?

High Level

查看源码

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

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

这个级别已经没有输入框了,不过题目已经给了足够多的提示。

首先先看一下 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 文件的,但是在查看服务端源码的时,可以看到下面代码:
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
    " . $_POST['include'] . "
";
}

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

jsonp.php

<?php
header("Content-Type: application/json; charset=UTF-8");

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

$outp = array ("answer" => "15");

echo $callback . "(".json_encode($outp).")";
?>

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

PS:坦白说,这个我还不太理解,也没试出来。

参考:

https://www.cnblogs.com/-zhong/p/10906270.html

https://zhuanlan.zhihu.com/p/110012962

posted @ 2020-05-06 17:21  zhengna  阅读(407)  评论(0编辑  收藏  举报