1. 程式人生 > >xxe漏洞的學習與利用總結

xxe漏洞的學習與利用總結

前言

對於xxe漏洞的認識一直都不是很清楚,而在我為期不長的挖洞生涯中也沒有遇到過,所以就想著總結一下,撰寫此文以作為記錄,加深自己對xxe漏洞的認識。

xml基礎知識

要了解xxe漏洞,那麼一定得先明白基礎知識,瞭解xml文件的基礎組成。

XML用於標記電子檔案使其具有結構性的標記語言,可以用來標記資料、定義資料型別,是一種允許使用者對自己的標記語言進行定義的源語言。XML文件結構包括XML宣告、DTD文件型別定義(可選)、文件元素

xml文件的構建模組

所有的 XML 文件(以及 HTML 文件)均由以下簡單的構建模組構成:

  • 元素
  • 屬性
  • 實體
  • PCDATA
  • CDATA

下面是每個構建模組的簡要描述。
1,元素
元素是 XML 以及 HTML 文件的主要構建模組,元素可包含文字、其他元素或者是空的。
例項:

<body>body text in between</body>
<message>some message in between</message>

空的 HTML 元素的例子是 "hr"、"br" 以及 "img"。

2,屬性
屬性可提供有關元素的額外資訊
例項:

<img src="computer.gif" />

3,實體
實體是用來定義普通文字的變數。實體引用是對實體的引用。

4,PCDATA
PCDATA 的意思是被解析的字元資料(parsed character data)。
PCDATA 是會被解析器解析的文字。這些文字將被解析器檢查實體以及標記。

5,CDATA
CDATA 的意思是字元資料(character data)。
CDATA 是不會被解析器解析的文字。

DTD(文件型別定義)

DTD(文件型別定義)的作用是定義 XML 文件的合法構建模組。

DTD 可以在 XML 文件內宣告,也可以外部引用。

1,內部宣告:<!DOCTYPE 根元素 [元素宣告]> ex: <!DOCTYOE test any>
完整例項:

<?xml version="1.0"?>
<!DOCTYPE note [
  <!ELEMENT note (to,from,heading,body)>
  <!ELEMENT to      (#PCDATA)>
  <!ELEMENT from    (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body    (#PCDATA)>
]>
<note>
  <to>George</to>
  <from>John</from>
  <heading>Reminder</heading>
  <body>Don't forget the meeting!</body>
</note>

2,外部宣告(引用外部DTD):<!DOCTYPE 根元素 SYSTEM "檔名"> ex:<!DOCTYPE test SYSTEM 'http://www.test.com/evil.dtd'>
完整例項:

<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note> 

而note.dtd的內容為:

<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

DTD實體

DTD實體是用於定義引用普通文字或特殊字元的快捷方式的變數,可以內部宣告或外部引用。

實體又分為一般實體和引數實體
1,一般實體的宣告語法:<!ENTITY 實體名 "實體內容“>
引用實體的方式:&實體名;
2,引數實體只能在DTD中使用,引數實體的宣告格式: <!ENTITY % 實體名 "實體內容“>
引用實體的方式:%實體名;

1,內部實體宣告:<!ENTITY 實體名稱 "實體的值"> ex:<!ENTITY eviltest "eviltest">
完整例項:

<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright W3School.com.cn">
]>

<test>&writer;&copyright;</test>

2,外部實體宣告:<!ENTITY 實體名稱 SYSTEM "URI">
完整例項:

<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
]>
<author>&writer;&copyright;</author>

在瞭解了基礎知識後,下面開始瞭解xml外部實體注入引發的問題。

XXE的攻擊與危害(XML External Entity)

1,何為XXE?
答: xxe也就是xml外部實體注入。也就是上文中加粗的那一部分。

2,怎樣構建外部實體注入?
方式一:直接通過DTD外部實體宣告
XML內容

方式二:通過DTD文件引入外部DTD文件,再引入外部實體宣告
XML內容:

DTD檔案內容:

方式三:通過DTD外部實體宣告引入外部實體宣告
好像有點拗口,其實意思就是先寫一個外部實體宣告,然後引用的是在攻擊者伺服器上面的外部實體宣告
具體看例子,XML內容

dtd檔案內容:

3,支援的協議有哪些?
不同程式支援的協議如下圖:

其中php支援的協議會更多一些,但需要一定的擴充套件支援。

4,產生哪些危害?

XXE危害1:讀取任意檔案

該CASE是讀取/etc/passwd,有些XML解析庫支援列目錄,攻擊者通過列目錄、讀檔案,獲取帳號密碼後進一步攻擊,如讀取tomcat-users.xml得到帳號密碼後登入tomcat的manager部署webshell。

另外,資料不回顯就沒有問題了嗎?如下圖,

不,可以把資料傳送到遠端伺服器,

遠端evil.dtd檔案內容如下:

觸發XXE攻擊後,伺服器會把檔案內容傳送到攻擊者網站

XXE危害2:執行系統命令

該CASE是在安裝expect擴充套件的PHP環境裡執行系統命令,其他協議也有可能可以執行系統命令。

XXE危害3:探測內網埠

該CASE是探測192.168.1.1的80、81埠,通過返回的“Connection refused”可以知道該81埠是closed的,而80埠是open的。

XXE危害4:攻擊內網網站

該CASE是攻擊內網struts2網站,遠端執行系統命令。

如何防禦xxe攻擊

方案一、使用開發語言提供的禁用外部實體的方法

PHP:
libxml_disable_entity_loader(true);

JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

方案二、過濾使用者提交的XML資料
關鍵詞:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。

最後

通過本次對XXE的總結,認真瞭解了XML基礎知識,XXE的攻擊方式與及防禦方案。