确认xml上传点是否支持xxe需先验证基础解析,再通过doctype声明和外部实体触发报错;java中documentbuilder和saxreader默认允许doctype,需显式禁用;绕过content-type检测可改后缀或加bom;盲xxe须结合dns/http回带与多协议交叉验证。

XML文件上传点怎么确认支持外部实体
不是所有能传XML的地方都支持XXE,关键看后端是否用了不安全的XML解析器且未禁用外部实体。常见于SOAP接口、配置导入、SVG上传、RSS订阅源提交等场景。
实操建议:
- 先传一个最简XML,比如
<?xml version="1.0"?><root>test</root>,观察是否正常解析并返回结果——这是基础连通性验证 - 再尝试触发报错:传入
<?xml version="1.0"?> ]><x>&e;</x>,如果响应里出现乱码、路径错误或直接返回了系统文件内容,说明解析器没禁用外部实体 - 注意:很多现代框架(如Spring Boot 2.6+默认的JAXB、Jackson XML)已默认禁用
DOCTYPE,但老项目或手动用DocumentBuilder、SAXReader时极易遗漏配置
Java里哪些XML解析方式默认危险
Java生态里最容易中招的是原生DocumentBuilder和SAXReader(Dom4j),它们默认开启http://apache.org/xml/features/disallow-doctype-decl为false,也就是允许DOCTYPE声明。
实操建议:
- 检查代码中是否出现
DocumentBuilderFactory.newInstance()但没调用setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - Dom4j用户要确认是否设置了
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true),而不是只设了setFeature("http://xml.org/sax/features/external-general-entities", false)——后者只禁外部通用实体,不拦SYSTEM声明 - Spring MVC里如果用
@RequestBody接收XML,底层可能是Jaxb2RootElementHttpMessageConverter,它在JDK 8u121+之后默认安全,但若项目显式指定了JAXBContext实例且未配置SecureProcessingFeature,仍有风险
上传点绕过Content-Type检测的常见手法
很多系统只校验Content-Type: application/xml或text/xml,但XML解析器根本不看这个头——它只认内容本身。所以伪造类型几乎总能绕过。
实操建议:
- 把XML文件后缀改成
.jpg或.png,同时把Content-Type设成image/jpeg,绝大多数后端仍会解析XML内容 - 如果服务端做了文件头检测(比如检查前4字节是否为
<?xm),可加空格或BOM:比如以<?xml version="1.0"?>开头(是UTF-8 BOM),能绕过部分简单判断 - 某些WAF会拦截
SYSTEM字符串,可尝试用SYSTEM "file:///etc/passwd"拆成多行、加注释<!-- -->包裹关键词,或换用php://filter协议读取PHP源码
盲XXE怎么快速验证回带成功
当无法直接看到响应内容(比如上传后只返回“处理成功”),就得靠带外通道(OOB)验证。重点不是“能不能发请求”,而是“目标是否真的解析并执行了实体”。
实操建议:
- 别一上来就打
xxe.example.com,先用自己可控的DNS日志服务(如burpcollaborator.net或interact.sh)生成唯一子域,构造,看后台有没有DNS查询记录 - 如果DNS无反应,试试HTTP回带:
,再查HTTP访问日志;注意有些内网环境出不去公网,得换用内网DNS服务器或本地监听端口 - Java应用中,
http://协议可能被SecurityManager拦截,此时改用ftp://或gopher://更稳,比如gopher://127.0.0.1:80/_GET%20/actuator/env%20HTTP/1.1%0D%0AHost:%20localhost%0D%0A%0D%0A
真正难的不是发payload,是区分“解析器拒绝加载实体”和“网络不通导致没回带”。得交叉验证DNS+HTTP+协议切换,否则容易误判为“不可利用”。










