生产事件实录-浅谈XXE漏洞

专栏链接地址

问题起源

微信商户平台收到了微信的安全通知,如下所示,漏洞详情则是XEE漏洞。所以就去了解了XEE

在这里插入图片描述
早在2018年7月初有国外白帽子就发现了这个漏洞,作为一线技术人员竟然全然不知(自我检讨ing…)
在这里插入图片描述

什么是XEE漏洞?

XXE是指基于xml的,xml外部实体攻击

下面看一段简单的xml文档代码,其中‘username’,‘password’,'address’被称为xml的元素

<?xml version="1..0"?>
<student>
	<useername>zhangsan</username>
	<password>123456</password>
	<address>ShenZhen</address>
</student>

有些XML文档包含system标识符定义的“实体”,这些XML文档会在DOCTYPE头部标签中呈现。这些定义的’实体’能够访问本地或者远程的内容。比如,下面的XML文档样例就包含了XML ‘实体’。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Anything[
<!ENTITY myentity SYSTEM="file:///etc/passwd"]>

<xxx>&myentity</xxx>

上面这段XML代码有XEE漏洞,其中entityex就是外部实体,我们可以通过这个参数来访问file://etc/passwd的内容,因为我们web服务器在解析xml文档的过程中,实体entityes的值会直接被替换成file://etc/passwd。关键字’SYSTEM’会告诉XML解析器,'entityes’的实体值将会从后面的URL获取,也就是我们所替换的file:///etc/passwd文件,其实这个过程就是XML实体攻击过程。

解决方式

非专业白帽就不演示攻击过程了,但是要时刻谨记,XML解析一定要禁用实体解析

造成问题的原因是因为服务端需要去解析xml文件,所以只需要在xml解析代码中禁用XML实体解析如下图所示

/**
     * XML格式字符串转换为Map
     *
     * @param strXML XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        try {
            Map<String, String> data = new HashMap<String, String>();
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
            documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
            documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
            documentBuilderFactory.setXIncludeAware(false);
            documentBuilderFactory.setExpandEntityReferences(false);

            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
            throw ex;
        }

    }
发布了86 篇原创文章 · 获赞 110 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/libra_ts/article/details/89395134