首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从Kryo反序列化到Marshalsec框架到CVE挖掘

从Kryo反序列化到Marshalsec框架到CVE挖掘

作者头像
Jayway
发布2020-05-07 15:12:23
2.1K0
发布2020-05-07 15:12:23
举报
文章被收录于专栏:卓文见识卓文见识

一、关于Kryo

Kryo 是一个快速序列化/反序列化工具,其使用了字节码生成机制。Kryo 序列化出来的结果,是其自定义的、独有的一种格式,不再是 JSON 或者其他现有的通用格式;而且,其序列化出来的结果是二进制的(即 byte[];而 JSON 本质上是字符串 String),序列化、反序列化时的速度也更快。

很多大型软件都使用了这个库:

其相对于其他反序列化类的特点是可以使用它来序列化或反序列化任何Java类型,而不需要实现Serializable。

二、Kryo的使用

Kryo序列化使用kryo.writeObject(output)方法,反序列化使用kryo.readObject(input)或

kryo.readClassAndObject(input),此外还支持替换策略StdInstantiatorStrategy,写个Demo:

可以看到Kryo的反序列化速度极快。

三、反序列化漏洞

能搜索到的Kryo反序列化漏洞资料较少,只有marshalsec的pdf文件这样一段介绍:

翻译过来如下, Kryo有两种反序列化漏洞:Kryo原生和替换策略StdInstantiatorStrategy,其对应的gadgets也不同,此外还存在一些finalize的附加危害(后反序列化漏洞):

四、从marshalsec到漏洞复现

这里直接拿marshalsec的代码讲解漏洞原理及利用链,可以从github上直接下载工程文件到本地编译使用:

https://github.com/mbechler/marshalsec

工程目录结构较简单,marshalsec目录下的是模拟各种反序列化包的使用场景,如Kryo.java,可见其继承MarshallerBase并实现了SpringAbstractBeanFactoryPointcutAdvisor和CommonsBeanutils,后者就是我们可使用的gadget:

这里重点在unmarshal方法里对输入in进行readClassAndObject反序列化操作,main方法执行run方法,跟进这个run方法,来到其继承的类MarshallerBase,这里对参数args进行校验,分别是我们在jar包里使用的[-a] [-v] [-t]:

指定后最终在test方法里调用特定gadget进行攻击:

而测试类最终也是走到这里,调用对应的unmarshal方法,从而完成整个调用链:

SpringAbstractBeanFactoryPointcutAdvisor为例具体攻击链如下:

关键点在于Kryo将数据反序列化为对象时,在对Map类的数据进行操作时调用了HashMap.put()方法,而后调用DefaultBeanFactoryPointcutAdvisor的equals方法,跟进getAdice中的this.beanFactory.getBean,参数为this.adviceBeanName,其值为ldap://x.x.x.x:1389/obj(攻击者可控),getBean方法接着调用this.doGetSingleton方法, doGetSingleton中调用了JndiLocatorSupport.lookup方法,最终利用JNDI进行RCE。

另外需注意的是payload中将SimpleJndiBeanFactory中的logger设置为NoOpLog而不是使用原来的SLF4JLog,是因为Kryo需要序列化的类有一个无参数的构造函数,只有NoOpLog符合这一点。

CommonsBeanutils的调用链也类似,参照Xstream的调用链。

五、防护手段

1)结合业务场景尽量使用kryo.readObject而不是kryo.readClassAndObject;

2)通用方法:反序列化类设置白名单。

六、后反序列化

这里聊一下上面提到的后反序列化,可以参考这篇:

https://www.contrastsecurity.com/security-influencers/serialization-must-die-act-1-kryo-serialization

或者这篇:

https://paper.seebug.org/1133/

研究了一下,比较有意思,之前关注点都集中在反序列化过程中的触发点而忽略了反序列化之后的攻击面,主要是tostring方法,如IDEA:

还有finalize方法,其作用一般是用来做序列化之后的资源回收,如org.jpedal.io.ObjectStore类中的finalize方法:

可见其调用了flush方法,接着根据imagesOnDiskAsBytes中包含的文件路径依次删除。 我们可以通过以下代码,强制其finalize:

从而实现删除任意文件的效果:

调用链如下:

除此之外还有关闭任意文件、内存损坏、绕过反序列化黑名单等思路,有兴趣可以继续研究。

七、扩展:CTF+CVE

1)从Kryo反序列化到TCTF:

https://github.com/Tom4t0/My-CTF-Challenges/tree/master/tctf2018_finals

2)从marshalsec到CVE:

研究一下Marshalsec各种pop链,或许可以获得一些刷CVE的新思路。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 卓文见识 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、关于Kryo
  • 二、Kryo的使用
  • 三、反序列化漏洞
  • 四、从marshalsec到漏洞复现
  • 五、防护手段
  • 六、后反序列化
  • 七、扩展:CTF+CVE
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档