Magic In Java Api
如果无法正常显示,请先停止浏览器的去广告插件。
1. Magic In Java API
Speaker:yemoli 、R1ckyZ
2. About Us
yemoli 、永信至诚伽玛实验室高级研究员
R1ckyZ 、中国科学院大学
wha1er R1ckyZ-WEB
@yemoliSec @iR1ckyZ
yml-sec.top r1ckyz.github.io
3. 01
Agenda
04
API简介
02 安全影响
03 RASP攻防Tricks
减缓措施
4. API简介
JDK中 PrintServiceLookup接口用于提供打印服务的注册查找功能,在linux的JDK中它的实现类叫
做UnixPrintServiceLookup 或 PrintServiceLookupProvider (高版本 jdk中)
5. API简介
execCmd的参数来自于类的属性,在某些特定情况下如果被篡改掉可能存在着一些安全风险
6. 01
安全影响
FieldBased mechanism
02
03
Pojo Class Recovery
Member of gadget chain
7. How FieldBased mechanism work in deserialisation
•
•
•
•
在某些时候实例化类时调用无参数构造方法
还原 Map 类型时,会调用 hashcode 等方法
允许反序列化未实现 Serializable 接口的类
使用反射来恢复对象的属性
Existing ideas
8. Utilisation under FieldBased mechanism
Serialize Type Affect
java native serialize NO
Hessian YES(version=3.x)
Hessian Lite YES(version<=3.2.12)
SOFA-Hessian YES(version<4.0.0)
Kryo YES
FastJson YES (FieldBased)
Jackson YES (FieldBased)
XStream NO
FST NO
9. Hessian
Hessian是一种轻量级的二进制序列化协议,3.x版本中其反序列化的大致流程如下
10. Hessian
总结来讲,在进行反序列化时有如下的关键行为
•可以反序列化不实现Serializeable的类
•使用默认反序列化器JavaDeserializer实例化类时会调用构造方法
•优先使用无参数构造方法,没有无参数构造方法时会选择有参数的构造方法,但只能还原基本类型参
数,其他类型的参数会自动设置为null
•通过反射来恢复属性
perfect with UnixPrintServiceLookup
11. Why not hessian 4.x ?
12. Why not hessian 4.x ?
13. Hessian Lite
hessian-lite是Apache Dubbo的一个模块,它是基于官方hessian的一个修改版本,在安全性上来说,相比于
原始的hessian ,hessian-lite中维护了一个黑名单,用于防御已知的反序列化攻击;
在3.2.12以及之前的版本中,可以反序列化没有继承Serializable的类,同时在黑名单中也不存在对sun.print的
包的过滤,且默认的反序列化器为JavaDeserializer,因此可以完全符合我们对UnixPrintServiceLookup的利
用要求
14. Lead to CVE-2022-39198
dubbo通信时默认使用hessian-lite进行反序列化,流程如下
15. Lead to CVE-2022-39198
根据上述流程可以发现完全符合UnixPrintServiceLookup的利用条件;
对于此官方修复方案是在黑名单中限制了包名,同时不允许实例化未继承Serializable的类
16. SOFA-Hessian
SOFA-Hessian也是一个基于原生 Hessian 的改进版本, 同样的,在3.x版本中,其默认的反序列化
器为 JavaDeserializer,且 sun.print 包并不在其 serialize.blacklist 黑名单中,所以在3.x版本中
对于 SOFA-Hessian 也可以直接利用 UnixPrintServiceLookup
而在4.x的版本中,其反序列化器选择上同Hessian一样做出了改动,因此无法使用
17. Safety Case
某开源rpc框架依赖了SOFA-Hessian 3.x,Server端解析客户端传入数据的流程如下
在进行通信解析客户端传入参数时,会使用SOFA-Hessian进行反序列化,当构造好恶
意的Object类型参数时,就可以将UnixPrintServiceLookup封装到数据中,在反序列化
时执行命令,由于在反序列化前Server端并没有校验客户端调用的方法是否存在,因此
无需知道远程的方法名也不影响反序列化恶意数据。
18. Kryo
Kryo是一种Java对象序列化协议,它可以快速地序列化和反序列化Java对象,并且生成的序
列化数据比其他Java序列化协议更小,其反序列化的流程如下
kryo在反序列化类时当类不在预设的缓存中时会使用FieldSerializer进行反序列化,
FieldSerializer实例化类时仅会使用类的无参数的构造方法,当类没有无参数的构造方法
时无法实例化,实例化后利用反射来恢复属性。
19. Lead to CVE-2020-5413
Spring Integration是一种消息控制框架,其CodecMessageConverter在对消息进行转换时会
使用到kryo进行反序列化,具体流程如下
在5.2.7及以前的版本中,类无需注册即可使用kryo进行反序列化,因此在这里可以反序列化任意类,
在反序列化时会默认用到FieldSerializer来恢复类和属性,因此这里符合使用UnixPrintServiceLookup
的条件,无需任何依赖即可完成RCE利用
20. Lead to CVE-2020-5413
官方对于该问题的修复逻辑主要是开启了kryo的类注册机制,因此在高版本中当消息接收方没有
注册我们的恶意类时,是无法进行利用的
21. FastJson(FieldBased)
当FastJson开启Autotype和FieldBased配置时,将JSON转换为JAVA对象的流程如下
22. Lead to CVE-2023-23638[1]
version: 3.1.0-3.1.4
在dubbo的 3.1.x版本中,新增了fastjson2反序列化器,反序列化数据的流程如下
23. Lead to CVE-2023-23638[1]
version: 3.1.0-3.1.4
在dubbo中默认会使用hessian进行反序列化,但攻击者可以通过consumer更改Serializeid来
更改反序列化器的类型,虽然在高版本的dubbo存在着对反序列化id的校验检查,但在检查之
前还存在着一个readUTF来读取dubbo的版本号,在Fastjson2反序列化器中readUTF会调用
readObject来进行反序列化,整体流程如下
可以看到在调用fastjson2解析数据时开启了AutoType和
FieldBased,可以利用UnixPrintServiceLookup 执行命令,值得注
意的是,该种方法适用性更强,无需知道远程服务的服务名及参数类
型即可利用;
24. Lead to CVE-2023-23638[1]
version: 3.1.0-3.1.4
对此问题,官方关闭了Autotype,同时不允许反序列化不实现Serializable的类
25. Pojo Class Recovery
通常应用在恢复Pojo类时为了兼容无setter方法的属性会使用反射来直
接恢复属性,当其恢复类实例时如使用默认的构造方法,即可满足我
们的要求
26. Lead to CVE-2023-23638[2]
当Dubbo服务提供者收到一个泛化调用请求时,GenericFilter会对请求进行处理,将请求中的参
数转换为对应的Java对象,并将其传递给实际的服务实现类进行处理,在dubbo泛化调用时将
其模式设置为raw.return后,在还原Pojo类时将使用默认的构造方法,并使用反射来恢复属性
27. Lead to CVE-2023-23638[2]
其泛化调用时也有着自己的黑名单,位于serialize.blockedlist,在3.1.4版本前,sun.print包不在黑名单的
范围中,因此这里符合利用UnixPrintServiceLookup的条件,利用泛化调用时的类实例化来执行命令;为
了修复该问题,官方在后续的版本中对类实例化使用了黑白名单结合的过滤形式;使得后续的版本中整体的
安全性大大提升。
28. Lead to Flink RCE
当向/v1/jobs路由发送文件上传的数据包时,会对上传的数据进行反序列化操作,起始点位于
org.apache.flink.runtime.rest.handler.job.JobSubmitHandler#loadJobGraph
这里可以使用org.apache.flink.api.common.state.StateDescriptor中的readObject来选择反序列化器进行二
次反序列化,当选择PojoSerializer反序列化器时,会使用无参构造函数来创建对象,同时使用反射的方式来
恢复属性
29. Lead to Flink RCE
在这里完全适用UnixPrintServiceLookup 的利用条件,将看似“鸡肋”的反序列化变得不再鸡肋
30. Member of gadget chain
由于UnixPrintServiceLookup中执行命令的方法会由getDefaultPrintService方法调用到,且
该方法为public方法,因此在反序列化中可以充当getter的gadget的角色,在实际利用中,通常
会结合Fastjson、Rome等组件结合使用
31. Safety Case
某开源的分布式远程服务调用(RPC)框架中,在其进行远程方法调用的过程中,会默认使用
hessian2进行数据序列化与反序列化,同时在反序列化前并不会对远程是否存在客户端所请求
的方法进行校验;
32. Safety Case
即使不知道远程服务端的方法,也可以进行反序列化的利用,通过查询其依赖可以发现发现存在
着fastjson的依赖 ;由于其没有反序列化安全过滤,可以直接通过fastjson中的
JSONObject.toString 来调用UnixPrintServiceLookup的getDefaultPrintService方法,进而执
行命令;
33. RASP攻防Tricks
34. RASP攻防Tricks
根据UnixPrintServiceLookup实例化时新建线程的特性,对RASP的检测规则能够轻松的绕过,
demo如下
35. RASP攻防Tricks
上面的操作中显式的使用了反射来修改值,假如存在着一些漏洞场景时,可以有如下更隐蔽的利用
如在spel + fastjson的场景下,可以无感的使用 fastjson特性来恢复属性
36. 减缓措施
37. 减缓措施
对于 RPC服务来说
•对泛化调用进行严格的类型检查
•对通信时使用的序列化器使用黑白名单配置
•使用安全性较高的序列化器
对于其他应用来说
•对用户可控的类实例化操作进行严格校验和检查
•对危险类对象的恢复进行检查
38. 感谢您的观看!
THANK
YOU
FOR
YOUR
WATCHING