快捷搜索:  网络  渗透  后门  CVE  扫描  木马  黑客  as

Apache Shiro 1.2.4反序列化漏洞阐发

0×00 Apache Shiro

这个组件的漏洞很久之前就爆出来了,然则近来工作中又遇到了,刚好近来也在看Java反序列化的器械,所以决定拿出来再阐发一下,期间也遇到了一些希罕的问题。

网上的阐发文章中大部分都是手动添加了co妹妹ons-collections4-4.0的依靠,目的是为了使用ysoserial生成的Co妹妹onsCollections2这个payload,然而我遇到的情形是使用了Co妹妹onsBeanutils1就可以直接打成功,所以这里我们再也不重复网上对Co妹妹onsCollections2的阐发了。

0×01 调试阐发

调试环境:

JDK 1.8.0_72

Tomcat 8.0.30

起首我们把shiro的源码clone归来,并切到有问题的分支上去。

git clone https://github.com/apache/shiro.git shiro-rootcd shiro-root
git checkout 1.2.0

为了能让shiro自带的sample跑起来,要对samples/web/pom.xml文件做一些修改,需要将jstl的版本改成1.2,并且删掉servlet-api的scope字段。同时将jstl-1.2.jar放置在WEB-INF/lib下面。然后应该就可以跑起来并且调试了。

我们将断点打到org.apache.shiro.mgt.DefaultSecurityManager中的resolvePrincipals要领,并且发送一个带有rememberMe Cookie的要求,应该就可以断下来了。

image.png

我们继续跟进这个getRememberedIdentity要领: 

image.png继续始终跟到getRememberedSerializedIdentity要领: 

image.png在这个要领中,读出了我们传入的Cookie,并且进行了base64解码: 

image.png接下来shiro会调用convertBytesToPrincipals并将base64解码后的字节数组作为参数传入:

image.png

这里通过函数名也能猜出来,进行了两个操作,分别是解密以及反序列化,我们先来看解密部分,经过简单的调试后,发现是一个AES解密,并且存在一个预设秘钥Base64.decode(“kPH+bIxk5D2deZiIxcaaaA==”);,在shiro自带的sample中,并没有通过其他的方式配置这个秘钥,所以这里用的就是这个预设值。

而AES解密中遇到的IV也是从我们传入的Cookie中的前几个字节中获取的,因而我们可以轻易的组织出包含任意内容的Cookie值,解密好的明文就是序列化的内容,WEB黑客,调用了deserialize进行反序列化。

终极会调用到org.apache.shiro.io.DefaultSerializer#deserialize要领进行反序列化:
image.png

全部流程十分简单,简要概括一下就是:读取cookie -> base64解码 -> AES解密 -> 反序列化

所以我们的payload组织起来也是十分的简单,完备的PoC我会放到我的GitHub上。

0×02 疑点解惑

在调试的过程中,遇到了一些问题,并没有成功的弹出计算器,这里记录一下。

1. 为什么内陆搭建环境,使用Co妹妹onsBeanutils1打不成功,老是提示ClassNotFound异常?

这个问题我那时调试了好久,一度觉得是payload有问题或者shiro的代码因为年代久遥有了变迁,因为那时遇到的case就是这个payload一发入魂的,表示十分的迷茫。后来发现了症结问题,我们从github上clone到的sample中,co妹妹ons-beanutils这个依靠的版本是1.8.3,而ysoserial生成的payload的版本是1.9.2,所以在默认的sample中是没法打成功的。因而我修改版本号到1.9.2,一发入魂。

所以遇到的谁人案例中,实际的依靠环境版本可能也是如许的吧,所以才能直接打成功。

2. 倘使我的依靠中就是没有高版本的co妹妹ons-beanutils以及co妹妹ons-collections之类的包,怎么行使?

这个项目clone下来以后,可以看到是存在一个co妹妹ons-collections的包的: 

image.png

然则使用ysoserial提供的Co妹妹onsCollections1是没法成功的,会爆出一个异常:

image.png这就十分的希罕了,为什么恰恰没法反序列化byte array类型,调试了一下发现是在这里抛出的异常:

image.png

查了一下Java中Class.forName()和ClassLoader.loadClass()的区分,发现forName()老是使用调用者的ClassLoader(),而loadClass()则是可以本人指定一个不同的ClassLoader。那shiro中的ClasssLoader是怎么来的?是通过Thread.currentThread().getContextClassLoader();获取的,也就是WebappClassLoader。然则为啥提示没法加载byte array呢,搜索了一番看到了orange博客下面的讨论,了解到了全部事情的真象:

Shiro resovleClass使用的是ClassLoader.loadClass()而非Class.forName(),而ClassLoader.loadClass不支持装载数组类型的class。

详细的内容我在这里就不放开讨论了,详情可参考文末原作者的链接。各位同砚可以去研究一下,包括在低版本下反弹shell的要领,在orange的博客中也有讲到。

0xFF 参考链接

强网杯“彩蛋”——Shiro 1.2.4(SHIRO-550)漏洞之发散性思考

Pwn a CTF Platform with Java JRMP Gadget

Loading an array with a classloader

*

您可能还会对下面的文章感兴趣: