追洞小组 | fastjson1.2.24复现+分析

访客3年前黑客工具554

文章来源|MS08067 WEB攻防知识星球

本文作者:爱吃芝士的小葵(Ms08067实验室追洞小组成员)

漏洞复现分析 认准追洞小组

1、靶场搭建

2、漏洞复现

3、漏洞分析

4、漏洞修复

5、心得

靶场搭建

使用idea maven项目创建,在pom中导入fastjson的坐标。(因为本文复现1.2.24的rce,所以版本要小于1.2.24,本文采
取1.2.23版本坐标)。

导入之后在右边点击maven图标导入。

坑点

其中环境有一个非常细小的点,可以说是个大坑,我调试了很久,之前的报错如下:

1、rmi+jndi环境:java.sql.SQLException: JdbcRowSet (连接) JNDI 无法连接
2、ldap+jndi环境:java.lang.ClassCastException: javax.naming.Reference cannot be
cast to javax.sql.DataSource

后来才发现是java的环境没有配置对,虽然都是jdk1.8,但是复现的环境采用1.8.0_102,之前的环境1.8.0_221没有复现成 功。因为JDK8u113 之后,系统属性 com.sun.jndi.rmi.object.trustURLCodebase 、
com.sun.jndi.cosnaming.object.trustURLCodebase的默认值变为false,即默认不允许RMI、cosnaming从远程的 Codebase加载Reference工厂类。

漏洞复现

一、准备被远程下载的class文件

这边简单弹个计算器,也可以反弹shell


命令行输入 javac Calc.java ,在当前文件夹下会生成Calc.class文件。

二、 http服务

可以简单的用python3在当前Calc.class文件的文件夹下起http服务

python -m http.server 8088

三、RMI服务

使用marshalsec起rmi服务

简而言之就是将class文件放到了http服务上,再用rmi服务绑定该class文件,并将rmi服务的端口应用在8888端口上。

漏洞分析

fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并调用该类的set/get *** 来访问属性。通过查找代码中相关的 *** ,即可构造出一些恶意利用链。

首先放上服务端使用的poc demo:

一、熟悉fastjson工作流程

我们的poc中用到的类是

com.sun.rowset.JdbcRowSetImpl


我们直接进入 com.alibaba.fastjson. *** ON 这个类中,并在parseObject函数上面下断点。

image.png

最后会跟到这个 *** 上。通过Default *** ONParser类去parse我们传入的字符串

image.png

跟进74行的parse代码。这里是根据 *** ONLexer的token为12到case的判断,进入关键函数。

image.png

根据lexer.token() *** 返回token的值,这里是12,所以进入else进行处理。

image.png

然后进入while(true)循环,之一步骤就是lexer.skipWhitespace,跟进去查看 ***

image.png

因而返回的是 “ 号,所以可以进入if判断,根据变量名我们也可以得知,scanSymbol这个 *** 返回的是key关键字。

(key、value对)

image.png

大家可以简单的跟进

com.alibaba.fastjson.parser. *** ONLexerBase#scanSymbol

这个函数走一下流程,最后会通过双引号的闭合判断来返回value字符串,这边返回的就是之一个字符串 @type

image.png

继续往下走到了这里,将key和全局静态常量作比较看是否为 @type ,如果是的话,进入if判断。

image.png

跟进 com.alibaba.fastjson.util#loadClass ,这里面并没有做什么黑名单的过滤就讲这个类对象返回了。

image.png
上面那行代码,跟进分析

image.png

判断是类名返回

image.png

跟进 *** 分析返回

FastJsonA *** Deserializer_1_JdbcRowSetImpl

image.png

再跟进deserialze后继续往下调试,进入setDataSourceName *** ,将dataSourceName值设置为目标RMI服务的地址

一路跟到parseField ***

image.png

调用 *** artMatch *** 来处理我们传入的key值,跟进这个 ***

image.png

之后回跟到

((FieldDeserializer)fieldDeserializer).parseField(parser, object, objectType,
fieldValues);这行代码,进入FieldDeserializer的parseField *** 。进行一些Field的赋值操作。

image.png
再跟进

com.alibaba.fastjson.parser.deserializer.FieldDeserializer#setValue

*** ,根据fieldInfo.fieldClass判断该类,最后进入箭头指向的else体,通过反射调用setAutoCommit关键 *** 。嘿嘿,接下来不是为所欲为。

image.png

这个jdk自带的类必须要先获得一个connection,如果没有的话先执行connect *** 。我们进去看看里面有什么。

image.png

因为我们在前面通过setDataSourceName() *** 设置了dataSourceName的值,所以进入esle if通过lookup *** 去获取

dataSource。而rmi(java远程 *** 调用机制)的主角就是这个 *** ,如果lookup里面传入的参数可控,就可以指向我们所构造的rmi服务,那么就有很大的可能被攻击。(InitialContext
是一个实现了Context接口的类。使用这个类作为JNDI命名服务的入口点。)

这里也简单提一句JNDI和RMI关系,以便更好理解。简单来说,JNDI (Java Naming and Directory
Interface)是一组应用程序接口。JNDI底层支持RMI远程对象,RMI注册的服务可以通过JNDI接口来访问和调用。JNDI接口在初始化时,可以将RMI
URL作为参数传入,而JNDI注入就出现在客户端的lookup()函数中。

image.png

用referenceWrapper包装reference类,注册在jndi的rmi服务实现上,这里rmi服务器绑定的类并没有实现相应的接口,而是通过Refernces类来绑定过一个外部的远程对象。(这里先提及一下,后面会详细说明)一路跟进到这个最终的 *** ,该 *** 执行完就会加载完远程类实现rce。可以看到这里的var3是RegistryContext类,调用lookup函数。

image.png
跟进去时候传入的这个参数是Calc也就是/后面的请求文件,不为空之后调用this.registry(RegistryImpl_Stub,stub和skel的概念是相对而言的,并不只存在于服务端和客户端之间)的lookup *** ,是我们可控的,所以就造成了JNDI注入漏洞。

image.png
继续跟进marshelsec可能会出现这样的错误:

原因是 *** 读取数据超时,我们跟进 *** 的同时加长的数据传输的时间,等待超时抛出错误。至此利用的部分已经结束。

疑惑

因为JNDI注入中RMI服务器最终执行远程 *** ,但是目标服务器lookup()一个恶意的RMI服务地址,反而是目标服务器执行了。那么究竟是什么原因?

在JNDI服务中,RMI服务端除了直接绑定远程对象之外,还可以通过Reference类来绑定一个外部的远程对象(当前名称目录系统之外的对象)。绑定了Reference之后,服务端会先通过Referenceable.getReference()获取绑定对象的引用,并且在目录中保存。当客户端在lookup()查找这个远程对象时,客户端会获取相应的object
factory,最终通过factory类将reference转换为具体的对象实例。

简而言之,在Server绑定Reference时,这个恶意对象是不在Server上的,Reference指向某个地址,Client会去这个地址

取出对象并在Client实例化。

总结

攻击者准备rmi服务和web服务,将rmi绝对路径注入到lookup *** 中,受害者JNDI接口会指向攻击者控制rmi服务器,JNDI接口向攻击者控制web服务器远程加载恶意代码,执行构造函数造成RCE。

漏洞修复

从1.2.25开始对这个漏洞进行了修补,修补方式是会在

com.alibaba.fastjson.parser.Default *** ONParser#parseObject

*** 中调用

com.alibaba.fastjson.parser.ParserConfig#checkAutoType

来检查我们传入的类是不是在黑名单中,也就是将TypeUtils.loadClass替换为checkAutoType()函数:

image.png
只有通过了白名单的校验才会调用loadClass。

但是这里同时使用白名单和黑名单的方式来限制反序列化的类,只有当白名单不通过时才会进行黑名单判断,相当于白

名单并没有真正起到白名单的作用。我们仍然可以进入后续的流程来进行绕过。

黑名单里面禁止了一些常见的反序列化漏洞利用链:


心得

1、
Fastjson主要还是利用了autotype功能实现"@type"字段指定反序列化的Class类型,所以尽量关闭autotype就没有问题。虽然Fastjson在1.2.24之后实现了一套黑名单,但还是存在被绕过风险。

2、
rmi在fastjson中的利用只是jndi的一种手段,还有ldap等。是在rmi服务器上绑定reference对象,与rmi本身的反序列话不是很有关系。它将从攻击者控制的服务器获取工厂类,然后实例化工厂以返回
JNDI所引用的对象的新实例。

MS08067实验室官网:www.ms08067.com

公众号:" Ms08067安全实验室"

Ms08067安全实验室目前开放知识星球: WEB安全攻防,内网安全攻防,Python安全攻防,KALI Linux安全攻防,二进制逆向入门

最后期待各位小伙伴的加入!

目前36000+人已关注加入我们

相关文章

全国外围儿上门,高端商务陪伴三千起步【尤珍】

全国外围小学妹上门,高端商务陪伴三千起步【尤珍】 今天给大家分享的内容是“全国外围小学妹上门,高端商务陪伴三千起步【尤珍】”,我是尤珍,来自江津市,今年25岁,作为职业:艺术,我热爱我的职业:艺术...

大规模用户运营系统,初期该如何建设?

大规模用户运营系统,初期该如何建设?

本文笔者将分享三个板块内容:早期的会合化运营;关于召回、留存、促活的相关手段以及案例理会;风雅化运营初期的用户数据建档、消费行为的阐明建档、数据收罗的模式包括数据收罗后,如何风雅化运营和自动化运营。...

小细胞肺癌治疗进入免疫时代,福建近十万患者有望获益

小细胞肺癌治疗进入免疫时代,福建近十万患者有望获益

肺癌一直是威胁我国居民健康的第一癌,而小细胞肺癌又是所有肺癌中最危险的一种,占所有肺癌的15%,2/3的患者初诊时已经出现了远端器官或淋巴结转移,确诊后5年平均生存率只有2%。 今年2月13日,一款...

如何用ps做gif动态图

开启ps,文档,新创建,键入名字及有关数据信息,建立,再度点文档,开启,寻找表情图所属的部位并双击鼠标加上进去,将涂层表情图双击鼠标开启,将他们搬移到第一个文档部位,进行后点一下顶端的对话框,启用时间...

闲鱼卖货套路就是故事会!

闲鱼卖货套路就是故事会!

有很多小同伴,对象挂在闲鱼上老卖不出去,我又何尝不是。所以本日,我花了一成天在逛闲鱼(我立誓我不是在摸鱼),最终发明白它的三大卖货套路。可以说,正经的告白人看了都认输!此刻,我就要分享给你们。 So...

树大招风,有可能是年度最佳港片,林家栋/陈小春/任贤齐

HK国际影戏节作品,2016年4月上映。 主演:林家栋/陈小春/任贤齐 影片类型为犯罪、枪战。 改编自1990年代HK“三大贼王”张子强、叶继欢与季炳雄的犯罪履历。 豆瓣评分7.9,有网友称这...