什么是内存马
内存马(Memory Webshell) 是一种不依赖文件落地的 Webshell 技术。攻击者通过漏洞(反序列化、JNDI注入、文件上传+解析等)获得代码执行能力后,直接在 JVM 内存中注册恶意的 Servlet 组件或修改已有组件的行为,从而实现持久化的命令执行通道
核心思路
1 | 获得代码执行能力 → 获取关键上下文对象 → 动态注册恶意组件 → 通过正常HTTP请求触发 |
内存马分类体系
1 | 内存马 |
各类型对比
| 类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Filter 型 | 拦截所有请求、优先级高、最稳定 | 需获取 StandardContext | 通用场景首选 |
| Servlet 型 | 实现简单 | 只能拦截特定 URL | URL 不冲突时使用 |
| Listener 型 | 最早执行 | 获取 request/response 稍复杂 | 需要最早执行的场景 |
| Controller 型 | Spring 环境原生支持 | 仅限 Spring 应用 | Spring Boot 应用 |
| Interceptor 型 | 类似 Filter,Spring 原生 | 仅限 Spring MVC | Spring MVC 应用 |
| Agent 型 | 无痕修改任意类 | 需要额外 attach 操作 | 高隐蔽需求 |
| Valve 型 | Tomcat 原生管道机制 | 仅限 Tomcat | Tomcat 环境 |
内存马注入的前提条件
内存马不是凭空出现的,需要一个 “代码执行入口”
常见入口
反序列化漏洞
Fastjson、Shiro、Commons-Collections 等
通过构造恶意序列化数据触发任意代码执行
JNDI 注入
Log4j2(CVE-2021-44228)
Fastjson JNDI
表达式注入
SpEL(Spring Expression Language)
OGNL(Struts2)
EL 表达式
文件上传 + 解析
上传 JSP 文件执行后注入内存马,然后删除 JSP
“落地即焚” 策略
已有的 Webshell
从传统 Webshell 升级为内存马
提高隐蔽性
内存马的生命周期
1 | ┌─────────────────────────────────────────────────────┐ |
学习建议
推荐学习顺序
1 | 1. Filter 型内存马(最经典,原理最清晰) |
实验环境准备
JDK 8(内存马最常见的运行环境)
Tomcat 8.5 / 9.0
Spring Boot 2.x
Maven
IDEA / VSCode
BurpSuite(抓包调试)
关键概念速查
| 术语 | 含义 |
|---|---|
| StandardContext | Tomcat 中代表一个 Web 应用的核心对象 |
| FilterDef | Filter 的定义信息 |
| FilterMap | Filter 的 URL 映射信息 |
| ApplicationFilterChain | 请求经过的 Filter 链 |
| WebApplicationContext | Spring 的应用上下文 |
| RequestMappingHandlerMapping | Spring MVC 的路由映射管理器 |
| Instrumentation | Java Agent 的核心 API |
| defineClass | 动态将字节码加载为 Class 的方法 |
| 上一章 | 目录 | 下一章 |
|---|---|---|
| 00-前置知识 | 内存马 | 02-Servlet型内存马 |