0x00、XXE漏洞
XXE漏洞全稱XML External Entity Injection 即xml外部實體注入漏洞,XXE漏洞發生在應用程序解析XML輸入時,沒有禁止外部實體的加載,導致可加載惡意外部文件和代碼,造成任意文件讀取、命令執行、內網端口掃描、攻擊內網網站、發起Dos攻擊等危害。
XXE漏洞觸發的點往往是可以上傳xml文件的位置,沒有對上傳的xml文件進行過濾,導致可上傳惡意xml文件。
0x01、XML基礎知識
要了xxe漏洞,那么一定得先弄明白基礎知識,了解xml文檔的基礎組成
XML 指可擴展標記語言(Extensible Markup Language)
XML 被設計用來傳輸和存儲數據。
HTML 被設計用來顯示數據
XML把數據從HTML分離,XML是獨立於軟件和硬件的信息傳輸工具。
XML語言沒有預定義的標簽,允許作者定義自己的標簽和自己的文檔結構
XML的語法規則:
- XML 文檔必須有一個根元素
- XML 元素都必須有一個關閉標簽
- XML 標簽對大小敏感
- XML 元素必須被正確的嵌套
- XML 屬性值必須加引導
<?xml version="1.0" encoding="UTF-8"?> <!--XML 聲明-->
<girl age="18"> <!--自定的根元素girl;age屬性需要加引導-->
<hair>長頭發</hair> <!--自定義的4個子元素,即girl對象的屬性-->
<eye>大眼睛</eye>
<face>可愛的臉龐</face>
<summary>可愛美麗的女孩</summary>
</girl> <!--根元素的閉合-->
實體引用
在 XML 中,一些字符擁有特殊的意義。
如果您把字符 "<" 放在 XML 元素中,會發生錯誤,這是因為解析器會把它當作新元素的開始。
這樣會產生 XML 錯誤:
<message>if salary < 1000 then</message>
為了避免這個錯誤,請用實體引用來代替 "<" 字符:
<message>if salary < 1000 then</message>
在 XML 中,有 5 個預定義的實體引用:
| < | < | 小於號 |
| > | > | 大於號 |
| & | & | 和號 |
| ' | ' | 單引號 |
| " | " | 引號 |
0x02、DTD (Document Type Definition)
DTD(文檔類型定義)的作用是定義XML文檔的合法構建模塊
DTD 可被成行地聲明於 XML 文檔中,也可作為一個外部引用。
<!--XML聲明--> <?xml version="1.0"?> <!--文檔類型定義--> <!DOCTYPE note [ <!--定義此文檔是 note 類型的文檔--> <!ELEMENT note (to,from,heading,body)> <!--定義note元素有四個元素--> <!ELEMENT to (#PCDATA)> <!--定義to元素為”#PCDATA”類型--> <!ELEMENT from (#PCDATA)> <!--定義from元素為”#PCDATA”類型--> <!ELEMENT head (#PCDATA)> <!--定義head元素為”#PCDATA”類型--> <!ELEMENT body (#PCDATA)> <!--定義body元素為”#PCDATA”類型--> ]]]> <!--文檔元素--> <note> <to>Dave</to> <from>Tom</from> <head>Reminder</head> <body>You are a good man</body> </note>
上述XML代碼基本分為三個部分:
第一部分是XML的聲明;
第二部分是XML的DTD文檔類型定義
第三部分是XML語句
而外部實體攻擊主要利用DTD的外部實體來進行注入的。
DTD有兩種構建方式,分別為內部DTD聲明和外部DTD聲明
內部DTD聲明:
<!DOCTYPE 根元素 [元素聲明]>
實例:如上述代碼
外部DTD聲明:
<!DOCTYPE 根元素 SYSTEM "文件名">
實例:
<?xml version="1.0"?> <!DOCTYPE root-element SYSTEM "test.dtd"> <note> <to>Y</to> <from>K</from> <head>J</head> <body>ESHLkangi</body> </note>
test.dtd
<!ELEMENT to (#PCDATA)><!--定義to元素為”#PCDATA”類型--> <!ELEMENT from (#PCDATA)><!--定義from元素為”#PCDATA”類型--> <!ELEMENT head (#PCDATA)><!--定義head元素為”#PCDATA”類型--> <!ELEMENT body (#PCDATA)><!--定義body元素為”#PCDATA”類型-->
PCDATA的意思是被解析的字符數據。PCDATA是會被解析器解析的文本。這些文本將被解析器檢查實體以及標記。文本中的標簽會被當作標記來處理,而實體會被展開。
CDATA意思是字符數據,CDATA 是不會被解析器解析的文本,在這些文本中的標簽不會被當作標記來對待,其中的實體也不會被展開。
DTD實體同樣有兩種構建方式,分別為內部實體聲明和外部實體聲明。
內部實體聲明:
<!ENTITY entity-name "entity-value">
實例:
<?xml version="1.0"> <!DOCTYPE note [ <!ELEMENT note(name)> <!ENTITY hacker "ESHLkangi"> ]> <note> <name>&hacker;</name> </note>
外部實體聲明:
<!ENTITY entity-name SYSTEM "URL/URL">
默認協議

PHP擴展協議

實例:
<?xml cersion="1.0"> <!DOCTYPE hack [ <!ENTITY xxe SYSTEM "file:///etc/password"> ]> <hack>&xxe;</hack>
上述代碼中,XML的外部實體“xxe”被賦予的值為:file:///etc/passwd
當解析xml文檔是,xxe會被替換為file:///ect/passwd的內容。
參數實體+外部實體:
<?xml version="1.0" encoiding="utf-8"> <!DOCTYPE hack [ <!ENTITY % name SYSTEM "file:///etc/passwd"> %name; ]>
"%name"(參數實體)實在DTD中被引用,而"&name;"是在xml文檔中被引用的。
XXE漏洞攻擊主要是利用了DTD引用外部實體導致的漏洞。
0x03、攻擊思路
1、引用外部實體遠程文件讀取
2、Blind XXE
3、Dos
攻擊實例:看下篇
