shiro550漏洞分析
今天来仔细研究一下这个漏洞
环境搭建暂时就不说了,这个可以在网上找教程,直接开始漏洞分析,祝福。
漏洞分析
加密
漏洞产生点在CookieRememberMeManager
该位置,来看到rememberSerializedIdentity
方法。
在此处,对序列化的字节数组进行base64编码,并将编码结果设置为cookie值。那我们看看是什么地方调用了这个方法.
点这个2个用法,这样就可以看到是在哪里用了这个方法.
可以看到是AbstractRememberMeManager类里面调用了这个方法
还可以用ctrl+alt+h来看是哪些东西调用了这个方法
在这里会发现rememberIdentity
方法会被onSuccessfulLogin
方法给调用,跟踪到这一步,就看到了onSuccessfulLogin
登录成功的方法。
当登录成功后会调用AbstractRememberMeManager.onSuccessfulLogin
方法,该方法主要实现了生成加密的RememberMe Cookie
,然后将RememberMe Cookie
设置为用户的Cookie值。在前面我们分析的rememberSerializedIdentity
方法里面去实现了。
接下来,我们在这个登陆函数这里打个断点,进行分析,正向的。
开始环境,然后输入账号密码,root,secret
idea里面都可以看到穿进去了
这里看到调用了isRememberMe
很显而易见得发现这个就是一个判断用户是否选择了Remember Me
选项。
这里进入这个rememberIdentity方法
前面说过该方法会去生成一个PrincipalCollection
对象,里面包含登录信息。F7进行跟进rememberIdentity
方法。
查看convertPrincipalsToBytes的使用,根据英文名字,我们都可以猜测,这个点作用就是将凭证转化为字节流,不过我们还是跟进去看看
跟进来看之后,发现是将凭证序列化之后,再进行转字节流数组。
这里我们接下来看另外一个地方,cipherService
再来看到下一段代码,这里如果getCipherService
方法不为空的话,就会去执行下一段代码。getCipherService
方法是获取加密模式。
后面就是进行加密了
我们跟入这个加密参数来看看
可以看到,如果值不为空就进入加密。
这里,有个getEncryptionCipherKey()
从名字看,就是获取加密密钥的,我们这里就跟进去看看,是怎么获取密钥的。
然后看下面哈
看,下面那个setEncryptionCipherKey
在AbstractRememberMeManager.java的AbstractRememberMeManager方法中被调用了。
然后去查看这个DEFAULT_CIPHER_KEY_BYTES
的值
可以看到,密钥是被定义死的,那么加密过程基本就很清晰了
凭证等值->tobytes->aes->base64
解密
现在看看解密的过程
还是在AbstractRememberMeManager.decrypt中,一层一层网上追溯。
在convertBytesToPrincipals方法中使用了解密方法,继续网上追溯
在这个getRememberedPrincipals方法中调用了convertBytesToPrincipals方法,从名字我们就可以看出,这个getRememberedPrincipals是获取登陆凭证的一个函数
好,那我们就在这个方法中下一个断点,一步一步跟踪。
首先rememberme传进来之后,就会进行base解密,之后和加密差不多,最后就是传入readObject()导致的反序列化漏洞。
漏洞攻击
就用工具即可
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。后续可能会有评论区,不过也可以在github联系我。