九维团队-绿队(改进)| shiro反序列化漏洞源码分析

admin 2022年9月15日10:45:49评论56 views字数 2970阅读9分54秒阅读模式

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


shiro介绍


Apache Shiro是企业常见的JAVA安全框架,执行身份验证、授权、密码和会话管理。只要rememberMe的AES加密密钥泄露,无论shiro是什么版本都会导致反序列化漏洞。


shiro漏洞原理


Apache Shiro框架提供了记住我的功能(RemeberMe),用户登录成功后会生成经过加密并编码的cookie。cookie的key为RemeberMe,cookie的值是经过对相关信息进行序列化,然后使用aes加密,最后在使用base64编码处理形成的。


在服务端接收cookie值时,按以下步骤解析:

1.检索RemeberMe cookie的值

2.Base 64解码

3.使用ACE解密(加密密钥硬编码)

4.进行反序列化操作(未作过滤处理


在调用反序列化的时候未进行任何过滤,导致可以触发远程代码执行漏洞。


处理流程如下:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


简单的环境搭建

shiro1.2.4的war包链接:https://pan.baidu.com/s/1i-XEEZsoBgzMzSwclAh2gA 提取码:6mzq

*左右滑动查看更多


将war包放到tomcat的webapps下,双击bin目录下的startup.bat,然后访问http://localhost:端口/shiro/login.jsp即可。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


使用root/secret登录,抓包,服务端会返回一串加密的字符。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


源码分析

首先关注CookieRememberMeManager,是一个用于处理cookie的manager:

orgapacheshirowebmgtCookieRememberMeManager.java

*左右滑动查看更多


九维团队-绿队(改进)| shiro反序列化漏洞源码分析


这个manager管理器会在默认的管理器DefaultWebSecurityManager里面对其进行实例化。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

在CookieRememberMeManager里面,有关于rememberMe的序列化和反序列的函数:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


对反序列化的过程进行分析,进入getRememberedSerializedIdentity。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


服务器获取request和response里的cookie,先进行base64解码,但看文章一开始的流程图,是还有一个aes解密的,但到这里,已经返回null了,说明aes解密在另外一个函数里解决了,另外一个函数里肯定包含

getRememberedSerializedIdentity。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


查找一下哪里调用了

getRememberedSerializedIdentity:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


跳转到源码,发现下面是调用了

convertBytesToPrincipals:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


这里插播一下,因为对SubjectContext对象的内容是什么比较感兴趣,于是去找调用,里面存放的是token和info信息:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


继续找createSubject的调用,是在login方法里面:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


继续找login的调用:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

会发现其实到最后传入的参数就是request和response了,即客户端发起的请求,而AuthenticationToken其实是

UsernamePasswordToken。


插播结束,继续之前的内容。跟进去,可以看到这个函数做了两步操作,一个解密一个反序列化,解密应该就是aes解密,就不看了。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


看反序列化函数。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


接着跟进,看到是一个实现泛型的序列化接口:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

点击绿色的标签:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


看到deserialize的两个实现:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

点击默认的序列化类,调用的是原生的反序列化接口,可以看到里面有readObject方法。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


接下来只需要找到aes密钥那我们就可以自己构造参数了,回到刚刚的convertBytesToPrincipals函数跟进到decrypt。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

可以看到先将getCipherService实例化为cipherService再去调decrypt进行解密。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

跟进getDecryptionCipherKey方法,直接返回一个常量。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

找到写它的地方:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

跟进去可以看到是用来设置密钥的函数:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

接着找哪里调用了它:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

可以看到是用来设置密钥的函数。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

查看哪里调用,可以看到

AbstractRememberMeManager函数里的setCipherKey是一个常量,跟进去:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

然后看到密钥是一段固定值:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

那么现在有了密钥我们就可以自己构造数据包,就是序列化aes加密base64加密,然后把它放到正常的执行流程里就可以利用了。


再看一下序列化的过程,就是上面的逆过程。


我们登录成功的时候,服务器生成cookie然后返回给客户端,这个就是序列化的过程:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

rememberSerializedIdentity是将已经加密的aes数据进行base64编码,然后返回到前端,找一下调用的地方:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

convertPrincipalsToBytes应该就是序列化和aes加密的函数,跟进

convertPrincipalsToBytes:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

可以看到是先将认证信息进行序列化,然后aes加密:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

serialize函数一直跟下去,就是原生的序列化方法:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

返回convertPrincipalsToBytes,进入encrypt方法:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

同样也是先实例化CipherService对象,然后调用encrypt方法进行aes加密:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

getEncryptionCipherKey是获取key,后面的就和上面一样了,不做重复。

我们返回rememberSerializedIdentity方法,去查看它的调用:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

发现最后是到DefaultSecurityManager的login方法,简单看一下,显示进行认证,如果最后成功登录,则跳到rememberMeSuccessfulLogin:

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


然后继续跟进,看到的是会先进行一个清楚的操作,然后生成一个新的认证。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

至于具体的内容,后面就不深入,因为最后就会到rememberSerializedIdentity方法,有兴趣可以自己深入一下。


经过上面的调试,可以看出反序列化的过程中,先对SubjectContext的内容进行base64解密操作,然后先是aes解密,解密根据一个key进行解密,再调用原生的反序列化函数进行反序列化,这个过程没有进行过滤,且key不是随机的而且是我们能够得到的,那就意味着在已知key的情况下就可以复原这个过程。


思路:

我们构造恶意的poc,对其进行序列化然后aes加密(key已知)再base64加密,然后放入cookie中向服务器发起请求,这时服务器就会进行反序列化的操作,先base64解密、aes解密,最后就是反序列化操作,反序列化的过程并没有过滤,那么就能够进行一些恶意的操作。


修复方法


去掉或者替换默认的秘钥。


1、去掉默认秘钥

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


2、替换默认秘钥

这里可以自定义一个,或者使用下边自动生成的方式。


新建类GenerateCipherKey,添加静态方法getCipherKey()。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析


在初始化AbstractRememberMeManager的时候调用。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析




—  往期回顾  —

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

九维团队-绿队(改进)| shiro反序列化漏洞源码分析



关于安恒信息安全服务团队
安恒信息安全服务团队由九维安全能力专家构成,其职责分别为:红队持续突破、橙队擅于赋能、黄队致力建设、绿队跟踪改进、青队快速处置、蓝队实时防御,紫队不断优化、暗队专注情报和研究、白队运营管理,以体系化的安全人才及技术为客户赋能。

九维团队-绿队(改进)| shiro反序列化漏洞源码分析

九维团队-绿队(改进)| shiro反序列化漏洞源码分析
九维团队-绿队(改进)| shiro反序列化漏洞源码分析

原文始发于微信公众号(安恒信息安全服务):九维团队-绿队(改进)| shiro反序列化漏洞源码分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年9月15日10:45:49
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   九维团队-绿队(改进)| shiro反序列化漏洞源码分析http://cn-sec.com/archives/1296951.html

发表评论

匿名网友 填写信息