Open venusdrogon opened 6 years ago
https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#C.2FC.2B.2B
Introduction XML eXternal Entity injection (XXE), which is now part of the OWASP Top 10, is a type of attack against an application that parses XML input. This attack occurs when untrusted XML input containing a reference to an external entity is processed by a weakly configured XML parser. This attack may lead to the disclosure of confidential data, denial of service, Server Side Request Forgery (SSRF), port scanning from the perspective of the machine where the parser is located, and other system impacts. The following guide provides concise information to prevent this vulnerability. For more information on XXE, please visit XML External Entity (XXE) Processing.
http://www.freebuf.com/articles/web/126788.html
浅谈XXE攻击
0×00. 介绍 现在越来越多主要的web程序被发现和报告存在XXE(XML External Entity attack)漏洞,比如说facebook、paypal等等。 举个例子,我们扫一眼这些网站最近奖励的漏洞,充分证实了前面的说法。尽管XXE漏洞已经存在了很多年,但是它从来没有获得它应得的关注度。很多XML的解析器默认是含有XXE漏洞的,这意味着开发人员有责任确保这些程序不受此漏洞的影响。
本文主要讨论什么是XML外部实体,这些外部实体是如何被攻击的。
更新:最新微信XXE漏洞案例
0×01. 什么是XML外部实体? 如果你了解XML,你可以把XML理解为一个用来定义数据的东东。因此,两个采用不同技术的系统可以通过XML进行通信和交换数据。 比如,下图就是一个用来描述一个职工的XML文档样本,其中的’name’,'salary’,'address’ 被称为XML的元素。
Image
有些XML文档包含system标识符定义的“实体”,这些XML文档会在DOCTYPE头部标签中呈现。这些定义的’实体’能够访问本地或者远程的内容。比如,下面的XML文档样例就包含了XML ‘实体’。
Image
在上面的代码中, XML外部实体 ‘entityex’ 被赋予的值为:file://etc/passwd。在解析XML文档的过程中,实体’entityex’的值会被替换为URI(file://etc/passwd)内容值(也就是passwd文件的内容)。 关键字’SYSTEM’会告诉XML解析器,’entityex’实体的值将从其后的URI中读取。因此,XML实体被使用的次数越多,越有帮助。
0×02. 什么是XML外部实体攻击? 有了XML实体,关键字’SYSTEM’会令XML解析器从URI中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。 简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)。比如,下面的代码将获取系统上folder/file的内容并呈献给用户。
Image
0×03. 怎么甄别一个XML实体攻击漏洞? 最直接的回答就是: 甄别那些接受XML作为输入内容的端点。 但是有时候,这些端点可能并不是那么明显。在这种情况下,渗透测试人员就必须尝试不同的测试方式,比如修改HTTP的请求方法,修改Content-Type头部字段等等方法,然后看看应用程序的响应,看看程序是否解析了发送的内容,如果解析了,那么则可能有XXE攻击漏洞。
0×04. 如何确认XXE漏洞? 出于演示的目的,我们将用到一个Acunetix维护的demo站点,这个站点就是: http://testhtml5.vulnweb.com/。这个站点可用于测试Acunetix web扫描器的功能。 访问 http://testhtml5.vulnweb.com/ 站点,点击 ‘Login’下面的 ‘Forgot Password’ 链接。注意观察应用程序怎样使用XML传输数据,过程如下图所示:
请求:
Image
响应:
Image
观察上面的请求与响应,我们可以看到,应用程序正在解析XML内容,接受特定的输入,然后将其呈现给用户。为了测试验证XML解析器确实正在解析和执行我们自定义的XML内容,我们发送如下的请求
修改后的请求和响应:
Image
如上图所示,我们在上面的请求中定义了一个名为myentity、值为’testing’的实体。 响应报文清晰地展示了解析器已经解析了我们发送的XML实体,然后并将实体内容呈现出来了。 由此,我们可以确认,这个应用程序存在XXE漏洞。
0×05. 如何进行XXE攻击? Code 1:
1. To read files on same server:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ENTITY myentity SYSTEM "file:///location/anyfile" >]>
<abc>&myentity;</abc>
2. To crash the server / Cause denial of service:
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!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>
上面样例代码1中的XXE漏洞攻击就是著名的’billion laughs’(https://en.wikipedia.org/wiki/Billion_laughs)攻击,该攻击通过创建一项递归的 XML 定义,在内存中生成十亿个”Ha!”字符串,从而导致 DDoS 攻击。原理为:构造恶意的XML实体文件耗尽可用内存,因为许多XML解析器在解析XML文档时倾向于将它的整个结构保留在内存中,解析非常慢,造成了拒绝服务器攻击。除了这些,攻击者还可以读取服务器上的敏感数据,还能通过端口扫描,获取后端系统的开放端口。
影响: 此漏洞非常危险, 因为此漏洞会造成服务器上敏感数据的泄露,和潜在的服务器拒绝服务攻击。
补救措施: 上面讨论的主要问题就是XML解析器解析了用户发送的不可信数据。然而,要去校验DTD(document type definition)中SYSTEM标识符定义的数据,并不容易,也不大可能。大部分的XML解析器默认对于XXE攻击是脆弱的。因此,最好的解决办法就是配置XML处理器去使用本地静态的DTD,不允许XML中含有任何自己声明的DTD。
比如下面的Java代码,通过设置相应的属性值为false,XML外部实体攻击就能够被阻止。因此,可将外部实体、参数实体和内联DTD 都被设置为false,从而避免基于XXE漏洞的攻击。
以下是代码的第二段
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; // catching unsupported features
...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
String FEATURE = "http://xml.org/sax/features/external-general-entities";
dbf.setFeature(FEATURE, false);
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
FEATURE = "http://xml.org/sax/features/external-parameter-entities";
dbf.setFeature(FEATURE, false);
// Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl
FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
dbf.setFeature(FEATURE, true);
// remaining parser logic
...
catch (ParserConfigurationException e) {
// This should catch a failed setFeature feature
logger.info("ParserConfigurationException was thrown. The feature '" +
FEATURE +
"' is probably not supported by your XML processor.");
...
}
catch (SAXException e) {
// On Apache, this should be thrown when disallowing DOCTYPE
logger.warning("A DOCTYPE was passed into the XML document");
...
}
catch (IOException e) {
// XXE that points to a file that doesn't exist
logger.error("IOException occurred, XXE may still possible: " + e.getMessage());.. }
关于dom4j的微信XXE实体注入错误,使用DocumentHelper进行解析的漏洞修补
https://blog.csdn.net/wtbapi/article/details/80944244
SpringMVC中的XXE漏洞测试
关于dom4j的微信XXE实体注入错误,使用DocumentHelper
进行解析的漏洞修补
7月4日微信发来通知说存在XML实体注入漏洞,请修改。
由于自己的后台采取的dom4j的包,而且当时业务也只是对微信传入的xml进行解析处理,所以就直接使用DocumentHelper
的parseText
的方式进行解析,而没有使用SAXReader
的方式进行,在网上搜罗了很多资料,发现处理方式都无法使用。
最后自己在看了dom4j的源代码后,发现DocumentHelper
的parseText方法的实现,其实也是SAXReader
实现的,再查看SAXReader
源码,里面也有一个方式setFeature
,于是找到了处理方式
Document doc = null;
SAXReader reader = new SAXReader();
try{
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
}
catch (SAXException e) {
// On Apache, this should be thrown when disallowing DOCTYPE
wtbapi.Log.log("A DOCTYPE was passed into the XML document","GJ.java文件错误2");
}
String encoding = getEncoding(str);
InputSource source = new InputSource(new StringReader(str));
source.setEncoding(encoding);
doc = reader.read(source);
if (doc.getXMLEncoding() == null) {
doc.setXMLEncoding(encoding);
}
其中getEncoding(String)方法是DocumentHelper内部的方式
private static String getEncoding(String text)
{
String result = null;
String xml = text.trim();
if (xml.startsWith("<?xml"))
{
int end = xml.indexOf("?>");
String sub = xml.substring(0, end);
StringTokenizer tokens = new StringTokenizer(sub, " =\"'");
while (tokens.hasMoreTokens())
{
String token = tokens.nextToken();
if ("encoding".equals(token))
{
if (!tokens.hasMoreTokens()) {
break;
}
result = tokens.nextToken(); break;
}
}
}
return result;
}
有三个包要引入一下
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import java.util.StringTokenizer;
XMLInputFactory (a StAX parser) StAX parsers such as XMLInputFactory allow various properties and features to be set.
To protect a Java XMLInputFactory from XXE, do this:
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); // This disables DTDs entirely for that factory xmlInputFactory.setProperty("javax.xml.stream.isSupportingExternalEntities", false); // disable external entities
Note: The above defenses require Java 7 update 67, Java 8 update 20, or above, because the above countermeasures for DocumentBuilderFactory and SAXParserFactory are broken in earlier Java versions, per: CVE-2014-6517.
XML parsers should not be vulnerable to XXE attacks Vulnerability Blocker Main sources
cwe, owasp-a4 Available Since Apr 02, 2020 SonarAnalyzer (Java) Constant/issue: 15min Allowing access to external entities in XML Parsing could introduce vulnerabilities like SSRF or confidential file disclosures:
Example in XML document:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
Example in XSL document:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE root [ <!ENTITY content SYSTEM "file:/etc/passwd"> ]>
关于XML解析存在的安全问题指引
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5
微信支付商户,最近暴露的XML外部实体注入漏洞(
XML External Entity Injection
,简称 XXE),该安全问题是 由XML组件默认没有禁用外部实体引用导致 ,非微信支付系统存在漏洞。如果你在使用支付业务回调通知中,存在以下场景有使用XML解析的情况,请务必检查是否对进行了防范。
场景1:支付成功通知; 场景2:退款成功通知; 场景3:委托代扣签约、解约、扣款通知; 场景4:车主解约通知; 场景5:扫码支付模式一回调;
注:APP支付的用户端SDK不受影响,但APP支付成功回调通知里面要检查。
微信支付会通过这几个系统号码通知商户进行安全周知和询问是否授权平台进行安全扫描。 (0755)36560292 (0755)61954612 (0755)1954613 (0755)61954614 (0755)61954615 (0755)61954616 授权检测支付系统操作,不会影响商户系统安全。
检查及修复建议
1.如果您的后台系统使用了官方SDK,请更新SDK到最新版本 SDK的链接:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 2.如果您是有系统提供商,请联系提供商进行核查和升级修复; 3.如果您是自研系统,请联系技术部门按以下指引核查和修复:
XXE漏洞需要你在代码中进行相应的设置,不同语言设置的内容不同,下面提供了几种主流开发语言的设置指引:
【JAVA】
附录
更多开源库/语言版本的修复建议可参考: https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#C.2FC.2B.2B