Commons-Collections3.2.2反序列化绕过

屏幕截图 2024-08-21 194803

前言

3.2.2是将不安全类禁用反序列化,但是可以通过将系统属性org.apache.commons.collections. enableunsafesserialization设置为”true”,而4.1直接完全禁用。

image-20240821234954209

绕过的思路就是寻找可控的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

使用工具搜索调用那个方法的地方,这个方法还是很好用。

image-20240822221648788

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
2
3
4
5
6
Tuple2 prop = new scala.Tuple2<>(key, value);
SerializedLambda lambdaSetSystemProperty = new SerializedLambda(scala.sys.SystemProperties.class,
"scala/Function0", "apply", "()Ljava/lang/Object;",
MethodHandleInfo.REF_invokeStatic, "scala.sys.SystemProperties",
"$anonfun$addOne$1", "(Lscala/Tuple2;)Ljava/lang/String;",
"()Lscala/sys/SystemProperties;", new Object[]{prop});

这段代码为什么选择了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

System.setProperty配置系统属性详解-阿里云开发者社区 (aliyun.com)