内存马
基本概念
内存马(Memory Shell)是一种驻留在服务器内存中的 WebShell,与传统文件型 WebShell 不同,它不依赖磁盘上的脚本文件,而是直接利用应用程序运行时内存实现恶意功能。
工具资源
内存马生成工具(Java-Chains 自带)
Java 内存马特点
- 无文件落地:不写入磁盘,仅存在于内存中
- 高隐蔽性:常规文件扫描难以检测
- 依赖运行时环境:利用 Java 反射、类加载等机制
- 存活周期:随应用重启而消失(非持久化)
技术原理
Java 内存马主要利用以下机制:
JVM 类加载机制
- 通过自定义 ClassLoader 加载恶意字节码
- 利用
defineClass()
方法动态加载类
Servlet 容器机制
- 注入 Filter/Servlet/Listener 等组件
- 例如:添加恶意 Filter 拦截所有请求
Java 反射机制
- 绕过访问控制获取关键类实例
- 动态调用私有方法
常见类型
类型 | 注入方式 | 特点 |
---|---|---|
Filter 型 | 动态添加 Filter | 拦截所有请求 |
Servlet 型 | 注册新 Servlet | 指定路径触发 |
Listener 型 | 添加事件监听器 | 基于事件触发 |
Controller 型 | Spring 框架注入 | 兼容 MVC 架构 |
Interceptor 型 | 注入拦截器 | 类似 Filter 但更底层 |
与 JSP 的区别
在传统 JSP(Java Server Pages)环境中:
- 可直接上传
.jsp
文件执行 - JSP 会被编译为 Servlet 类
- 现代应用通常禁用 JSP 上传功能
实例
举例 1 Shiro-550 写内存马
首先开启 JRMP Listener Port。
在 JRMP 使用如 CB1 链等生成 JMG 内存马。
注意:记得保存相应的密码等。
基础信息:
加密器: JAVA_AES_BASE64
密码: RRoE
密钥: QfVcgIDCR
请求路径: /*
请求头: Accept: scHnVsktaSiAStPzq
随后在 ShiroPayload 生成 JRMPClient(JRMPClient) 的 Payload。
抓取网站的请求包,写入 Payload,并发出请求包。
随后使用选定的内存马工具进行连接,此处使用的是 Godzilla,将前面保存的密码等填入,进行连接。
注意此处需要修改请求配置。
举例 2 Fastjson 写内存马
首先开启 JNDI 中的 LDAP 和 RMI 监听。
随后利用 JNDIBasicPayload 模块生成内存马。
同时保存生成好的账密等。
基础信息:
密码: ioOyPYTeOf
请求路径: /*
请求头: Accept: rpkCZO
脚本类型: JSP
在 FastjsonPayload 模块中选择链,并填入上一步中获取到的 JNDIURL,最后获取到 Payload。
抓包获取,并将 Payload 放入请求包(将请求改为 POST 请求,Content-Type 改为 json)
发送请求包,连接冰蝎。