
1. 原理深度:Java反序列化漏洞的底层机制是什么?为什么反序列化可能导致RCE?
参考答案:
-
机制 :Java反序列化通过
ObjectInputStream
将二进制数据还原为对象。若攻击者控制输入,可构造恶意对象,在反序列化时触发危险操作(如动态代理、反射调用)。 -
RCE成因 :
-
Gadget链 :利用类库中多个可串联的类(如
InvokerTransformer
、TemplatesImpl
),通过链式调用执行任意代码。 -
动态加载 :某些类(如
URLClassLoader
)允许加载远程代码,结合反序列化触发类初始化逻辑。 -
反射调用 :利用
Method.invoke()
或Runtime.exec()
等实现命令执行。
-
-
关键点 :反序列化过程中未对输入数据进行校验,导致恶意类的
readObject()
或readExternal()
方法被触发。
2. 框架漏洞:Apache Commons Collections如何被用于构造反序列化利用链?请描述具体类和方法的作用。
参考答案:
-
核心类 :
-
InvokerTransformer
:通过反射调用任意方法,如Runtime.getRuntime().exec("cmd")
。 -
ChainedTransformer
:将多个Transformer
串联,形成链式调用。 -
ConstantTransformer
:返回固定值,用于传递恶意对象。 -
TransformedMap
/LazyMap
:在Map操作时触发Transformer链。
-
-
利用链构造 :
-
构造
ChainedTransformer
链,串联反射调用Runtime.exec()
。 -
通过
TransformedMap.decorate()
包装Map,使Map的put()
或get()
操作触发Transformer链。 -
利用
AnnotationInvocationHandler
的readObject()
反序列化入口,触发Map操作。
-
-
示例Payload :
Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"}) }; ChainedTransformer chain = new ChainedTransformer(transformers);
3. 防御机制:如何有效防御Java反序列化漏洞?对比黑名单与白名单方案的优缺点。
参考答案:
-
防御手段 :
-
输入验证:禁止反序列化不可信数据。
-
白名单 :使用
ValidatingObjectInputStream
(VOIS)仅允许反序列化安全类。 -
替换序列化机制:使用JSON(如Jackson)或Protocol Buffers替代Java原生序列化。
-
JEP 290:JDK9+的过滤器机制,通过模式匹配限制反序列化类。
-
安全加固:移除危险类库(如Commons Collections 3.x升级至4+)。
-
-
黑名单 vs 白名单 :
-
黑名单 :拦截已知危险类(如
InvokerTransformer
),但易被绕过(新增Gadget或组合类)。 -
白名单:仅允许已知安全类,安全性更高,但维护成本较大(需覆盖业务所有合法类)。
-
4. 框架案例:Fastjson反序列化漏洞的原理是什么?如何利用TemplatesImpl
类实现RCE?
参考答案:
-
漏洞原理 :Fastjson的
autoType
功能允许反序列化时指定任意类。攻击者可构造恶意JSON,触发目标类的setter
/getter
或构造函数中的危险操作。 -
TemplatesImpl利用 :
-
构造恶意类 :生成一个继承
AbstractTranslet
的类,在静态代码块或构造函数中插入恶意代码。 -
Base64编码:将类字节码Base64编码后嵌入JSON。
-
触发加载 :通过
@type
指定com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
,并设置_bytecodes
和_outputProperties
字段,触发类加载与初始化。
-
-
Payload示例 :
{ "@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl", "_bytecodes": ["恶意类Base64编码"], "_outputProperties": {} }
5. 高级绕过:如何绕过反序列化黑名单机制?请举例说明一种非传统的Gadget链构造方法。
参考答案:
-
绕过手段 :
-
利用冷门类库 :如使用
groovy.util.Expando
或org.apache.xbean
等非默认黑名单类构造链。 -
动态加载字节码 :通过
BCEL ClassLoader
或ClassLoader.defineClass()
加载远程字节码。 -
二次反序列化 :利用
Serializable
对象内部嵌套另一个反序列化入口点。
-
-
示例:BCEL绕过 :
String className = "$$BCEL$$..."; // BCEL格式的恶意类字节码 ClassLoader loader = new ClassLoader() {}; Class clazz = loader.loadClass(className); clazz.newInstance();
-
反射+动态代理 :通过
Proxy.newProxyInstance()
创建代理类,结合InvocationHandler
执行命令。