XSS已有近二十年的歷史了,但它仍然是Web上最常見的漏洞之一。因此,已經發展了許多機制來減輕漏洞的影響。我經常會誤以爲這些機制可以作爲針對XSS的保護。今天,我們將瞭解爲什麼情況並非如此。我們將在代碼重用攻擊領域探索一種相對較新的技術。Web的代碼重用攻擊於 2017年 首次描述,可用於繞過大多數現代瀏覽器保護,包括:HTML sanitizers,WAF和CSP。

介紹

讓我們使用示例進行演示:

<?php 
/* File: index.php */
// CSP disabled for now, will enable later
// header("Content-Security-Policy: script-src 'self' 'unsafe-eval'; object-src 'none';");
?>
​
<!DOCTYPE html>
<html lang="en">
<body> 
  <div id="app">
  </div>
  <script src="http://127.0.0.1:8000/main.js"></script>
</body>
</html>
/** FILE: main.js **/
var ref=document.location.href.split("?injectme=")[1];
document.getElementById("app").innerHTML = decodeURIComponent(ref);

該程序具有基於DOM的XSS漏洞。Main.js獲取GET參數 injectme 的值,並將其作爲原始HTML插入到DOM中。這是一個問題,因爲用戶可以控制參數的值。因此,用戶可以隨意操作DOM。下面的請求是一個poc,證明我們可以注入任意JavaScript。

http://127.0.0.1:8000/?injectme=<img src="n/a" onerror="alert('XSS')"/>

image元素將插入到DOM中,並且在加載期間會出錯,從而觸發onerror事件處理程序。這會彈出一個警告消息,提示“ XSS”,證明我們可以使該應用運行任意JavaScript。

現在,通過刪除index.php中第5行的註釋來啓用內容安全策略。然後重新加載頁面,您將看到攻擊失敗。如果在瀏覽器中打開開發者控制檯,則會看到一條說明原因的消息。

涼!所以發生了什麼事?IMG html元素已創建,瀏覽器看到了onerror事件屬性,但由於CSP而拒絕執行JavaScript。

用一個不切實際的簡單小工具繞過CSP

在我們的示例中,CSP限制–允許來自同一主機的JavaScript–阻止危險的功能,例如eval(不安全的eval)–阻止了所有其他腳本–阻止了所有對象(例如flash)

但是,如果我們能以某種方式觸發CSP白名單中已經存在的JavaScript代碼怎麼辦?如果是這樣,我們也許可以執行任意JavaScript而不會違反該政策。讓我們看一個小工具的簡單示例,以瞭解基本概念。

假設main.js文件看起來像這樣:

/** FILE: main.js **/
var ref = document.location.href.split("?injectme=")[1];
document.getElementById("app").innerHTML = decodeURIComponent(ref);
​
document.addEventListener("DOMContentLoaded", function() {         
    var expression = document.getElementById("expression").getAttribute("data");
    var parsed = eval(expression);
    document.getElementById("result").innerHTML = '<p>'+parsed+'</p>';
});

代碼基本相同,但是這次我們的目標也有某種數學計算器。請注意,僅main.js被更改,index.php與以前相同。您可以將數學函數視爲一些未真正使用的舊代碼。

作爲攻擊者,我們可以濫用數學計算器代碼來評估並執行JavaScript,而不會違反CSP。我們不需要注入JavaScript。我們只需要注入一個ID爲“ expression”和一個名爲“ data”的屬性的HTML元素。內部數據將傳遞給eval。

我們試一試,是的!我們繞過了CSP!

轉向現實的腳本小工具

如今的網站包含許多第三方資源,而且情況越來越糟。這些都是合法的列入白名單的資源,即使強制執行了CSP。數百萬行的JavaScript中也許有有趣的小工具?嗯,是!Lekies等。(2017)分析了16個廣泛使用的JavaScript庫,發現幾乎所有庫中都有多個小工具。

小工具有幾種類型,它們可以直接有用,或者需要與其他小工具鏈接纔能有用。

字符串操作小工具:用於繞過基於模式的緩解措施很有用。元素構造小工具:

有助於繞過XSS緩解措施,例如創建腳本元素。函數創建小工具:可以創建新的函數對象,以後可以由第二個小工具執行。JavaScript執行接收器小工具:類似於我們剛纔看到的示例,可以獨立運行,也可以作爲鏈中的最後一步

讓我們看另一個例子。我們將使用相同的應用程序,但現在讓我們包括jQuery mobile。

<?php 
/** FILE: index.php **/
header("Content-Security-Policy: script-src 'self' https://code.jquery.com:443 'unsafe-eval'; object-src 'none';");
?>
​
<!DOCTYPE html>
<html lang="en">
<body>
  <p id="app"></p>
  <script src="http://127.0.0.1:8000/main.js"></script>
  <script src="https://code.jquery.com/jquery-1.8.3.min.js"></script>
  <script src="https://code.jquery.com/mobile/1.2.1/jquery.mobile-1.2.1.min.js"></script>
</body>
</html>
/** FILE: main.js **/
var ref = document.location.href.split("?injectme=")[1];
document.getElementById("app").innerHTML = decodeURIComponent(ref);

CSP進行了少許更改,以允許來自code.jquery.com的任何內容,幸運的是,jQuery Mobile有一個已知的腳本小工具可供我們使用。該小工具還可以嚴格動態地繞過CSP。

讓我們首先考慮以下html

<div data-role=popup id='hello world'></div>

此HTML將觸發jQuery Mobile的 Popup Widget中的 代碼。可能不明顯的是,當您創建彈出窗口時,庫會將id屬性寫入HTML註釋中。

jQuery中負責此工作的代碼如下所示:

這是一個代碼小工具,我們可以濫用它來運行JavaScript。我們只需要繞過註釋,然後我們就可以做我們想做的任何事情。

我們最終的payload將如下所示:

<div data-role=popup id='--!><script>alert("XSS")</script>'></div>

執行,彈框!

相關文章