shiro反序列化
未完待续
环境配置
本人近几天一直头疼于怎么配置这个shiro550的源码环境,这里我给出详细的步骤,以免后人再踩进我踩过的大坑…
首先,下载p神的shiro源码:
https://github.com/phith0n/JavaThings/
下载好之后用IDEA打开这个shirodemo。
我的JDK版本:8u66,正常来说pom.xml里面是不会爆红的。
接着去配置Tomcat,这个步骤比较简单,网上教程也很多,这里不多赘述,推荐:
IntelliJ IDEA中配置Tomcat(超详细)_intellij idea配置tomcat-CSDN博客
我下载的是9.0.100版本。
在项目中配置
接着来到项目结构的工件这里:
可以看到已经有两个部署好的工件,选择下面这个,点应用。
编辑配置里头新建本地Tomcat:
点击应用后直接运行login.jsp,记得修改下它的端口号。
然后我们点击这里:
即可启动。
漏洞分析
数据包特点
在登录框中我们先简单地抓个包(点击了Remember me):
没点击的包:
相比之下得出结论:
勾选了remember me之后,在返回的数据包上多了Set-Cookie字段,第一个值为deleteMe
,第二个像是一串Base64。
1 | 6nTT7Ep5Grk1dN3I5KgZ1iTjjdZnS2+zSoEcYP69yZ7n+r2mYNzMXMXY1WvN99zuOQlrEsv1uHH9UOuTO0fyQjg0v0rh4RVzw4V4SANKcQSkSsFX7V8CSelOgTmiBX+3goGAsbhFGonZIE0nSlqprPgLsybCTW5hdJf/FbE6hC2g1xnoNHbuJ6Lj+BBgRY4IYmSm7kz2AhvtioQi6k6AsDAayvnZKwQlSIzH8Y4s2lEt6vxndTjQcHIngWQTxGZxjmXnQuOrsu6IeLtlRLpNzYSRw0RtXe3T5SifdcBXs5JC15ljEoRJqkO8GBT/8u1RfUNAXW9+stYrDbxBoQRO5bOZWZq/AHUXkACTiGJsiL17WjGYkT/Ec022fmdiZPGnvrLWeaOQeDXCFfg4IqSCH4tnHzt1kpwncCdSwpEbkbWb9/5/v1ZM3Ejz1j/KQI4Winhwytrz2cZq83CcITV1D1YeUGW4c0kVLPFu8NWVwM8hvxtmIphLYQgKU3xbe8tK |
试图解码一下发现并不是base64,下面我们来看看Shiro框架(550版本)的加解密过程。
过程分析
我们先定位到CookieRememberMeManager类:
CookieRememberMeManager类
构造方法:
1 | /** |
getRememberedSerializedIdentity()
:
长话短说:
- 先判断是否为 HTTP 请求
- 如果是的话,获取 cookie 中 rememberMe 的值
- 然后判断是否是 deleteMe,如果存在,则返回null。
- 如果不是,则判断是否是符合 base64 的编码长度,然后再对其进行 base64 解码,将解码结果返回。
AbstractRememberMeManager类
现在我们去寻找一下谁会调用CookieRememberMeManager#getRememberedSerializedIdentity()
getRememberedPrincipals()
- 首先是将 HTTP Requests 里面的 Cookie 拿出来,赋值给 bytes 数组;
- 随后将 bytes 数组的东西进行
convertBytesToPrincipals()
转换成principals(这是什么?)
我们跟进到神秘的convertBytesToPrincipals():
convertBytesToPrincipals()
正常情况下这里调用了decrypt()
与deserialize()
看看decrypt()
decrypt()
1 | /** |
既然有decrypt函数,肯定也有encrypt函数。我们把断点下在encrypt函数:
在单步跟的过程中可以知道encrypt采用的是AES加密:
而且AES的key是一个固定值,写在了本类的源码中:
deserialize()
1 | /** |