DVWA--CSP Bypass


 

 0x01看到標題,是否有點疑惑 CPS 是什么東東。簡單介紹一下就是瀏覽器的安全策略,如果 標簽,或者是服務器中返回 HTTP 頭中有 Content-Security-Policy 標簽 ,瀏覽器會根據標簽里面的內容,判斷哪些資源可以加載或執行

廬山真面目 —— 何為CSP

為了研究CSP(Content Security Policy)對XSS攻擊的防護作用,他們做了對CSP安全模型的首次深入分析,分析了CSP標准中對web缺陷的保護能力,幫助識別常見的CSP策略配置的可能錯誤,並且展示了三類能使CSP無效化的繞過方法。

這次研究所采用的材料基於從Google搜索的索引文件中所提取到的CSP策略,從語料庫中提取了大約1060億頁的頁面,其中39億是受CSP保護的,其中確認了26,011個獨立的策略。他們發現,由於策略配置錯誤和白名單條目不安全,這些策略中至少有94.72%無法緩解XSS攻擊。基於這樣的研究結果,他們建議在實踐中部署CSP時,使用基於nonce的方法而不是傳統的白名單。並且,他們提出了名為“strict dynamic”的新特性,這是當前在Chromium瀏覽器中實現的CSP3規范的一個新特性。以下會詳細講述為何要使用這種策略和特性。

首先,何為CSP?我們知道,內容安全策略(CSP)是一種聲明機制,允許Web開發者在其應用程序上指定多個安全限制,由支持的用戶代理(瀏覽器)來負責強制執行。CSP旨在“作為開發人員可以使用的工具,以各種方式保護其應用程序,減輕內容注入漏洞的風險和減少它們的應用程序執行的特權”。當前,CSP還處在快速的發展期,目前正在進行規范中的版本是CSP3,CSP標准由用戶代理選擇實現。例如,Chromium具有完整的CSP2支持,並且實現了CSP3的大部分工作草案,僅在某些情況下可能會落后於實驗中的某些特性,而MozillaFirefox和基於WebKit的瀏覽器則剛剛獲得了完整的CSP2支持。在實際使用中,CSP策略在Content-Security-Policy HTTP響應頭或元素中提供。

0x02初級篇,如果不看源碼的話。看檢查器(F12),也可以知道一些被信任的網站。

首先我們來查看一下源碼

<?php

$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/raw/R570EE00

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

 

觀察頭信息,羅列允許JavaScript的網站 當然你也可以從這里開發者工具來看到這個頭

$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com  example.com code.jquery.com ht

此時可以上pastebin網站上自己寫一個javascript代碼alert(“hahaha”),保存后記住鏈接,

https://pastebin.com/raw/zSLDySJn

然后在上面界面中輸入鏈接,結果如下

看到嘛,在pastebin上保存的js代碼被執行了。那就是因為pastebin網站是被信任的。攻擊者可以把惡意代碼保存在收信任的網站上,然后把鏈接發送給用戶點擊,實現注入。

0X03medium級別的

老規矩我們先看一下源碼

<?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>
';
http頭信息中的script-src的合法來源發生了變化,說明如下

    unsafe-inline,允許使用內聯資源,如內聯< script>元素,javascript:URL,內聯事件處理程序(如onclick)和內聯< style>元素。必須包括單引號。
    nonce-source,僅允許特定的內聯腳本塊,nonce=“TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA”

現在更加簡單了,可以直接輸入以下代碼
<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert('qisheng')</script>

不用解釋了吧,nonce是設定好的,允許運行。

0X04high級別的CSP

繼續看源碼

vulnerabilities/csp/source/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>
';

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 文件的(除非結合別的漏洞, 拿 shell 后修改). 然而, 我后來在查看服務端源碼的時候發現了這個:
竟然還偷偷接收 include 參數(不清楚是不是作者復用了之前 Medium 的代碼). 總之, 這肯定能作為一個注入點, 我開始打算用簡單粗暴的 <script>alert('hacked')</script> 來搞定的, 誰知道, 這種是屬於 'unsafe-inline' 形式的, 所以被限制執行了. 嗯... 既然如此的話, 那我就利用 src 吧.
這個即使你不看源碼, 你做幾個測試也會發現, 那個 callback 參數可以被操控以生成任何你想要得到的結果, 比如 alert, 因此可以構造 Payload: <script src="source/jsonp.php?callback=alert('hacked');"></script>, 並把這個當做 include 參數傳給界面就  注入成功!

0x05Impossible

該級別主要還是修復了 callback 參數可被控制問題(畢竟這是問題根源):

https://content-security-policy.com/ 學習鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM