CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con

这只是一篇自己学习的文章,难免与其他大佬的文章有重合之处,还请大佬们勿怪。

0x00 漏洞成因

按照其他大佬说的这个漏洞出现的原因是因为/invoker/readonly的过滤器没有写好,文件路径是:server\all\deploy\httpha-invoker.sar\invoker.war\WEB-INF\classes\org\jboss\invocation\http\servlet,在这个路径下的ReadOnlyAccessFilter.class中。

把这个class扔到IDEA中查看源码,发现这个过滤器在做过滤的时候没有做任何的校验,导致恶意用户在直接访问这个接口去POST数据的时候(看63行之前的代码)服务器得到输入流,对输入流进行对象化,执行数据流中的对象,这不就是序列化的概念吗。

图片[1]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科0x01 漏洞复现

那么如何构造这个漏洞的POC呢,JBoss5.1版本中使用了commons collections的3.1版本。

使用commons collections可以进行反射链的构造。先复现一下,看看人家的POC是怎么写的:

使用ysoserial.jar这个工具生成各种反序列化的poc或者exp,里面包含了各种各样的反射链所使用到的库。

java -jar ysoserial.jar CommonsCollections6 "calc.exe" > poc.ser

curl http://192.168.154.129:8080/invoker/readonly --data-binary @poc.ser

图片[2]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科

0x02 POC编写

成功之后看看人家是怎么玩的。大佬们的POC是这么写的:图片[3]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科图片[4]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科

在学习了Java反射链的构造之后,还差一步就是如何在反序列化的过程中触发反射链。

于是写POC/EXP的大佬们找到了sun.reflect.annotation.AnnotationInvocationHandler的readObject方法

再看获取构造方法getDeclaredConstructor()获取有参的构造方法

getDeclaredConstructor(Class<?>… parameterTypes)

这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的。

再来看getConstructor(Class<?>… parameterTypes)

这个方法返回的是上面那个方法返回结果的子集,只返回制定参数类型访问权限是public的构造器。

获取构造器对象并将其实例化:

通过类对象的getConstructor()(获取public属性的构造方法)或getDeclaredConstructor()(可获取所有类型的构造方法)方法获得构造器(Constructor)对象并调用其newInstance()方法创建对象,适用于无参和有参构造方法。

不多说,看下AnnotationInvocationHandler构造方法的源码

图片[5]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科

第一行代码:获取Target.class这个类所实现的所有的接口

接着if判断这个类是不是一个注解类型,而且它只实现了一个接口,判断它的所实现的接口是不是一个注解类,满足的话分别赋值。

现在看它的readObject方法,在这里将会触发整个反射链

图片[6]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科

首先传入对象输入流,去读取这个对象输入流,然后是var2去解析这个注解类,获得到值之后,获取成员类型的值:

图片[7]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科

获取到了什么值呢?

图片[8]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科var3引用memberTypes,即var3与传入的Map类型相同,var4为传入Map的集 合转化,接着判断var4中有无元素,如果有元素对其var5获得var4的集 合转化,接着var6获取var5的key值,var7获得var3的类对象,如果var7是存在的,那么var8从var5处getValue,最后如果var8不可以被转化为var7,那么对var5进行setValue操作,如果var5进行setValue操作的话,那么它将进行下面的操作:

图片[9]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科

看下checksetValue的源码:

图片[10]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科

进行了transform操作,如果知道反射链的大佬们此时已经知道反射链的触发就在此处。

var1-var7的值如下:

图片[11]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科

使用自己学习人家的POC去打一遍看看。

图片[12]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科

将生成的bin.ser拷贝到kali中,将其使用curl发送到JBOSS服务器上。

curl http://192.168.154.129:8080/invoker/readonly –data-binary @bin.ser

成功弹出计算器:

图片[13]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科图片[14]-CVE-2017-12149 JBOSS反序列化漏洞学习 – 作者:水木逸轩con-安全小百科

 

来源:freebuf.com 2020-08-14 15:12:40 by: 水木逸轩con

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论