前言
3.2.2是将不安全类禁用反序列化,但是可以通过将系统属性org.apache.commons.collections. enableunsafesserialization
设置为”true”,而4.1直接完全禁用。
绕过的思路就是寻找可控的java.lang.System#setProperty
System.setProperty方法用于设置指定的系统属性。其签名为:
1 public static String setProperty(String key, String value)
- key: 属性的名称。
- value: 属性的值。
当调用System.setProperty方法时,它会将指定的属性键值对存储在系统属性集中。应用程序和JVM可以根据这些属性来调整其行为和配置。
所以当一个项目使用Commons-Collections3.2.2并且可以在存在反序列化接口并且可控的情况下,寻找这个项目中调用java.lang.System#setProperty
并且尝试控制进行反序列化攻击。
CVE-2024-32030 Apache Kafka UI
使用工具搜索调用那个方法的地方,这个方法还是很好用。
SerializedLambda每个入参的含义,这样便于理解它是如何捕获匿名函数的:
序号 | 属性 | 含义 |
---|---|---|
1 | capturingClass | lambda表达式出现的类 |
2 | functionalInterfaceClass | 以斜杠分隔的形式表示返回的lambda对象的静态类型的名称 |
3 | functionalInterfaceMethodName | lambda工厂现场的当前功能接口方法的名称 |
4 | functionalInterfaceMethodSignature | lambda工厂现场存在的功能接口方法的签名 |
5 | implMethodKind | 实现方法的方法句柄类型 |
6 | implClass | 以斜杠分隔的形式表示包含实现方法的类的名称 |
7 | implMethodName | 实现方法的名称 |
8 | implMethodSignature | 实现方法的签名 |
9 | instantiatedMethodType | 类型变量替换为捕获站点实例化后的主要功能接口方法的签名 |
10 | capturedArgs | lambda工厂站点的动态参数,表示lambda捕获的变量 |
疑问
1 | Tuple2 prop = new scala.Tuple2<>(key, value); |
这段代码为什么选择了apply作为工厂现场的当前功能接口方法的名称。
因为在 Scala 中,apply
是函数对象的默认调用方法。[Java 8 默认方法 | 菜鸟教程 (runoob.com)](https://www.runoob.com/java/java8-default-methods.html#:~:text=简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。 我们只需在方法名前面加个,default 关键字即可实现默认方法。)
后续就是寻找调用apply()方法的地方以及反序列化的入口,参考的第一篇写得很清楚了。
参考:
CVE-2024-32030 Apache Kafka UI 远程代码执行漏洞分析 (qq.com)
https://commons.apache.org/proper/commons-collections/security-reports.html