tabby在vaadin反序列化链寻找的应用
字数 1884 2025-08-29 08:30:24

Vaadin反序列化漏洞利用链分析与Tabby工具检测缺陷

前言

本文基于Vaadin框架的反序列化漏洞利用链分析,结合静态分析工具Tabby在实际应用中的表现,总结了Vaadin框架中新的利用方式以及Tabby工具在检测过程中的一些缺陷。主要内容包括MethodProperty类的任意方法调用、TextFileProperty类的文件读取以及J2EEConnectionPool类的JDBC攻击等利用方式。

MethodProperty类的任意方法调用

原始利用方式回顾

原始的Vaadin反序列化Gadget是通过利用NestedMethodProperty#getValue方法进行利用的。而实际上,MethodProperty#getValue方法也可以作为替代使用,且使用更为方便。

MethodProperty#getValue方法分析

MethodProperty#getValue方法的实现非常简洁:

public Object getValue() {
    if (instance != null) {
        return ReflectTools.invokeMethod(getMethod, instance, getArgs);
    }
    return null;
}

该方法逻辑为:若instance属性不为空,则反射调用getMethod属性中的方法。

关键属性分析

这些关键属性都是通过MethodProperty类的构造函数进行传入的:

  1. 第一个构造函数(两个参数:instancebeanPropertyName):

    • 获取传入的instance对象的类
    • 处理传入的属性名(首字母大写)
    • 通过initGetterMethod获取后续能够反射调用的Method方法
    • 可以调用getter/is/are方法
  2. 倒数第二个构造函数(七个参数):

    • 直接反射从传入的instance实例中获取该对象所有的方法列表
    • 使用传入的getMethodNametype与反射获取的方法列表进行比对
    • 比对成功则直接将其赋值给getMethod属性
    • 关键点:未对传入的getMethodName变量做任何限制,不仅可以传入getter方法,也可以传入非getter方法
  3. 最后一个构造函数

    • 直接赋值构造函数,最为直接

利用方式

Way1:调用getter方法

// 构造调用getter方法的示例
MethodProperty mp = new MethodProperty(targetObject, "propertyName");

Way2:调用任意方法

// 构造调用任意方法的示例
MethodProperty mp = new MethodProperty(targetObject, "methodName", parameterTypes, parameters);

TextFileProperty类的文件读取

com.vaadin.data.util.TextFileProperty类在其getValue方法中:

public Object getValue() {
    try {
        return FileUtils.readFileToString(file);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

该方法直接传入file属性(该属性值可控),在读取文件之后将内容进行返回。

注意:在反序列化漏洞场景下,这种文件读取的利用方式需要进一步验证其实际可行性。

JDBC攻击利用

J2EEConnectionPool#reserveConnection利用

J2EEConnectionPool#reserveConnection方法的利用流程:

reserveConnection -> getDataSource -> lookupDataSource

这个流程可以触发JNDI注入。此外,如果dataSource属性值不为空,则会调用DataSource#getConnection,从而触发JDBC攻击。

POC示例

// J2EEConnectionPool#reserveConnection的JDBC attack示例
// 需要使用dbcp依赖,打EL表达式,需添加对应依赖

Tabby工具的检测缺陷分析

现有问题

  1. 虽然污点分析工具可以找到原始利用链的完整通路,但对于某些链子(如J2EEConnectionPool#reserveConnectionSimpleJDBCConnectionPool#reserveConnection方法)不存在有通路。

  2. 这些链子在最后达到sink点(如JNDI触发位置)时,并没有参数被污染,数据流不能够被传递。

Tabby的具体缺陷

  1. 虽然能够使用apoc.algo.allSimplePaths这个procedure查到对应的两条链子,但不能检索到J2EEConnectionPool#reserveConnection中存在的JDBC attack。

  2. 根本原因:在生成调用关系图的过程中,没有处理连续调用的情况(如getDataSource().getConnection()),这是一个检测上的缺陷。

总结

  1. MethodProperty类提供了灵活的任意方法调用能力,通过不同的构造函数可以实现getter方法调用或任意方法调用。

  2. TextFileProperty类存在潜在的文件读取风险,但在反序列化场景下的利用需要进一步验证。

  3. J2EEConnectionPool类不仅可以通过JNDI注入利用,还可以通过JDBC攻击进行利用。

  4. 静态分析工具Tabby在处理某些特定调用模式(如连续方法调用)时存在检测缺陷,需要人工分析进行补充。

  5. 在实际漏洞挖掘中,需要结合工具分析和人工验证,才能全面发现潜在的利用链。

Vaadin反序列化漏洞利用链分析与Tabby工具检测缺陷 前言 本文基于Vaadin框架的反序列化漏洞利用链分析,结合静态分析工具Tabby在实际应用中的表现,总结了Vaadin框架中新的利用方式以及Tabby工具在检测过程中的一些缺陷。主要内容包括MethodProperty类的任意方法调用、TextFileProperty类的文件读取以及J2EEConnectionPool类的JDBC攻击等利用方式。 MethodProperty类的任意方法调用 原始利用方式回顾 原始的Vaadin反序列化Gadget是通过利用 NestedMethodProperty#getValue 方法进行利用的。而实际上, MethodProperty#getValue 方法也可以作为替代使用,且使用更为方便。 MethodProperty#getValue方法分析 MethodProperty#getValue 方法的实现非常简洁: 该方法逻辑为:若 instance 属性不为空,则反射调用 getMethod 属性中的方法。 关键属性分析 这些关键属性都是通过 MethodProperty 类的构造函数进行传入的: 第一个构造函数 (两个参数: instance 和 beanPropertyName ): 获取传入的instance对象的类 处理传入的属性名(首字母大写) 通过 initGetterMethod 获取后续能够反射调用的Method方法 可以调用getter/is/are方法 倒数第二个构造函数 (七个参数): 直接反射从传入的instance实例中获取该对象所有的方法列表 使用传入的 getMethodName 和 type 与反射获取的方法列表进行比对 比对成功则直接将其赋值给 getMethod 属性 关键点 :未对传入的 getMethodName 变量做任何限制,不仅可以传入getter方法,也可以传入非getter方法 最后一个构造函数 : 直接赋值构造函数,最为直接 利用方式 Way1:调用getter方法 Way2:调用任意方法 TextFileProperty类的文件读取 com.vaadin.data.util.TextFileProperty 类在其 getValue 方法中: 该方法直接传入 file 属性(该属性值可控),在读取文件之后将内容进行返回。 注意 :在反序列化漏洞场景下,这种文件读取的利用方式需要进一步验证其实际可行性。 JDBC攻击利用 J2EEConnectionPool#reserveConnection利用 J2EEConnectionPool#reserveConnection 方法的利用流程: 这个流程可以触发JNDI注入。此外,如果 dataSource 属性值不为空,则会调用 DataSource#getConnection ,从而触发JDBC攻击。 POC示例 Tabby工具的检测缺陷分析 现有问题 虽然污点分析工具可以找到原始利用链的完整通路,但对于某些链子(如 J2EEConnectionPool#reserveConnection 和 SimpleJDBCConnectionPool#reserveConnection 方法)不存在有通路。 这些链子在最后达到sink点(如JNDI触发位置)时,并没有参数被污染,数据流不能够被传递。 Tabby的具体缺陷 虽然能够使用 apoc.algo.allSimplePaths 这个procedure查到对应的两条链子,但不能检索到 J2EEConnectionPool#reserveConnection 中存在的JDBC attack。 根本原因 :在生成调用关系图的过程中,没有处理连续调用的情况(如 getDataSource().getConnection() ),这是一个检测上的缺陷。 总结 MethodProperty 类提供了灵活的任意方法调用能力,通过不同的构造函数可以实现getter方法调用或任意方法调用。 TextFileProperty 类存在潜在的文件读取风险,但在反序列化场景下的利用需要进一步验证。 J2EEConnectionPool 类不仅可以通过JNDI注入利用,还可以通过JDBC攻击进行利用。 静态分析工具Tabby在处理某些特定调用模式(如连续方法调用)时存在检测缺陷,需要人工分析进行补充。 在实际漏洞挖掘中,需要结合工具分析和人工验证,才能全面发现潜在的利用链。