背景
这个问题是由 fastjson 和 (net.sf.json-lib 或者 org.json 其中一个库)同时在代码中使用且编写不当造成,
关于 JSON-lib 和 org.json 这两个库做过 Java 开发的应该比较熟悉,是除了 Jackson、gson 以外使用量和知名度都算是比较高的库了。
所以一个工程中同时出现使用 fastjson 和 (json-lib/org.json)也是常有的事。
SSRF
fastjson 对 URL 的处理
在 fastjson 反序列化类白名单里设置了很多常用的 Java 类,在没有开启 autotype 的情况下这些类也是默认允许被反序列化的,其中包括了 java.net.URL
要想让 java.net.URL 类发起 URL 请求,就需要调用这三种方法
new URL(...).getContent();
new URL(...).openStream();
new URL(...).openConnection().connect();
在反序列化中也只有 get 开头的无参方法可以被调用了,所以要想让 URL 类在 反序列化时触发请求 就要想办法调用 URL 的 getContent()
显然光靠 fastjson 是无法完成 getContent() 方法调用的,不然这篇文章就叫 fastjson 1.2.76 SSRF 了。
fastjson 一般可以通过 JSONPath 和转JSON 的时候调用 get 方法,但这两种方法都有局限,无法调用到 getContent() ,所以需要前面说到的 json-lib 或者 org.json 来触发。
触发 getContent
这里直接放上几种可以触发 getContent 的代码
分别是 json-lib JSONObject类的 fromObject()、put()、 containsValue
还有 org.json 的 JSONObject 构造方法
至于为何 org.json 和 json-lib 可以调用传入对象的所有 get 方法跟进源码看一下就知道了。
所以要想找到这个漏洞就需要去看代码有没有先用 fastjson 去解析 JSON,然后要看 org.json/json-lib 有没有把 fastjson 解析的结果传入。如果有这样的情况那很可能就会存在问题
关于触发点的一些想法
fastjson 是一个开源的项目,可以在 issue 提出问题,如果向 fastjson 的项目提出希望支持 json-lib 这样看似很正常实际能造成漏洞的需求,这个漏洞的利用可能就更完美了,当然这样做肯定是不厚道的。
另外 net.sf.json.JSONObject 也是一个实现了 java.util.Map 接口的类,fastjson 对 Map 类型的反序列化在com.alibaba.fastjson.parser.deserializer.MapDeserializer
中也有做专门的处理。
遗憾的是这里没有指定期望类,如果指定了期望类是 java.util.Map
的话,可以这样触发。
TypeReference<Map<String, Object>> typeReference = new TypeReference<Map<String, Object>>() {
};
Map<String, Object> stringObjectMap = JSON.parseObject("{"@type":"net.sf.json.JSONObject","a":{"@type":"net.sf.json.JSONObject","x":{"@type":"java.net.URL","val":"http://127.0.0.1:2333"}}}", typeReference);
代码执行
前段时间看了朋友分享了一篇文章《Yongtao Wang & Yang Zhang - NTLM Relay Risk Is Coming_ A New Exploit Technique Makes It Reborn》[1],正好可以在这里用到,在 Java+Windows 环境下存在SSRF或反序列化没有可用的 rce gadget 时可以利用文中提到的方式窃取 NTLM Hash。
图中使用的 exploit 是 5alt/UltraRelay[2],需要准备一台 ubuntu 虚拟机来开启恶意的 http 服务,然后在 Windows server 2008 上用 java.net.URL 类访问恶意的 http 服务即可获取到 NTLM Hash,拿到 NTLM Hash 就可以去执行命令了。
场景
我在本地搭了一套用来复现的 springboot 服务,为了省事直接设置了 fastjson 的 httpMessageConverter。这样只用在绑定了 RequestMapping 方法的参数中使用 @RequestBody 注解就可以自动使用 fastjson 解析,效果同等于 JSON.parse
以上几个例子都可以造成 SSRF。
这种问题一般更容易通过白盒去发现,我见过使用两个 json 库比较多的场景大概是这样的:一个接口会先用 fastjson 解析请求中的 json 得到一个 Map ,然后把 fastjson 解析的 Map 对象里某个值或者整个 Map 都放到第二个 JSON 处理库的 JSON 对象,最后把第二个 JSON 处理库的 JSON 对象转成 Map 或者字符串,并作为内部 API 接口的请求参数去发起请求。
代码参考下图
总结
fastjson、JSON-lib、org.json 三个库都是引用量、使用量、知名度仅次于 jackson 和 gson 的 json 处理库,开发者也完全不会意识到使用两个 json 库可能会造成安全问题,所以这样的问题多少还是会存在的。
最后,欢迎各位大佬一起交流探讨。
References
[1]
《Yongtao Wang & Yang Zhang - NTLM Relay Risk Is Coming_ A New Exploit Technique Makes It Reborn》: https://github.com/ssd-secure-disclosure/typhooncon2019/blob/master/Yongtao%20Wang%20%26%20Yang%20Zhang%20-%20NTLM%20Relay%20Risk%20Is%20Coming_%20A%20New%20Exploit%20Technique%20Makes%20It%20Reborn.pdf[2]
5alt/UltraRelay: https://github.com/5alt/ultrarelay
本文始发于微信公众号(安全档案):fastjson 1.2.76 和其他JSON库使用不当可能造成漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论