T3-XML格式和常见利用
好的!既然题目里出现了 <阵枢> 这样的中文标签,我们正好借此机会把 XML 的“骨架”彻底拆解一遍。
XML 的本质是一种纯文本的、用来结构化存储和传输数据的格式(你可以把它想象成更严格的 JSON)。它必须遵守一套严格的语法规则。
下面我把 XML 的核心构成要素,结合你题目里的标签给你讲透:
1. XML 的五大核心组成部分
| 组成部分 | 作用 | 你的题目里的体现 |
|---|---|---|
| ① 声明(可选) | 告诉解析器版本和编码 | <?xml version="1.0"?> |
| ② 根元素(必须) | 有且仅有一个最外层的包裹标签 | <root> 或你自定义的最外层标签 |
| ③ 元素(必须) | 成对出现的开始和结束标签 | <阵枢>内容</阵枢> |
| ④ 属性(可选) | 写在开始标签内,key="value" 形式 |
<阵枢 id="1"> |
| ⑤ 实体(特殊) | 用来表示特殊字符或引用外部资源 | &xxe;(你 Payload 里的变量) |
2. 关键语法规则(必须死记,CTF 常考)
- 必须有唯一的根元素:所有标签必须被一个最外层的父标签包裹。不能写两个并列的顶级标签。
- 标签必须严格闭合:有
<阵枢>就必须有</阵枢>。如果没有内容,可以简写为<阵枢/>。 - 标签名区分大小写:
<Array>和<array>是两个不同的标签。 - 属性值必须加引号:可以是单引号或双引号,但必须存在,例如
<解析 状态="成功">。 - 嵌套不能交叉:
<A><B></A></B>是绝对错误的,必须<A><B></B></A>(后进先出)。
3. 你的题目为什么可以用“中文标签”?
因为 XML 底层使用 Unicode(UTF-8) 编码,所以标签名、属性名、文本内容都支持中文。所以在后端代码里写 <阵枢> 是完全合法且有效的,你提交的 Payload 会被 PHP 的 DOMDocument 正常解析。
4. 重点来了:DTD(文档类型定义)—— 这是你解题的关键
你在漏洞利用时,肯定看到了 <!DOCTYPE ...> 这串东西。它不属于普通的 XML 数据,而是 XML 的“前置说明书”,用来定义文档的结构规则和实体(变量)。
DTD 内部实体(普通变量):
1 |
引用方式:&变量名;
例如:
1 |
|
解析后,<阵枢> 里的内容会变成 “小张”。
DTD 外部实体(你读取文件用的):
这就是你 Payload 里的核心:
1 |
SYSTEM 关键字告诉解析器:“这个变量的值,不在文本里写死,请去我指定的外部路径(系统文件)去读取内容。”
当你写 <阵枢>&xxe;</阵枢> 时,&xxe; 被替换成了 /etc/passwd 的全部文本内容。
5. 把完整结构串起来(标准 XML 文档全貌)
1 | <!-- ① 声明:告诉版本和编码 --> |
特别提醒(针对本题环境)
你的题目报错 Start tag expected, '<' not found,说明后端接收到的不是以 < 开头的文本(比如你之前只输了 env)。
由于这个 XML 解析器没有禁用外部实体加载(这是漏洞根源),所以只要你的输入格式完全符合上述 5 条核心规则,它就会乖乖去读文件并把内容吐回给你。
现在再回头看你成功读取 /etc/passwd 的 Payload,是不是每个字符的位置和含义都清晰多了?如果还有哪个标签符号觉得模糊,随时问我。😊
评论