shiro550反序列化漏洞学习(没怎么学过java的人简单尝试)

shiro框架提供了rememberme这个功能,用户登陆后会生成经过加密并编码的cookie,在服务端接收cookie值后,进行解密流程

Base64解码——>AES解码——>反序列化

因此我们只需要获取AES加密的密钥,就可以构造一个恶意对象,再对其进行加密

反序列化——>AES加密——>Base64编码

然后将构造的恶意对象,将其作为cookie的rememberMe字段发送,Shiro将rememberMe进行解密并且反序列化,最终造成反系列化漏洞。

漏洞成因:

Shiro 1.2.4及之前的版本中,AES加密的密钥默认硬编码在代码里(SHIRO-550)

源码分析:

入口点:

onSuccessfulLogin(Subject subject, AuthenticationToken token, AuthenticationInfo info)函数

 

isRememberMe(token) 判断token是否为true

token为true后,进入rememberIdentity函数

跟入getIdentityToRemember函数,这个函数接收subject和AuthenticationInfo作为参数,但是忽略了subject参数,只返回AuthenticationInfo中的principals,这个函数主要用来存储用户主体,相当于把获取的用户名赋值给principals

跟入rememberIdentity函数,看到调用了convertPrincipalsToBytes函数

继续跟入convertPrincipalsToBytes函数,发现这个函数先对之前获取的用户进行反序列化,利用getCipherService()来判断返回的结果是否为空(如果AbstractRememberMeManager类中有一个CipherService属性,那么getCipherService方法就会返回这个属性的值。如果没有这个属性,那么getCipherService方法就会返回null),后进入encrypt函数

encrypt函数

定义一个变量value,初始化为参数serialized。
获取一个CipherService对象,赋值给变量cipherService。
如果cipherService不为空,执行以下操作:
调用cipherService的encrypt方法,传入参数serialized和一个加密密钥,得到一个ByteSource对象,赋值给变量byteSource。
调用byteSource的getBytes方法,得到一个字节数组,赋值给变量value。
返回变量value。

跟入这个函数

cipherService.encrypt(serialized, getEncryptionCipherKey())函数

cipherService是一个接口,encrypt是接口中的函数

在CipherService.java中发现了AesCipherService

继续跟入发现了AES,可以看出是AES加密

继续跟入继承的DefaultBlockCipherService,发现了其运行方式为CBC与填充方案是 PKCS5

跟入PKCS5,可以看出整个加密方法是AES-CBC-PKCS5Padding

回到之前的encrypt函数,这次的目标是getEncryptionCipherKey()函数

跟入getEncryptionCipherKey()函数

查看encryptionCipherKey的调用层次,会发现调用了DEFAULT_CIPHER_KEY_BYTES这个常量

查看一下这个常量,发现是由base64的硬编码,开头到这一步刚好可以分析出加解密为

反序列化——>AES-CBC-PKCS5Padding——>base64

在调用关系中可以看出,这个AbstractRememberMeManager()是继承CookieRememberMeManager,跟入后看到了熟悉的"rememberMe"

总结流程:

  1. 用户名序列化

  2. AES-CBC加密,key已知为kPH+bIxk5D2deZiIxcaaaA==

  3. Base64编码

  4. 将上述设置到cookie中的rememberme字段

提示:不怎么会java,文章可能有些错误

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值