Web渗透:XXE-XML外部实体漏洞

XML External Entity (XXE) 漏洞是一种注入攻击,利用不安全的XML解析器来执行各种恶意操作,如读取本地文件、执行远程代码、发起拒绝服务攻击等;此漏洞的根本原因在于XML标准允许在文档中定义外部实体,并在解析时进行解析和替换。在正式开始阐述XXE漏洞之前首先来说明一下XML语言。

什么是XML?

XML(可扩展标记语言,Extensible Markup Language)是一种标记语言,用于描述数据。XML非常适合数据存储和传输,因为它是纯文本,并且是可读的和可扩展的。XML广泛用于各种应用程序中,包括配置文件、文档格式和数据交换等。

XML示例

下面是一个简单的XML示例,描述了一本书的信息:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore><book category="children"><title lang="en">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book><book category="web"><title lang="en">Learning XML</title><author>Erik T. Ray</author><year>2003</year><price>39.95</price></book>
</bookstore>

在上述示例中:

  • 根元素是<bookstore>

  • bookstore元素包含两个子元素<book>

  • 每个<book>元素包含四个子元素:<title><author><year><price>

  • book元素还有一个属性category,用来标识书的类别。

  • title元素也有一个属性lang,用来标识语言。

XML的结构

XML文档由以下几部分组成:

  1. 声明(Prolog):可选部分,通常包含XML版本和编码声明。

    <?xml version="1.0" encoding="UTF-8"?>

  2. 根元素(Root Element):每个XML文档必须且只能有一个根元素,所有其他元素都是该根元素的子元素。

    <root>...
    </root>

    在上述示例中的根元素是<bookstore>;根元素是整个XML文档的顶级元素。

  3. 元素(Element):由开始标签和结束标签包围的内容,可以包含属性、文本、子元素等。

    <element attribute="value">Content</element>
  4. 属性(Attribute):位于元素的开始标签内,提供额外的信息。

    <element attribute="value">Content</element>
  5. 文本(Text):元素内的内容,可以是纯文本或混合内容(文本和子元素的组合)。

    <element>Text content</element>
  6. CDATA(Character Data):不需要解析的文本数据,用于包含不需要被解析的字符,如HTML代码。

    <![CDATA[<div>Some HTML content</div>]]>
XML解析

不同编程语言提供了丰富的库来解析和生成XML文档;此处我们以PHP语言为例子进行演示:

<?php
$xml = <<<XML
<bookstore><book category="children"><title lang="en">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book>
</bookstore>
XML;
​
$xmlObject = simplexml_load_string($xml);
echo $xmlObject->book->title . "\n";     // 输出:Harry Potter
?>
XML-DTD文档类型定义

DTD(Document Type Definition,文档类型定义)是XML的一种语法,用于定义XML文档的结构和规则;DTD可以在XML文档内部(内部DTD)或外部(外部DTD)定义,通过DTD,您可以指定XML文档中允许的元素、属性、嵌套关系、数据类型等,从而确保XML文档的有效性和一致性。

以下是一个简单的XML文档及其对应的DTD示例:

xml文档
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bookstore SYSTEM "bookstore.dtd">
<bookstore><book category="children"><title lang="en">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book><book category="web"><title lang="en">Learning XML</title><author>Erik T. Ray</author><year>2003</year><price>39.95</price></book>
</bookstore>

重点解析:

<!DOCTYPE bookstore SYSTEM "bookstore.dtd">

这行代码是XML文档中的一个声明,指定了该文档所使用的外部DTD(文档类型定义)。

<!DOCTYPE bookstore ... >:这部分声明了XML文档的文档类型定义(DTD);bookstore 是根元素的名称,表示此DTD描述了名为 bookstore 的根元素及其内容结构。

SYSTEM "bookstore.dtd":SYSTEM关键字表示DTD的位置是一个系统标识符;"bookstore.dtd" 是一个外部DTD文件的路径或URL,这个文件定义了XML文档的结构和规则。

外部DTD(bookstore.dtd)
<!ELEMENT bookstore (book+)> 
<!ELEMENT book (title, author, year, price)>
<!ATTLIST book category CDATA #REQUIRED>
<!ELEMENT title (#PCDATA)>
<!ATTLIST title lang CDATA #REQUIRED>
<!ELEMENT author (#PCDATA)>
<!ELEMENT year (#PCDATA)>
<!ELEMENT price (#PCDATA)>
DTD的组成部分:

①元素声明:用于定义元素的名称和内容模型;语法:<!ELEMENT 元素名 内容模型>

<!ELEMENT bookstore (book+)>
<!ELEMENT book (title, author, year, price)>

②属性声明:用于定义元素可以拥有的属性。语法:<!ATTLIST 元素名 属性名 属性类型 默认值>,示例:

<!ATTLIST book category CDATA #REQUIRED>
<!ATTLIST title lang CDATA #REQUIRED>

使用 <!DOCTYPE> 声明和外部DTD文件,可以确保XML文档符合预定义的结构和规则,帮助验证数据的有效性和一致性。这对于交换和处理结构化数据非常有用。

③实体声明(Entity Declarations):实体用于定义常用的文本片段,可以在XML文档中重复使用。语法:<!ENTITY 实体名 "实体值">;示例:

<!ENTITY example "This is an example entity">

在说完前置内容XML之后,这会儿我们就接着来说XXE漏洞;在此处我们也是拿pikachu靶场中的XXE相关靶场进行阐述说明:

1.打开页面后发现页面中出现一个输入框,该输入框是用来接收xml数据的一个接口,输入的内容只能是xml数据,若输入的内容为其他数据则此时我们会被质疑hh。

2.尝试输入一个简单定义义并使用了一个内部实体的XML文档;查看当前页面是否对输入的xml有回显:

<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe "This is an example entity">] >
<foo>&xxe;</foo>

<!DOCTYPE foo [...]>:声明文档类型定义(DTD)部分,指定该XML文档的根元素是foo

<!ENTITY xxe "This is an example entity">:定义了一个名为xxe的内部实体,其值为字符串 "This is an example entity"。

<foo>foo是根元素。

&xxe;:引用了之前定义的内部实体xxe

将xml数据输入后查看到页面效果:

此时可以判断当前页面对内部输入实体xml是有回显的,接着可以尝试输入xml内带外部实体的payload来确定当前页面是否支持外部实体。

<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///C:/Windows/System32/drivers/etc/hosts">] >
<foo>&xxe;</foo>

这个XML示例定义了一个外部实体 xxe,其内容是指向系统文件 C:/Windows/System32/drivers/etc/hosts。该外部实体在XML文档中被引用。如果一个不安全的XML解析器处理这个XML文档,它会尝试读取并插入 hosts 文件的内容。

<!DOCTYPE foo [...]>:声明文档类型定义(DTD)部分,指定该XML文档的根元素是foo

<!ENTITY xxe SYSTEM "file:///C:/Windows/System32/drivers/etc/hosts">:定义了一个名为xxe的外部实体,指向系统文件路径 C:/Windows/System32/drivers/etc/hosts

<foo>foo是根元素。

&xxe;:引用了之前定义的外部实体xxe

输入payload后的效果:页面显示服务器中的hosts文件

攻击成功;接着我们结合源代码进行XXE漏洞原理的剖析:

$html='';
//考虑到目前很多版本里面libxml的版本都>=2.9.0了,所以这里添加了LIBXML_NOENT参数开启了外部实体解析
if(isset($_POST['submit']) and $_POST['xml'] != null){
​$xml =$_POST['xml'];
//    $xml = $test;$data = @simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOENT);if($data){$html.="<pre>{$data}</pre>";}else{$html.="<p>XML声明、DTD文档类型定义、文档元素这些都搞懂了吗?</p>";}
}

这个PHP代码片段的主要功能是处理用户提交的XML数据,并在某些条件下将其显示为HTML。

①使用 simplexml_load_string 函数加载用户提交的XML字符串,创建一个 SimpleXMLElement 对象。

第三个参数 LIBXML_NOENT 启用了外部实体解析。这意味着如果XML包含外部实体引用,解析器将尝试解析和替换它们。

@符号抑制了任何可能出现的警告或错误。

②如果成功加载XML(即 $data 不为空),将XML数据转换为字符串并包裹在<pre>标签中追加到 $html 中。

如果加载失败,显示一条提示信息,告知用户可能需要理解XML声明、DTD文档类型定义和文档元素。

        此处,这个代码片段存在一个严重的安全漏洞——XXE(XML External Entity Injection),因为指定了 LIBXML_NOENT 参数,启用了外部实体解析,这个时候攻击者就可以提交包含外部实体的XML数据,从而读取服务器上的敏感文件或执行其他恶意操作。

LIBXML 是 PHP 中用于处理 XML 数据的库,基于 libxml2 库。LIBXML 解析器提供了多种常量和选项,用于配置和控制 XML 文档的解析行为。但是在 libxml2 版本 2.9.0 之前,外部实体解析是默认启用的,这意味着,如果没有特别禁用外部实体解析,XML 解析器将会解析和处理外部实体,从而产生XXE漏洞。

XXE漏洞防护
1. 禁用外部实体解析

在 PHP 中,可以通过 libxml_disable_entity_loader 函数来禁用外部实体解析,这是防止 XXE 攻击的主要方法之一:

libxml_disable_entity_loader(true);
$xmlObject = simplexml_load_string($xmlString);
libxml_disable_entity_loader(false);
2. 验证和清理输入

在处理 XML 输入之前,进行严格的验证和清理,确保输入数据是可信的。例如:

  • 使用白名单验证文件类型和内容。

  • 对文件内容进行正则表达式验证。

3. 配置 Web 应用防火墙 (WAF)

配置 WAF 以检测和阻止恶意的 XML 数据。WAF 可以识别和拦截常见的 XXE 攻击模式。

4. 关闭不必要的功能

在 XML 解析器中,关闭不必要的功能,如外部实体解析、DTD 验证等,以减少攻击面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/34463.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Navicat连接服务器MySQL

Navicat连接服务器MySQL 1. Navicat连接服务器MySQL2. 如何查看MySQL用户名和密码3. 修改MySQL登录密码4. 安装MySQL(Centos7)遇到错误和问题1. error 1045 (28000): access denied for user rootlocalhost (using password:yes) 1. Navicat连接服务器MySQL 选择数据库 直接使用…

jar包转exe封装软件并一键安装使用

目录 封装文档说明如有跨域问题在ems服务增加配置服务启动自动打开浏览器使用工具 Launch4j 把jar包打成exe执行文件现在还不能给用户用&#xff0c;因为缺少jre&#xff0c;后面整合资源会把jre一起打包使用inno setup合并资源&#xff0c;mysql之类的服务&#xff0c;最终打包…

数字化转型下的企业人力资源信息系统研究

随着数字化转型的加速&#xff0c;企业人力资源管理面临着全新的挑战和机遇。传统的人力资源信息系统&#xff08;HRIS&#xff09;在新时代的要求下必须进行深刻的革新和升级&#xff0c;以更好地支持企业的发展战略和员工的需求。 数据驱动的决策支持 在当今这个信息化迅猛发…

【系统架构设计师】四、嵌入式基础知识(软件|软件设计|硬件|式总线逻辑)

目录 一、嵌入式软件 1.1 嵌入式软件分类 1.2 板级支持包(BSP) 1.3 BootLoader 1.4 设备驱动程序 二、嵌入式软件设计 2.1 编码 2.2 交叉编译 2.3 交叉调试 三、嵌入式系统硬件的分类 3.1 根据用途分类 3.2 存储器分类 四、内&#xff08;外&#xff09;总线逻辑 …

uni-app系列:uni.navigateTo传值跳转

文章目录 1. 使用URL参数2. 使用页面栈注意事项&#xff1a;uni.navigateTo API 参数详细说明回调函数参数 在uni-app中&#xff0c;如果想要通过uni.navigateTo方法跳转到另一个页面并传递参数&#xff0c;可以使用页面路由的URL参数或者页面栈的方式来传递。但是&#xff0c;…

分享一个解决 EF 性能低的思路,通过 Python 访问心跳侦测 API 保持 EF 在线

前言 .NET FrameWork EF&#xff08;Entity Framework&#xff09;是一个很优秀的 ORM 框架&#xff0c;对于提高工作效率很有帮助&#xff0c;但由于底层原因&#xff0c;在程序启动时&#xff0c;EF 需要初始化和加载模型及其对应的数据库元数据等等&#xff0c;涉及到数据库…

20240507-招商证券 基于鳄鱼线的指数择时及轮动策略

动量震荡指标构造 动量震荡指标为交易者提供了获利的钥匙。动量震荡指标测算了5根价格柱相对于34根价格柱的动量变化。首先计算最近5根价格柱的最高价和最低价间的中点的简单移动平均值&#xff0c;即(最高价最低价)12的简单移动平均&#xff0c;将得出的值减去最近34根价格柱…

urfread学Linux|基本操作

切换界面 如何在VMware切换到命令行界面、切回图形化界面、释放鼠标和键盘 使用ctrlalt可以释放虚拟机对鼠标键盘的控制——就是你可以按这个键切出来到windows 使用ctrlaltF1可以切到图形化界面 使用ctrlaltF2可以切到命令行界面 文件夹相关操作 创建&#xff1a;mkdir文件…

Odoo OWL组件简介

Odoo OWL是Odoo框架中的一个前端开发工具&#xff0c;它被设计用来创建高效、可维护的用户界面组件。OWL利用现代JavaScript的特性&#xff0c;如组件、钩子&#xff08;Hooks&#xff09;和虚拟DOM&#xff0c;来提高开发效率和用户体验。OWL组件是构建Odoo前端的基础&#xf…

Cephalo:专门用于仿生设计的多模态视觉大型语言模型

实时了解业内动态&#xff0c;论文是最好的桥梁&#xff0c;专栏精选论文重点解读热点论文&#xff0c;围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;…

linux库函数 gettimeofday() localtime 使用demo

1. 基本说明 /* linux库函数 gettimeofday 1. 头文件#include <sys/time.h> 2. 函数形式int gettimeofday(struct timeval *tv, struct timezone *tz); 3. 返回值Returns 0 on success, or –1 on error 4. 参数tv&#xff1a;虽然tv_usec字段提供微秒级精度&#xff0…

代码随想录训练营第十七天 654最大二叉树 617合并二叉树 700二叉树搜索树的搜索

第一题&#xff1a; 原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 先找到这个数组中的最大值的下标。 然后将数组分为左右两个区间。 然后进行递归。 /*** Definition for a binary tree node.* struct TreeNode {* int val;* …

审美进阶:7个小程序模板,助你提高设计感!

小程序是一种无需下载和安装即可使用的应用程序。小程序实现了应用程序“触手可及”的梦想。用户可以通过扫描或搜索打开应用程序。对于开发者来说&#xff0c;小程序也大大降低了开发成本。因此&#xff0c;越来越多的品牌争相制作小程序应用程序。本文将为您带来优秀的微信小…

安卓开发,获取本机手机号

用免费云服务器&#xff0c;三丰云记录安卓开发过程 以下是使用 Android 开发获取本机手机号的示例代码&#xff08;需要相关权限&#xff09;&#xff1a; java 复制 import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; i…

ubuntu安装qtcreator与环境配置

sudo apt-get update sudo apt-get install gcc g # 两个编译器 sudo apt-get install build-essential # 编译c/c所需要的软件包 sudo apt-get install libgl1-mesa-dev # 安装mesa&#xff0c;Mesa 实际上是一个库&#xff0c;它实现了多种图形 API 规范 sudo apt-get insta…

[pycrypto][python]pycrypto所有whl文件下载地址汇总

PyCrypto是一个强大的Python加密库&#xff0c;专为密码学和数据安全提供了一系列工具。以下是关于PyCrypto的详细介绍&#xff1a; 项目简介&#xff1a; PyCrypto是一个广泛使用的开源Python库&#xff0c;它包含了多种经典和现代的加密算法&#xff0c;如AES&#xff08;高级…

IOPaint前后端框架

IOPaint 前后端框架 IOPaint 是一个图像修复工具&#xff0c;使用了先进的AI模型进行图像编辑。以下是其前后端所使用的框架&#xff1a; 前端框架 IOPaint 的前端使用了 Node.js 和 npm 进行依赖管理和构建。具体步骤如下&#xff1a; 克隆仓库并进入 web_app 目录&#x…

微信小程序设置时间缓存限制,一段时间后自动清除缓存内容

在原生微信小程序的 app.js 文件里的 onShow (生命周期回调-监听小程序启动或切前台)进行设置 在 uni-app 的 App.vue 文件里的 onShow (生命周期回调-监听小程序启动或切前台)进行设置 onShow() {// 存入初次打开小程序的时间&#xff0c;为后面清除缓存使用const dataExpir…

MFC结构体定义中使用CString类型

MFC的结构体定义中字符串可以使用CString类型&#xff1b; struct MyStruct {int x;int y;CString str; }; ...... void CTttView::OnDraw(CDC* pDC) {CTttDoc* pDoc GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereCString str1;MyStruct m_…

React 组件通信-案例

React 组件通信是构建复杂应用的核心部分&#xff0c;涉及到不同组件之间的数据传递和事件处理。以下提供了相应的案例代码。 1. 父组件向子组件传递数据&#xff08;父传子&#xff09; 父组件通过 props 向子组件传递数据。 // ParentComponent.js import React from reac…