玩转JSON节点的Content-Type XXE攻击

正如我们所知道的,很多web和移动应用都基于客户端-服务器交互模式的web通信服务。不管是SOAP还是RESTful,一般对于web服务来说,最常见的数据格式都是XML和JSON。

尽管web服务可能在编程时只使用其中一种格式,但服务器却可以接受开发人员并没有预料到的其他数据格式,这就有可能会导致JSON节点受到XXE(XML外部实体)攻击,[参见安全脉搏《未知攻焉知防——XXE漏洞攻防》],这种攻击利用了服务器上脆弱配置的XML解析器。

XXE是一种大家所熟知的针对XML节点的攻击方式。为了利用这种攻击,需要在XML payload中包含外部实体声明,并且需要服务器对实体进行扩展,这就可能会导致以下结果:对web服务器文件系统的读取权限、通过UNC路径对远程文件系统的访问或者通过HTTP/HTTPS连接到任意主机。XXE攻击依赖于XML payload中的内联DOCTYPE定义。

在接下来的例子中,我们声明了一个指向web服务器上/etc/passwd文件的外部实体,并将其包含在了XML payload中:

这就构成了一个简单有效的攻击。现在,就让我们玩转一下Content – Type头和HTTP请求payload,然后看看是否可以利用它对JSON节点发起攻击。下面是一个示例JSON请求,请求中Content-Type设置为application / JSON(删除了一些无关紧要的内容)

此时,如果将Content – Type头更改为application / xml,那么客户端将告诉服务器说POST payload是XML格式的数据。

如果不是,那么服务器将无法解析它,并且可能会显示与下面类似的错误提示

该错误表明服务器能够处理XML格式的数据以及JSON格式的数据,但是因为发送过来的并不是Content-Type头中所指明的XML格式数据,所以数据无法被正确解析。为了克服这个问题,JSON数据必须转换成XML格式。网络上有很多在线工具可以提供此功能,并且Eric Gruber开发了一个Burp插件来在Burp中自动实现转换(Content-Type转换器

然而,这种直接的转换会导致得到的是一个无效的XML文档,因为它没有根元素,而根元素是正常XML文档所必须的内容。如果这个无效的XML发送到了服务器,有时服务器会返回一个错误消息来提示需要什么样的根元素,同时随着返回对应的名称空间。否则,最好的方法是添加根元素<root>将它变成一个有效的XML文件。

现在可以将原始的JSON请求以XML形式发送,并且服务器将会返回一个有效的响应

既然现在服务器接受了XML输入,那么我们就可以利用XXE 来攻击JSON节点了。

显然,并不是每一个JSON节点都接受XML。有时改变Content-Type头可能没有任何影响,也可能会导致415不支持的媒体类型错误消息。但另一方面,JSON转XML攻击并不仅仅局限于JSON内容的POST payload。我也见到过这种方法对JSON格式的GET和POST参数攻击也有效。如果将JSON参数进行转换并以XML形式发送到服务器,那么服务器将猜测它的内容类型。

所以,为了强化JSON节点的安全性,应该禁用XML解析或者禁用内敛DOCTYPE声明,以此来防止XEE注入攻击。

【via:playing-content-type-xxe-json-endpoints  / 安全脉搏 】

相关文章链接:《XXE注入攻击与防御