记录黑客技术中优秀的内容,传播黑客文化,分享黑客技术精华

Java 8u20反序列化漏洞分析

2020-06-04 18:43

一、前言

在JDK7u21中反序列化漏洞修补方式是在AnnotationInvocationHandler类对type属性做了校验,原来的payload就会执行失败,在8u20中使用BeanContextSupport类对这个修补方式进行了绕过。

二、Java序列化过程及数据分析

在8u20的POC中需要直接操作序列化文件结构,需要对Java序列化数据写入过程、数据结构和数据格式有所了解。 先看一段代码 [crayon-5ed8d03638433981942376/] [crayon-5ed8d0363843c440037626/] 运行A类main方法会生成a.ser文件,以16进制的方式打开看下a.ser文件内容 [crayon-5ed8d0363843f315876322/]   跟下ObjectOutputStream类,来一步步分析下这些代码的含义 java.io.ObjectOutputStream#writeStreamHeader 写入头信息 image-20200602134009099 java.io.ObjectStreamConstants 看下具体值 image-20200602134135011 STREAM_MAGIC 16进制的aced固定值,是这个流的魔数写入在文件的开始位置,可以理解成标识符,程序根据这几个字节的内容就可以确定该文件的类型。 STREAM_VERSION 这个是流的版本号,当前版本号是5。 在看下out.writeObject(object)是怎么写入数据的,会先解析class结构,然后判断是否实现了Serializable接口,然后执行java.io.ObjectOutputStream#writeOrdinaryObject方法 image-20200602140603087 1426行写入TC_OBJECT,常量TC_OBJECT的值是(byte)0x73,1427行调用writeClassDesc方法,然后会调用到java.io.ObjectOutputStream#writeNonProxyDesc方法 image-20200602141317264 TC_CLASSDESC的值是(byte)0x72,在调用java.io.ObjectStreamClass#writeNonProxy方法。 image-20200602141617673 721行先写入对象的类名,然后写入serialVersionUID的值,看下java.io.ObjectStreamClass#getSerialVersionUID方法 image-20200602142011776 默认使用对象的serialVersionUID值,如果对象serialVersionUID的值为空则会计算出一个serialVersionUID的值。 接着调用out.writeByte(flags)写入classDescFlags,可以看见上面判断了如果是实现了serializable则取常量SC_SERIALIZABLE 的0x02值。然后调用out.writeShort(fields.length)写入成员的长度。在调用out.writeByte和out.writeUTF方法写入属性的类型和名称。 然后调用bout.writeByte(TC_ENDBLOCKDATA)方法表示一个Java对象的描述结束。TC_ENDBLOCKDATA常量的值是(byte)0x78。在调用writeClassDesc(desc.getSuperDesc(), false)写入父类的结构信息。 接着调用writeSerialData(obj, desc)写入对象属性的值,调用java.io.ObjectOutputStream#writeSerialData image-20200602154727162 可以看见slots变量的值是父类在前面,这里会先写入的是父类的值。 java.io.ObjectOutputStream#defaultWriteFields image-20200602154248739 这里可以总结下,在序列化对象时,先序列化该对象类的信息和该类的成员属性,再序列化父类的类信息和成员属性,然后序列化对象数据信息时,先序列化父类的数据信息,再序列化子类的数据信息,两部分数据生成的顺序刚好相反。 分析Java序列化文件,使用SerializationDumper工具可以帮助我们理解,这里使用SerializationDumper查看这个序列化文件看下 [crayon-5ed8d03638444045591822/]  

三、漏洞分析及POC解读

8u20是基于7u21的绕过,不熟悉7u21的可以先看这篇文章了解下,看下7u21漏洞的修补方式。 sun.reflect.annotation.AnnotationInvocationHandler#readObject [crayon-5ed8d03638448194436706/]   在AnnotationType.getInstance方法里对this.type类型有判断,需要是annotation类型,原payload里面是Templates类型,所以这里会抛出错误。可以看到在readObject方法里面,是先执行var1.defaultReadObject()还原了对象,然后在进行验证,不符合类型则抛出异常。漏洞作者找到java.beans.beancontext.BeanContextSupport类对这里进行了绕过。 看下BeanContextSupport类 [crayon-5ed8d0363844b164693926/]   [crayon-5ed8d0363844e798745344/]   可以看到在readChildren方法中,在执行ois.readObject()时,这里try catch了,但是没有把异常抛出来,程序会接着执行。如果这里可以把AnnotationInvocationHandler对象在BeanContextSupport类第二次writeObject的时候写入AnnotationInvocationHandler对象,这样反序列化时,即使AnnotationInvocationHandler对象 this.type的值为Templates类型也不会报错。 反序列化还有两点就是: 1.反序列化时类中没有这个成员,依然会对这个成员进行反序列化操作,但是会抛弃掉这个成员。 2.每一个新的对象都会分配一个newHandle的值,newHandle生成规则是从0x7e0000开始递增,如果后面出现相同的类型则会使用TC_REFERENCE结构,引用前面handle的值。 下面直接来看pwntester师傅提供的poc吧 [crayon-5ed8d03638450788461545/]   这里直接构造序列化的文件结构和数据,可以看到注释分为6个步骤: 1.构造LinkedHashSet的结构信息 2.写入payload中TemplatesImpl对象 3.构造Templates Proxy的结构,这里定义了一个虚假的dummy成员,虚假成员也会进行反序列化操作,虽然会抛弃掉这个成员,但是也会生成一个newHandle的值。 4.这里为了BeanContextSupport对象反序列化时能走到readChildren方法那,需要设置serializable要>0并且父类 beanContextChildPeer成员的值为当前对象。BeanContextChildSupport对象已经出现过了,这里直接进行TC_REFERENCE引用对应的Handle。 5.前面分析过在readChildren方法中会再次进行ois.readObject(),这里把payload里面的AnnotationInvocationHandler对象写入即可。这里try catch住了,并没有抛出异常,虽然dummy是假属性依然会进行反序列化操作,目的就是完成反序列化操作生成newHandle值,用于后面直接进行引用。 6.这里就是原JDK7u21里面的payload,把AnnotationInvocationHandler对象引用至前面的handle地址即可。

四、总结

JDK7u21和8u20这两个payload不依赖第三方的jar,只需要满足版本的JRE即可进行攻击,整条链也十分巧妙,在8u20中的几个trick也让我对Java序列化机制有了进一步的认识。

五、参考链接

https://github.com/pwntester/JRE8u20_RCE_Gadget https://www.anquanke.com/post/id/87270 https://www.freebuf.com/vuls/176672.html https://xz.aliyun.com/t/7240#toc-3 https://blog.csdn.net/silentbalanceyh/article/details/8183849        
知识来源: blog.topsec.com.cn/java-8u20%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e6%bc%8f%e6%b4%9e%e5%88%86%e6%9e%90/

阅读:85024 | 评论:0 | 标签:未分类 漏洞 java

想收藏或者和大家分享这篇好文章→复制链接地址

“Java 8u20反序列化漏洞分析”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

永久免费持续更新精选优质黑客技术文章Hackdig,帮你成为掌握黑客技术的英雄

求赞助求支持·广告位💖

标签云