Java安全 - Shiro反序列化原理分析
Java安全 - Shiro反序列化原理分析
Shiro
Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序
原理
我们从攻击的逆推来看看这个shiro
的代码
通过工具代理到bp当中查看报文
这是执行了whoami的包
基本上跟说的序列化的值在cookie里头一致,这个时候全局去搜索一下rememberMe这个字段
可以找到CookieRememberMeManager方法
我们需要知道shiro是如何获取cookie的,通过上下文的跟踪看到了getCookie方法
查找调用getCookie发现存在getRememberedSerializedIdentity方法
跟进getRememberedSerializedIdentity方法 看他对我们传入的cookie做了什么-> 先进行获取base64的cookie值
然后进行了base64解密
再往上跟找到getRememberedPrincipals
方法
将我们base64解密的值传入了bytes
数组中
那么现在我们知道我们传入的cookie值会被base64解密,解密出来的值会去干嘛呢?
发现他走了shiro-shiro-root-1.2.4\core\src\main\java\org\apache\shiro\mgt\AbstractRememberMeManager#convertBytesToPrincipals()
这个方法,跟进
就是对我们base64解密出来的字节再一次解密,解密后调用
deserialize
来进行反序列化
那么我们在shiro-web.jar下进行cookie利用的断点调试最后也是走到了这个原生的反序列化里头
找到src/main/java/org/apache/shiro/io/DefaultSerializer#deserialize()#readobject()
1 |
|
那么我们再来看这个对字节做了什么解密
他其实是个接口,但是参数名是加密值+密钥 ,那么这个密钥怎么获得的呢,跟进getDecryptionCipherKey()
方法
发现是个常量
去找一下这个常量如何赋值
发现在这里找到了shiro-shiro-root-1.2.4\core\src\main\java\org\apache\shiro\mgt\AbstractRememberMeManager.java
再往上跟看是怎么把这个东西传进来的
在这里找到shiro-shiro-root-1.2.4\core\src\main\java\org\apache\shiro\mgt\AbstractRememberMeManager#setCipherKey()
再往上跟 shiro-shiro-root-1.2.4\core\src\main\java\org\apache\shiro\mgt\AbstractRememberMeManager#AbstractRememberMeManager
发现就是一个硬编码,整个Cookie的处理流程就跟完了,那么其实就是将从Cookie获取到的字节来去反序列化来打依赖,看有什么依赖打什么链(有CC就打CC 有CB就打CB)
生成shiro的脚本
1 |
|
打过去就OK了
总结一下就是 传入cookie->base64解密->(知道AES的key下可以恶意构造序列化的值)->打反序列化漏洞
这里有个要注意的点
- Shiro类是不允许出现数组类,就是里头不能有数组,打CC6的时候
tranfromer
有数组调用,所以无法打CC,要打的话就CC2+3+6 就是用In