代碼注入(Code injection):
1.OWASP將其定義為在客戶端提交的代碼在服務器端接收后當做動態代碼或嵌入文件處理。
2.Wikipedia將其定義為客戶端所提交的數據未經檢查就讓Web服務器去執行,這個范圍比OWASP定義的代碼注入范圍要廣闊得很多。
XML實體注入漏洞:
XXE漏洞全稱XML External Entity Injection即xml外部實體注入漏洞,XXE漏洞發生在應用程序解析XML輸入時,沒有禁止外部實體的加載,導致可加載惡意外部文件,造成文件讀取、命令執行、內網端口掃描、攻擊內網網站、發起dos攻擊等危害。xxe漏洞觸發的點往往是可以上傳xml文件的位置,沒有對上傳的xml文件進行過濾,導致可上傳惡意xml文件。
XXE漏洞是針對使用XML交互的Web應用程序的攻擊方法,在XXE漏洞的基礎上,發展出了Blind XXE漏洞。目前來看,XML文件作為配置文件(Spring、Struts2等)、文檔結構說明文件(PDF、RSS等)、圖片格式文件(SVG header)應用比較廣泛,此外,網上有一些在線XML格式化工具也存在過問題。
1、本質:
XML是一種數據組織存儲的數據結構方式,安全的XML在用戶輸入生成新的數據時候應該只能允許用戶接受的數據,需要過濾掉一些可以改變XML標簽也就是說改變XML結構插入新功能(例如新的賬戶信息,等於添加了賬戶)的特殊輸入,如果沒有過濾,則可以導致XML注入攻擊。
XML格式說明:
XML用於標記電子文件使其具有結構性的標記語言,可以用來標記數據、定義數據類型,是一種允許用戶對自己的標記語言進行定義的源語言。XML文檔結構包括XML聲明、DTD文檔類型定義(可選)、文檔元素。
DTD(文檔類型定義)的作用是定義XML文檔的合法構建模塊。DTD可以在XML文檔內聲明,也可以外部引用。
(1)內部聲明DTD
<!DOCTYPE 根元素 [元素聲明]>
(2)引用外部DTD
<!DOCTYPE 根元素 SYSTEM "文件名">
或<!DOCTYPE 根元素 PUBLIC "public_ID" "文件名">
DTD實體用於定義引用普通文本或特殊字符的快捷方式的變量,可以內部聲明或外部引用。
(3)DTD的實體
DTD(文檔類型定義)的作用是定義XML文檔的合法構建模塊。DTD可以在XML文檔內聲明,也可以外部引用。
外部實體是值XML處理器必須解析的數據。它對於在多個文檔之間創建共享的公共引用很用用。對外部實體進行的任何更改將在包含對其的引用的文檔中自動更新。即XML使用外部實體將信息或“內容”將自動提取到XML文檔的正文中。為此,我們需要在XML文檔內部聲明一個外部實體。
內部聲明實體
DTD實體是用於定義引用普通文本或特殊字符的快捷方式的變量,可以內部聲明或外部引用。一個內部實體聲明 <!ENTITY 實體名稱 “實體的值">
注釋:一個實體由三部分構成:一個和號(&),一個實體名稱,以及一個分號(;)。
引用外部實體
一個外部實體聲明<!ENTITY 實體名稱 SYSTEM "URI/URL“>或者<!ENTITY 實體名稱 PUBLIC "public_ID" "URI">
外部實體類型有:
(4)CDATA
CDATA指的是不應由XML解析器解析的文本數據(Unparsed Character Data)。在XML元素中,"<"(新元素的開始)和“&”(字符實體的開始)是非法的。某些文本,比如javascript代碼,包含大量“<"或”&“字符。為了避免錯誤,可以將腳本代碼定義為CDATA。CDATA部分中的所有內容都會被解析器忽略。CDATA部分由"<![CDATA["開始,由”]]>"結束。
XML的實體
XML中的實體分為以下五種:字符實體,命名實體,外部實體,參數實體,內部實體。普通實體和參數實體都分為內部實體和外部實體兩種,外部實體定義需要加上SYSTEM關鍵字,其內容是URL所指向的外部文件實際的內容。如果不加SYSTEM關鍵字,則為內部實體,表示實體指代內容為字符串。
(1)字符實體
指用十進制格式(&#aaa;)或十六進制格式(પ;)來指定任意Unicode字符。對於XML解析器而言,字符實體與直接輸入指定字符的效果完全相同。
(2)命名實體
也稱為內部實體,在DTD或內部子集(即文檔中<!DOCTYPE>語句中的一部分)中聲明,在文檔中用作引用。在XML文檔解析過程中,實體引用將由它的表示替代。
圖上 POC可以用作xxe+ssrf
(3)外部實體(XXE主要是利用了DTD引用外部實體導致的漏洞)
外部實體表示外部文件的內容,用SYSTEM關鍵詞表示。
<!ENTITY test SYSTEM "1.xml">
有些XML文檔包含system標識符定義的“實體”,這些文檔會在DOCTYPE頭部標簽中呈現。這些定義的‘實體’能夠訪問本地或者遠程的內容。比如,下面的XML文檔樣例就包含了XML‘實體’。
在上面的代碼中,XML外部實體‘entityex’被賦予的值為:file://etc/passwd。在解析XML文檔的過程中,實體'entityex'的值會被替換為URI(file:///etc/passwd)內容值(也就是passwd文件的內容)。關鍵字‘SYSTEM’會告訴XML解析器,‘entityex’實體的值將從其后的URI中讀取,並把讀取的內容替換entityex出現的地方。
假如SYSTEM后面的內容可以被用戶控制,那么用戶就可以隨意替換為其他內容,從而讀取服務器本地文件(file:///etc/passwd)或者遠程文件(http://www.baidu.com/abc.txt)
(4)參數實體
參數實體只用於DTD和文檔的內部子集中,XML的規范定義中,只有在DTD中才能引用參數實體,參數實體的聲明和引用都是以百分號%。並且參數實體的引用在DTD是理解解析的,替換文本將變成DTD的一部分。該類型的實體“%”字符(或十六進制編碼的%),並且僅在經過解析和驗證后才用於替換DTD中的文本或其他內容:
<!ENTITY % 實體名稱 “實體的值”>
或者<!ENTITY % 實體名稱 SYSTEM "URI">
參數實體只能在DTD文件中被引用,其他實體在XML文檔內引用。即下面實例,實體參數在DOCTYPE內,其他實體在外
參數實體在DTD中解析優先級高於xml內部實體,實體相當於變量“file:///etc/passwd"賦值給name
(5)內部實體
(6)命名實體+外部實體寫法
這種命名實體調用外部實體,發現evil.xml中不能定義實體,否則解析不了。
(7)第一種命名實體+外部實體+參數實體寫法
(8)第二種命名實體+外部實體+參數實體寫法
調用過程和第一種方法類似
XXE的危害:
1、讀取任意文件
2、執行系統命令
3、探測內網端口
4、攻擊內網網站
5、拒絕服務
POC
XXE漏洞類型:
1.基礎的XXE注入——外部實體注入本地DTD
2.基於盲注的XXE注入——XML解析器在響應中不顯示任何錯誤
(1)Blind XXE用途
對於傳統的XXE來說,要求有一點,就是攻擊者只有在服務器有回顯或者報錯的基礎上才能使用XXE漏洞來讀取服務器端文件。例如:
提交請求:
服務器在這個節點中返回etc/passwd的文件內容:
<username>root:1:3......</username>
如果服務器沒有回顯,只能使用Blind XXE漏洞來構建一條帶外信道提取數據。
如果目標服務器沒有回顯,就只能用Blind XXE了。原理就是帶着獲取的文件源碼以get參數或其他形式去訪問我們的服務器,然后再日志里就可以找到我們要獲取的內容了。
Blind XXE主要使用了DTD約束中的參數實體和內部實體。參數實體是一種只能再DTD中定義和使用的實體,一般引用時使用%作為前綴。而內部實體是指在一個實體中定義的另一個實體,也就是嵌套定義。
原理說明:
對於傳統的XXE來說,要求在服務器有回顯或者報錯的基礎上才能使用XXE漏洞來讀取服務器端文件,例如上述方式一。如果服務器沒有回顯,只能使用Blind XXE漏洞來構建一條帶外信道提取數據(Out-Of-Band)。但直接在內部實體定義中引用另一個實體的這種方法行不通。
最簡單的無非是通過參數實體引用,發送一個http請求到我們的服務器,然后觀察我們服務的日志,如果在服務日志上能接收到則說明存在漏洞。
但是這樣做行不通,原因是不能在實體定義中引用參數實體,即有些解釋器不允許在內層實體中使用外部連接,無論內層是一般實體還是參數實體。
解決方案:將嵌套的實體聲明放入到一個外部文件中,這里一般是放在攻擊者的服務器上,這樣做可以規避錯誤。
思路:
(1)客戶端發送payload 1給web服務器
(2)web服務器向vps獲取惡意DTD,並執行文件讀取payload2
(3)web服務器帶着回顯結果訪問VPS上特定的FTP或者HTTP
(4)通過VPS獲得回顯(nc監聽端口)
3.基於錯誤的XXE注入——成功解析之后,XML解析器始終顯示SAME響應。(即”您的消息已被接收“),因此,我們可能希望解析器將文件的內容”打印“到錯誤響應中。
判斷是否存在XXE漏洞:
測試:
1.任意文件讀取
任意讀取的代碼:
2)無回顯的情況:可以看第一種命名實體+外部實體+參數實體寫法和第二種命名實體+外部實體+參數實體寫法
訪問http://localhost/test.php,這就是模擬攻擊者構造XXE請求,然后存在漏洞的服務器會讀出file的內容(c:/1.txt),通過帶外通道發送給攻擊者服務器上的1.php,1.php做的事情就是把讀取的數據保存到本地的1.txt中,完成Blind XXE攻擊。可以從apache的日志中看到。
另外,數據不回顯就沒有問題了嗎?不,可以把數據發送到遠程服務器。
修復漏洞:
Xpath注入:
本質:xpath注入是類似SQL的一種從XML結構中搜索節點數據的語言(DSL),其注入方式就是構造完整的可執行的DSL,本質與SQL注入一樣。
Xpath即為XML路徑語言,Xpaht基於XML的樹形結構,提供在數據結構樹中找尋節點的能力。簡單的說,Xpath就是選取XML節點的一門語言。
如果程序沒有驗證用戶查詢輸入,就會發生Xpath注入,攻擊者可以提交惡意的請求修改查詢語句,導致:事物邏輯和認證繞過,獲取后端XMl數據庫內容。
不像傳遞的關系型數據庫,可以對數據庫、表、行或者列執行細粒度的訪問控制,XML沒有用戶或者權限的概念。這意味着整個數據庫都可以被用戶讀取,在應用中屬於很嚴重的安全漏洞。
防御方法:
JSON注入:
CRLF注入:
CRLF是“回車+換行”(\r\n)的簡稱。在HTTP協議中,HTTP Header與HTTP Body是用兩個CRLF分隔的,瀏覽器就是根據這兩個CRLF來取出HTTP內容並顯示出來。所有,一旦我們能夠控制HTTP消息頭中的字符,注入一些惡意的換行,這樣我們就能注入一些會話Cookie或者HTML代碼,所有CRLF Injection又叫HTTP Response Splitting,簡稱HRS。
1、本質
也叫CRLF注入攻擊。CR、LF分別對應回車(%0d)、換行(%0a)字符。HTTP頭由很多被CRLF組合分離的行構成,每行的結構都是“鍵:值”。如果用戶輸入的值部分注入了CRLF字符,它就有可能改變HTTP報頭結構。
2、防御
限制用戶輸入的CR和LF,或者對CR和LF字符正確編碼后再輸出
過濾\r、\n之類的換行符,避免輸入的數據污染到其他HTTP頭。
HPP(參數污染):
HPP參數污染不是一個漏洞,而是服務器端根據配置的不同所顯示出的不同特性。如果網站存在SQL注入或者是XSS等漏洞,並且有響相應的防護措施,那么HTTP參數污染可能會幫助攻擊者繞過這些防御措施。
HPP參數污染,簡單地講就是給一個參數賦上兩個或兩個以上的值。現行的HTTP標准沒有提及再遇到多個輸入值給相同的參數賦值時應該怎樣處理。因此web程序組件在遇到這類問題時采取的方法也不完全相同。
防御: