【带环境】保姆级shiro+spring环境分析并复现spring内存马注入
字数 1492 2025-08-26 22:11:35

Shiro+Spring环境分析与Spring内存马注入复现

目录

  1. Shiro550漏洞分析
  2. 关于CB链
    • JavaBean
    • PropertyUtils.getProperty
    • TemplatesImpl的getOutputProperties
    • 反序列化的入口点
    • 开始构造POC
  3. Spring拦截器内存马分析
    • 原理剖析
    • 自己实现一个拦截器
    • 实现Spring内存马
    • 长度限制绕过
  4. 注入内存马
  5. 参考文章

Shiro550漏洞分析

Shiro550是Apache Shiro框架中的一个著名反序列化漏洞,漏洞编号CVE-2016-4437。该漏洞源于Shiro默认使用了硬编码的加密密钥,攻击者可以利用这个密钥构造恶意的序列化数据,实现远程代码执行。

关键点:

  • 默认使用AES加密,密钥为kPH+bIxk5D2deZiIxcaaaA==
  • 攻击者可以构造恶意的rememberMe Cookie
  • 需要目标服务器存在可利用的反序列化链

关于CB链

JavaBean

JavaBean是Java中一种特殊的类,遵循特定的命名规范:

  • 属性私有化
  • 提供公共的getter和setter方法
  • 实现Serializable接口

PropertyUtils.getProperty

这是Apache Commons BeanUtils中的一个方法,用于通过反射获取JavaBean的属性值。它支持属性链式访问,如property1.property2

TemplatesImpl的getOutputProperties

com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl类中的getOutputProperties方法是一个特殊的getter方法,可以被利用来执行任意字节码。

反序列化的入口点

在Shiro中,反序列化的入口点是AbstractRememberMeManager#convertBytesToPrincipals方法,它会对rememberMe Cookie进行解密和反序列化。

开始构造POC

  1. 构造恶意TemplatesImpl对象
  2. 使用PropertyUtils.getProperty触发getOutputProperties
  3. 将恶意对象序列化
  4. 使用Shiro默认密钥AES加密
  5. 构造rememberMe Cookie发送给目标服务器

Spring拦截器内存马分析

原理剖析

Spring MVC的拦截器机制允许在请求处理前后插入自定义逻辑。内存马通过动态注册恶意拦截器实现持久化后门。

自己实现一个拦截器

public class EvilInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 恶意代码逻辑
        return true;
    }
}

实现Spring内存马

  1. 获取当前应用的上下文org.springframework.web.context.WebApplicationContext
  2. 获取拦截器注册表org.springframework.web.servlet.handler.AbstractHandlerMapping
  3. 动态注册恶意拦截器

长度限制绕过

由于rememberMe Cookie有长度限制,可以采用以下方法:

  1. 使用短类名
  2. 压缩payload
  3. 分块传输

注入内存马

完整攻击流程:

  1. 利用Shiro550漏洞获取反序列化能力
  2. 构造Spring内存马payload
  3. 通过反序列化执行注入拦截器的代码
  4. 验证内存马是否生效

关键代码片段:

// 获取WebApplicationContext
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);

// 获取HandlerMapping
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping)context.getBean("requestMappingHandlerMapping");

// 获取拦截器列表并添加恶意拦截器
List<HandlerInterceptor> interceptors = new ArrayList<>();
interceptors.add(new EvilInterceptor());
handlerMapping.setInterceptors(interceptors.toArray());

参考文章

  1. Apache Shiro官方文档
  2. Spring MVC拦截器机制
  3. Java反序列化漏洞研究
  4. 内存马技术研究论文

注意:本文仅供学习研究使用,请勿用于非法用途。

Shiro+Spring环境分析与Spring内存马注入复现 目录 Shiro550漏洞分析 关于CB链 JavaBean PropertyUtils.getProperty TemplatesImpl的getOutputProperties 反序列化的入口点 开始构造POC Spring拦截器内存马分析 原理剖析 自己实现一个拦截器 实现Spring内存马 长度限制绕过 注入内存马 参考文章 Shiro550漏洞分析 Shiro550是Apache Shiro框架中的一个著名反序列化漏洞,漏洞编号CVE-2016-4437。该漏洞源于Shiro默认使用了硬编码的加密密钥,攻击者可以利用这个密钥构造恶意的序列化数据,实现远程代码执行。 关键点: 默认使用AES加密,密钥为 kPH+bIxk5D2deZiIxcaaaA== 攻击者可以构造恶意的rememberMe Cookie 需要目标服务器存在可利用的反序列化链 关于CB链 JavaBean JavaBean是Java中一种特殊的类,遵循特定的命名规范: 属性私有化 提供公共的getter和setter方法 实现Serializable接口 PropertyUtils.getProperty 这是Apache Commons BeanUtils中的一个方法,用于通过反射获取JavaBean的属性值。它支持属性链式访问,如 property1.property2 。 TemplatesImpl的getOutputProperties com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl 类中的 getOutputProperties 方法是一个特殊的getter方法,可以被利用来执行任意字节码。 反序列化的入口点 在Shiro中,反序列化的入口点是 AbstractRememberMeManager#convertBytesToPrincipals 方法,它会对rememberMe Cookie进行解密和反序列化。 开始构造POC 构造恶意TemplatesImpl对象 使用PropertyUtils.getProperty触发getOutputProperties 将恶意对象序列化 使用Shiro默认密钥AES加密 构造rememberMe Cookie发送给目标服务器 Spring拦截器内存马分析 原理剖析 Spring MVC的拦截器机制允许在请求处理前后插入自定义逻辑。内存马通过动态注册恶意拦截器实现持久化后门。 自己实现一个拦截器 实现Spring内存马 获取当前应用的上下文 org.springframework.web.context.WebApplicationContext 获取拦截器注册表 org.springframework.web.servlet.handler.AbstractHandlerMapping 动态注册恶意拦截器 长度限制绕过 由于rememberMe Cookie有长度限制,可以采用以下方法: 使用短类名 压缩payload 分块传输 注入内存马 完整攻击流程: 利用Shiro550漏洞获取反序列化能力 构造Spring内存马payload 通过反序列化执行注入拦截器的代码 验证内存马是否生效 关键代码片段: 参考文章 Apache Shiro官方文档 Spring MVC拦截器机制 Java反序列化漏洞研究 内存马技术研究论文 注意:本文仅供学习研究使用,请勿用于非法用途。