准备:
在github下载shiro-root-1.2.4源码.
在IDEA中打开项目,进行如下配置:




添加 samples-web:war exploded即可

可以看见已经搭建成功了,我们通过burp抓包可以看到shiro反序列化的特征
加密分析
HTTP/1.1 302
Set-Cookie: rememberMe=deleteMe; Path=/samples; Max-Age=0; Expires=Tue, 29-Mar-2022 08:48:15 GMT
Set-Cookie: rememberMe=

在idea中查找rememberMe可见如下:

一个一个的查看可以发现RememberMeManager.class中定义了几个方法,而AbstractRememberMeManager.class和CookieRememberMeManager.class中便是一些程序代码。
在文件中可以看到rememberSerializedIdentity方法,看到这个名字就想到了序列化rememberme对象,于是在这个方法下一个断点进行调试


一路f8下来没有比较有意义的方法,直到进入AbstractRememberMeManager.class文件发现从rememberIdentity方法出来了,于是反过来查看该方法。

convertPrincipalsToBytes函数返回了rememberme的byte[],于是重新在此处下断点进行调试

f7进入serialize方法
this.getSerializer().serialize(principals);
再次f7,看到这里就明白了,这里先转为byte,写入缓冲区;然后进行了一个序列化,最后通过toByteArray()方法返回序列化后的Byte数组。

f8回去查看
if (this.getCipherService() != null) {
bytes = this.encrypt(bytes);
}
f7进getCipherService查看是判断的什么

可以看到获取了一个密码服务,再次f7就返回了,于是ctrl进去查看cipherService发现
private CipherService cipherService = new AesCipherService();
通过名字就可以看出是一个 aes加密服务 ,不过严谨来看还是进去查看一下:

可以看到确实是aes加密,继续debug看见 开始了

于是f7进入加密方法查看

可以发现该方法 主要是 ByteSource byteSource = cipherService.encrypt(serialized, this.getEncryptionCipherKey());起作用,于是f8到这个位置了f7进入查看该方法先看第一个encrypt

也是加密方法,而第二个getkey的话进入发现是获取aes的硬编码:
public byte[] getEncryptionCipherKey() {
return this.encryptionCipherKey;
}
而在上面有定义:
private static final byte[] DEFAULT_CIPHER_KEY_BYTES = Base64.decode("kPH+bIxk5D2deZiIxcaaaA==");
private byte[] encryptionCipherKey;
private byte[] decryptionCipherKey;
由此便是加密了。
解密分析
首先我们知道了加密是AES加密–>base64编码–>发送cookie
由此我把断点 下在了encrypt之下的decrypt。
然后使用shiro的利用工具发送请求包。


f8回去发现出自convertBytesToPrincipals

继续下去发现出自getRememberedPrincipals

重新下断点并debug。
进入getRememberedSerializedIdentity

并不能看出这个函数有什么作用,于是一路f8直到看见了String base64 = this.getCookie().readValue(request, response);

可以明白该函数读取了cookie中的数据

分析该函数可以看出通过getName()方法得到了key为remeberMe。然后把value置空,再通过getCookie获取到cookie。最后判断cookie不为空,则进入内部;随后获取到cookie的值;值则为序列化内容。然后再 return回序列化内容。
返回之前的函数一路f8,看到了

这里就将base64进行了解码并化为了byte。
接下来就是aes解密,我们继续f8,然后就回到了

可以看见convertBytesToPrincipals会接收并处理bytes,于是我们跟进这个方法

进入decrypt

继续跟进decrypt

都是解密的
一路f8回到上一层

重点来了,deserialize()。f7进入

继续f7进入

我们反序列化的神,readObject函数在这等着我们呢。
由此shiro反序列化就因为这个了,加密解密都看完了,准备过两天好好看看readobject和cc。
本文深入分析了Apache Shiro框架的反序列化漏洞,从准备环境到加密分析,再到解密分析,详细解释了Shiro如何进行AES加密、Base64编码以及如何处理cookie数据。在解密过程中,文章揭示了反序列化过程的关键步骤,指出`readObject`函数是导致反序列化漏洞的原因。
7342

被折叠的 条评论
为什么被折叠?



