简学-XXE攻击
前言
在学习 OWASP TOP 10 时,Xml外部拓展(XML External Entity(XXE))位于榜单第4名,因此上网搜索了想管的 XXE 原理、攻击手段、危害即防御手段等内容来学习,以下内容均来源于转载并做重新排版方便查看学习,转载地址在结尾放出。
XML 基础知识
- 要了解xxe漏洞,那么一定得先明白基础知识,了解xml文档的基础组成。
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素
XML 文档的构建模块
- 所有的 XML 文档(以及 HTML 文档)均由几种模块构成:
元素
、属性
、实体
、PCDATA
、CDATA
,下面是每个构建模块的简要描述:-
1、元素: 元素是 XML 以及 HTML 文档的主要构建模块,元素可包含文本、其他元素或者是空的。示例如下:
<body>body text in between</body> <message>some message in between</message>
空的 HTML 元素的例子:
<hr\>
、<br\>
以及<img\>
。 -
2、属性: 属性可提供有关元素的额外信息。示例如下:
<img src="computer.gif" /> <!--src 即为属性-->
-
3、实体: 实体是用来定义普通文本的变量。实体引用是对实体的引用。
-
4、PCDATA: PCDATA 的意思是被解析的字符数据(parsed character data)。PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
-
5、CDATA: CDATA 的意思是字符数据(character data)。CDATA 是不会被解析器解析的文本。
-
DTD (文档类型定义)
- DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。
- 1、内部声明:
<!DOCTYOE test any>
,示例如下:<?xml version="1.0"?> <!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
- 2、外部引用(引用外部DTD):
<!DOCTYPE test SYSTEM 'http://www.test.com/evil.dtd'>
,示例如下:
而 note.dtd 的内容为:<?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd"> <!-- 引用外部 dtd实体--> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
<!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>
- 1、内部声明:
DTD 实体
-
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。实体又分为一般实体和参数实体。
- 1、一般实体的声明语法:
引用实体的方式:&实体名;
- 2、参数实体只能在DTD中使用,参数实体的声明格式:
引用实体的方式:%实体名;
- 1、一般实体的声明语法:
-
1、内部实体声明:
<!ENTITY eviltest "eviltest">
,示例如下:<?xml version="1.0"?> <!DOCTYPE test [ <!ENTITY writer "Bill Gates"> <!ENTITY copyright "Copyright W3School.com.cn"> ]> <test>&writer;©right;</test>
-
2,外部实体声明: 示例如下:
<?xml version="1.0"?> <!DOCTYPE test [ <!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"> <!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"> ]> <author>&writer;©right;</author>
-
在了解了基础知识后,下面开始了解xml外部实体注入引发的问题。
XXE的攻击与危害(XML External Entity)
如何构建外部实体注入
- 方式一:直接通过DTD外部实体声明
XML 内容
- 方式二:通过DTD文档引入外部DTD文档,再引入外部实体声明
XML 内容:
DTD 文件内容:
- 方式三:通过DTD外部实体声明引入外部实体声明,先写一个外部实体神明,然后再引用攻击者服务器上的外部实体声明。
XML 内容:
DTD 文件内容:
外部实体支持的协议有哪些?
- 不同程序支持的协议如下图:
- 其中php支持的协议会更多一些,但需要一定的扩展支持。
XXE 攻击产生的危害
-
一、造成任意文件读取
- 该CASE是读取 /etc/passwd,有些 XML 解析库支持列目录,攻击者通过列目录、读文件,获取帐号密码后进一步攻击,如读取 tomcat-users.xml 得到帐号密码后登录 tomcat 的 manager 部署 webshell。
-
另外,数据不回显就没有问题了吗?如下图,
- 不,可以把数据发送到远程服务器,远程evil.dtd文件内容如下:
- 触发XXE攻击后,服务器会把文件内容发送到攻击者网站
- 不,可以把数据发送到远程服务器,远程evil.dtd文件内容如下:
-
二、执行系统命令
- 该CASE是在安装 expect 扩展的 PHP环境 里执行系统命令,其他协议也有可能可以执行系统命令。
-
三、探测内网端口
- 该CASE是探测192.168.1.1的80、81端口,通过返回的 “Connection refused” 可以知道该81端口是closed的,而80端口是open的。
-
四、攻击内网网站
- 该CASE是攻击内网struts2网站,远程执行系统命令。
如何防御 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))
- PHP:
- 二、过滤用户提交的XML数据
关键词:<!DOCTYPE
、<!ENTITY
、SYSTEM
、PUBLIC
以上内容均参考自:xxe漏洞的学习与利用总结