目录
参考
Java反序列化(六) | Shiroの起始篇(环境搭建+原理分析) - h0cksr - 博客园 (cnblogs.com)
Shiro 550 反序列化漏洞 详细分析+poc编写_shiro550原理_god_Zeo的博客-CSDN博客
简介
通过在cookie的rememberMe字段中插入恶意payload,
触发shiro框架的rememberMe的反序列化功能,导致任意代码执行。
shiro 1.2.24中,提供了硬编码的AES密钥:kPH+bIxk5D2deZiIxcaaaA==
由于开发人员未修改AES密钥而直接使用Shiro框架,导致了该问题
环境搭建
https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4
直接用这个项目
用tomcat起一下就可以了
分析
加密
找到加密的地方
/shiro-core-1.2.4.jar!/org/apache/shiro/mgt/AbstractRememberMeManager.class
这里是继承了RememberMeManager类,那么我们向上看
这里看到onSuccessfulLogin函数,这里是登录成功的处理
这里下个断点调试一下
下面进入forgetIdentity函数,这里处理request和response请求,继续跟进forgetIdentity函数
进入了getCookie的removeFrom方法,跟进removeFrom方法
里获取看配置信息,最后addCookieHeader放到了返回包中的cookie头中,其中就有我们熟悉的,deleteMe字段和rememberMe字段,也就是我们指纹识别最简单的两种方法的原理
然后就回到了onSuccessfulLogin函数
这个isRememberMe主要是检查选择了remember me这个按钮没有,随后步入 rememberIdentity 方法
这里authcInfo是root,继续往下走
进入rememberIdentity方法后发现,一个函数就是转化为bytes,跟进convertPrincipalsToBytes
这里是有序列化的,序列化的是传入的root用户名
再看到encrypt函数
发现CipherService cipherService = this.getCipherService(),就是获取密码服务的意思
这里看值,发现就是aes加密,AES/CBC/PKCS5Padding
再看getEncryptionCipherKey(),这个就是获取密钥,这个可以一直溯源,最终溯源到 getEncryptionCipherKey 就是开头中的 DEFAULT_CIPHER_KEY_BYTES,也就是我们一开始第一个提到的kPH+bIxk5D2deZiIxcaaaA==这个key
那么再往下进入cipherService.encrypt函数
这里就是生成初始化向量的地方了,后面就是加密细节,直接跳了
回到rememberIdentity函数,进入rememberSerializedIdentity
这里的逻辑就是把刚刚加密的base64放在cookie里面
解密
切入点是
org.apache.shiro.mgt.AbstractRememberMeManager 类的 getRememberedPrincipals,在这里下个断点
这个getRememberedSerializedIdentity方法中 有一个getCookie().readValue(request, response);
这里是要读取cookie中的数据,这里跟进去
一直往下跟可以看到decrypt,然后return回来,可以看到deserialize,往下走还可以看到readobject
编写poc
命令=>序列化=>AES加密=>base64编码=>RememberMe Cookie值
一般就结合其它链子打一下
工具还是挺多的