習CSS注入的目的是學習計算機知識,千萬不要做違反法律的事情,不然等待你的是法律的嚴懲。
CSS僅僅只是一種用來表示樣式的語言嗎?當然不是!CSS就已被安全研究人員運用于滲透測試當中。使用屬性選擇器和iFrame,并通過CSS注入來竊取敏感數據的方法。但由于該方法需要iFrame,而大多數主流站點都不允許該操作,因此這種攻擊方法并不實用。這里為大家詳細介紹一種不需要iframe且只需10秒,就能為獲得CSRF token的方法。
一、背景
CSS屬性選擇器開發者可以根據屬性標簽的值匹配子字符串來選擇元素。 這些屬性值選擇器可以做以下操作:
屬性選擇器能讓開發人員查詢單個屬性的頁面HTML標記,并且匹配它們的值。一個實際的用例是將以“https://example.com”開頭的所有href屬性變為某種特定的顏色。而在實際環境中,一些敏感信息會被存放在HTML標簽內。在大多數情況下CSRF token都是以這種方式被存儲的:即隱藏表單的屬性值中。
可以將CSS選擇器與表單中的屬性進行匹配,并根據表單是否與起始字符串匹配,加載一個外部資源,例如背景圖片,來嘗試猜測屬性的起始字母。通過這種方式,攻擊者可以進行逐字猜解并最終獲取到完整的敏感數值。想要解決這個問題受害者可以在其服務器實施內容安全策略(CSP),防止攻擊者從外部加載CSS代碼。
二、無 iFrames
要做到無iFrame,使用一種方法:創建一個彈窗,然后在設置計時器后更改彈出窗口的位置。使用這種方仍然可以加載受害者的CSS,不再依賴于受害者是否允許iFrame。因為最初的彈出是通過用戶事件觸發的,沒有被瀏覽器阻止。為了強制重載,在CSS注入間彈出一個虛擬窗口,如下:
但由于CSRF是針對客戶端的攻擊,因此如果能想出一種不需要服務器的方法,那么就可以節省大量的開銷和簡化操作。為了接收客戶端加載資源,可以利用Service Workers來攔截和讀取請求數據。Service Workers目前只適用于同源請求,在演示中受害者和攻擊者頁面已處于同一源上。
不久后,chrome很可能會合并這個實驗性的功能,允許Service Workers攔截跨域請求。這樣,就可以確保在客戶端的攻擊100%的執行,并強制用戶在10秒內點擊鏈接執行CSRF攻擊,演示如下:
三、Demo
如上所述,因為不想運行一個web服務器,所以使用service workers攔截和模擬服務器端組件。目前,該演示只適用于Chrome瀏覽器。首先創建了一個易受攻擊的目標,它存在一個基于DOM的CSS注入漏洞,并在頁面放置了一個敏感token。再對腳本標簽添加了一些保護措施,對左尖括號和右尖括號進行了編碼。
接下來將強制加載受害者的CSS,并且使用上述方法,可一次竊取(猜解)一個敏感字符。在接收端,定義一個攔截請求的service worker,并通過post-message將它們發送回域,然后將token存儲在本地存儲中以供后續使用。你也可以想象一個后端Web服務器,通過Web套接字或輪詢將CSRF token回發給攻擊者域。
如果你的瀏覽器支持的話,只需點擊打開頁面任意位置,你將看到CSRF token將逐一被猜解出來。
四、結束語
反射型CSS注入實際上比存儲型CSS注入更致命,因為存儲型CSS注入需要一個服務器在受害者渲染之前來更新CSS。一段時間以來,CSS注入在嚴重程度上來回變化。過去IE瀏覽器是允許用戶在CSS中執行Javascript代碼的。這個演示也從某種程度上表明了CSS注入,以及渲染不受信任的CSS仍會導致嚴重的安全問題。所以在設計軟件一定要測試,才能及時發現和修復各種漏洞。
讓我們看看如下這個web應用示例:
<html> <meta http?equiv="Content?Security?Policy" content="script?src 'nonce?...' 'unsafe?eval'"> <div id="template_target"></div> <script type="application/template" id="template"> Hello World! 1 + 1 = {{ 1 + 1 }} </script> Your search is <?php echo $_GET['q']; ?> <script nonce="..."> let template = document.getElementById('template'); template_target.innerHTML = template.innerText.replace(/{{(.?)}}/g,eval) </script> </html>
以上這段簡單的HTML代碼可能反映了現在滲透測試人員經常碰到的模板化Web應用。某些模板內容存儲在Web頁面中,然后再轉換為HTML代碼的一部分。上段代碼中含有id為template的HTML元素內容先被讀取,然后再執行{{}}括號內的內容,最后在某個單獨HTML元素中呈現出來。
Hello World! 1 + 1 = 2 Your search is ...........
其次,這段代碼應用程序會在頁面上打印URL中的參數值。這顯而易見是一個XSS漏洞,但由于CSP(內容安全策略)的存在,攻擊者并不能直接執行javascript。雖然直接運行javascript的路被堵死,但是我們可以找到其他繞過方法。
乍一看,貌似eval函數是一個可以利用的點,我們或許可以直接插入某些特制代碼,讓eval函數去執行。
為了實現這點,我們必須插入HTML元素中id為template的代碼。但在我們插入語句的前面已有id為template的HTML元素,而document.getElementById('template')只會去獲取第一個HTML元素,并不是我們所輸入的語句。
此刻,我們需要換個角度,看看瀏覽器是否能出現“意外”,以前就出現過很多瀏覽器的異常解析所導致的XSS攻擊。我把所有能使用的tag都收集起來進行測試,看看是否有驚喜。測試代碼如下:
<div id="template">First Tag</div> {% for tag in tag_list %} <{{tag}} id="template">{{tag}}</{{tag}}> {% endfor %} <script>console.log(document.getElementById('template'));</script>
當程序運行完畢時,我得到一個奇怪的結果:當輪到<html>時,頁面結構似乎發生了大變,此時已不再是<div>排在前面。讓我們看下當插入<html id="template">時的變化:
此時<html>已排在文檔頂部(在我所測試的所有瀏覽器中都是如此!),現在getElementById('template')將獲取<html>中的惡意數據,而不是<div>的內容。
只需簡單的?q=<html id="template">{{ alert("xss") }}</html>就可進行攻擊
最終,由于瀏覽器這個“莫名其妙”的特性,我們繞過了CSP成功進行了XSS攻擊!
本文由白帽匯整理并翻譯,不代表白帽匯任何觀點和立場
來源:https://nosec.org/home/detail/2860.html
原文:https://pagedout.institute/download/PagedOut_001_beta1.pdf(該PDF文檔的第62頁
白帽匯從事信息安全,專注于安全大數據、企業威脅情報。
公司產品:FOFA-網絡空間安全搜索引擎、FOEYE-網絡空間檢索系統、NOSEC-安全訊息平臺。
為您提供:網絡空間測繪、企業資產收集、企業威脅情報、應急響應服務。
京東SRC(Security Response Center)收錄大量外部白帽子提交的sql注入漏洞,漏洞發生的原因多為sql語句拼接和Mybatis使用不當導致。
mysql5.0以上版本中存在一個重要的系統數據庫information_schema,通過此數據庫可訪問mysql中存在的數據庫名、表名、字段名等元數據。information_schema中有三個表成為了sql注入構造的關鍵。
SQL注入常用SQL函數
// sqli vuln code
Statement statement = con.createStatement();
String sql = "select * from users where username = '" + username + "'";
logger.info(sql);
ResultSet rs = statement.executeQuery(sql);
// fix code 如果要使用原始jdbc,請采用預編譯執行
String sql = "select * from users where username = ?";
PreparedStatement st = con.prepareStatement(sql);
使用未預編譯原始jdbc作為demo,注意此demo中sql語句參數采用單引號閉合。
對于字符類型注入,通常先嘗試單引號,判斷單引號是否被拼接到SQL語句中。推薦使用瀏覽器擴展harkbar作為手工測試工具。https://chrome.google.com/webstore/detail/hackbar/ginpbkfigcoaokgflihfhhmglmbchinc
正常頁面應該顯示如下:
admin后加單引號導致無信息回顯,原因是后端sql執行報錯,說明引號被拼接至SQL語句中
select * from users where username = 'admin' #正常sql
select * from users where username = 'admin'' #admin'被帶入sql執行導致報錯無法顯示信息
mysql中使用order by 進行排序,不僅可以是字段名也可以是字段序號。所以可以用來判斷表中字段數,order by 超過字段個數的數字就會報錯。
判斷字段數
當order by 超過4時會報錯,所以此表共四個字段。
后端所執行的sql語句
select * from users where username = 'admin' order by 1-- '
此處我們將原本username的值admin替換為admin’ order by 1 —+,其中admin后的單引號用于閉合原本sql語句中的前引號,—+用于注釋sql語句中的后引號。—后的+號主要作用是提供一個空格,sql語句單行注釋后需有空格,+會被解碼為空格。
主要用于定位后端sql字段在前端顯示的位置,采用聯合查詢的方式確定。注意聯合查詢前后字段需一致,這也就是我們為什么做第二步的原因。
通過下圖可知,后端查詢并回顯的字段位置為2,3位。
聯合查詢后的字段可以隨意,本次采用的是數字1到4直觀方便。
group_concat()函數用于將查詢結果拼接為字符串。
sqlmap兼容python2和python3,可以自動化檢測各類注入和幾乎所有數據庫類型。
-u 可能存在注入的url鏈接
-r讀取http數據包
--data 指定post數據
--cookie 指定cookie
--headers 指定http頭 如采用token認證的情況下
--threads 指定線程數
--dbms 指定后端的數據庫
--os 指定后端的操作系統類型
--current-user 當前用戶
--users 所有用戶
--is-dba 是否是dba
--sql-shell 交互式的sqlshell
-p指定可能存在注入點的參數
--dbs 窮舉系統存在的數據庫
-D指定數據庫
--tables 窮舉存在的表
-T指定表
--column 窮舉字段
-C指定字段
--dump dump數據
直接檢測
其中—cookie用于指定cookie,—batch 自動化執行,—dbms指定數據庫類型
檢測結果
讀取系統中存在數據庫
—dbs讀取當前用戶下的數據庫
讀取指定庫下的表
-D java_sec_code —tables
dump users表數據
-D java_sec_code -T users —dump
//采用#不會導致sql注入,mybatis會使用預編譯執行
@Select("select * from users where username = #{username}")
User findByUserName(@Param("username") String username);
//采用$作為入參可導致sql注入
@Select("select * from users where username = '${username}'")
List<User> findByUserNameVuln01(@Param("username") String username);
//錯誤寫法
<select id="findByUserNameVuln02" parameterType="String" resultMap="User">
select * from users where username like '%${_parameter}%'
</select>
//正確寫法
<select id="findByUserNameVuln02" parameterType="String" resultMap="User">
select * from users where username like concat(‘%’,#{_parameter}, ‘%’)
</select>
order by 后若使用#{}會導致報錯,因為#{}默認添加引號會導致找不到字段從而報錯。
//錯誤寫法
<select id="findByUserNameVuln03" parameterType="String" resultMap="User">
select * from users
<if test="order != null">
order by ${order} asc
</if>
</select>
//正確寫法 id指字段id 此表字段共四個 所以id為1-4
<select id="OrderByUsername" resultMap="User">
select * from users order by id asc limit 1
</select>
slqmap手冊:https://octobug.gitbooks.io/sqlmap-wiki-zhcn/content/Users-manual/Introduction.html
sql注入詳解:http://sqlwiki.radare.cn/#/
*請認真填寫需求信息,我們會在24小時內與您取得聯系。