ROME 反序列化分析


ROME 反序列化分析环境搭建利用链分析利用链构造getOutputProperties() 如何RCE触发链最终exp

环境搭建

首先找到rome-1.0下载地址 http://rometools.github.io/rome/ROMEReleases/rome-1.0.jar

IDEA新建一个Maven项目

然后导入rome

File->Project Structure->Project Settings::Modules->+->rome-1.0.jar

(我本地java版本是1.8.0_121

接着创建一个Poc.java用来触发漏洞

利用ysoserial生成弹计算器的payload

用之替换上面代码中的BASE64_STRING

运行即可看到弹出了计算器

 

利用链分析

利用链如下

因为要分析toString()(使用idea调试时,会默认调用实例的toString方法,并忽略toString使用的方法中的断点。)所以这里提前设置一下

 

首先到rome-1.0.jar!/com/sun/syndication/feed/impl/QbjectBeanhashCode()中下个断点以便后续分析

可以看到此时this._equalsBeanEqualsBean,于是会调用到EqualsBean.beanHashCode(),跟入之:

此时this.objObjectBean,所以跟到了当前文件下的toString()方法:

上图也可以看出来this._obj._toStringBeanToStringBean

导致触发了ToStringBean.toString()

这里从Variables里大概可以看出导致命令执行的地方就在this._obj里了,这个toString()作用是取一个prefix传入带参数的toString(String prefix)

然后进入toString(String prefix)

最终会运行到这一行并调用pReadMethod.invoke(this._obj,NO_PARAMS)从而触发精心构造的RCE

 

利用链构造

getOutputProperties() 如何RCE

首先要知道怎么直接通过可控.invoke(可控,NO_PARAMS)来达成RCE

从上面一张图中可以看出pReadMethodnamegetOutputProperties,且this._objTemplatesImpl

其实在TemplatesImpl中可以实现加载_bytecodes属性中的字节码来达成任意代码执行

先接着往下看,进一步跟进会到达这里:

然后会进入getTransletInstance()

到这里发现_classnull,会进入defineTransletClasses() 这个方法的作用是用ClassLoader加载字节码,并将其存在_class数组中,还是看一下代码比较清晰:

存入_class后会回到getTransletInstance()并调用

导致最终的任意代码执行

我们导入javassistrhino包先测试一下

直接写个触发getOutputProperties()的exp:

执行成功

 

触发链

入口点是用的HashMapreadObject(),因为其key可控

然后hash(key)就可以和上面最开始下断点的位置rome-1.0.jar!/com/sun/syndication/feed/impl/QbjectBeanhashCode()续上

此时就形成一个完整的链

 

具体构造懒得再一步步写了,先写个hashmap.put()来触发测试,因为

注意要通过2个objectbean才能达成触发条件,才能在反序列化时key满足这个条件,才可到达触发链(这个地方还是稍微有点绕的)

 

 

测试代码如下:

 

最终exp

最终生成序列化数据的exp如下: