shiro反序列化漏洞分析

本文深入分析了Apache Shiro框架的反序列化漏洞,从准备环境到加密分析,再到解密分析,详细解释了Shiro如何进行AES加密、Base64编码以及如何处理cookie数据。在解密过程中,文章揭示了反序列化过程的关键步骤,指出`readObject`函数是导致反序列化漏洞的原因。

准备:

在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。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值