Vaadin组件下的新反序列化链寻找
字数 1639 2025-08-22 12:23:36

Vaadin组件反序列化链分析与利用

前言

Vaadin是一个用于构建现代Web应用程序的Java框架。本文详细分析Vaadin组件中存在的反序列化漏洞链,特别是通过getValue方法实现的攻击路径。

反序列化流程概述

Vaadin反序列化的基本流程可归纳为:

  1. 找到一个反序列化入口,调用PropertysetItem#toString方法
  2. toString方法中,能够调用任意类的getValue方法
  3. 通过精心构造的getValue方法实现恶意操作

关键类分析

NestedMethodProperty类

这是之前研究中使用的类,其getValue方法可以调用任意属性的getter方法,常与TemplateImpl链结合使用。

AbstractSelect类

AbstractSelect#getValue方法流程:

  1. 首先调用父类AbstractField#getValue方法获取retValue
  2. 根据不同情况返回不同属性值(这些值均可控)
  3. 如果multiSelect属性为true(可控),进入if语句
  4. 如果super.getValue返回的值不是SetCollection,进入else语句
  5. 由于items属性可控,可以调用任意containsId方法

SQLContainer类

SQLContainer#containsId方法分析:

  1. 如果传入的itemIdRowId实例且不是TemporaryRowId实例
  2. 调用queryDelegate.containsRowWithKey(((RowId) itemId).getId())
  3. queryDelegate属性可能包含数据库执行功能

TableQuery实现

TableQuery类的关键行为:

  1. 使用generateSelectQuery动态生成查询语句
  2. 如果activeConnection属性为null:
    • 进入if (!isInTransaction())语句
    • 调用beginTransaction方法
  3. beginTransaction最终调用connectionPool.reserveConnection

JDBCConnectionPool实现

J2EEConnectionPool

J2EEConnectionPool#reserveConnection的关键点:

  1. 如果dataSource为空
  2. 调用lookupDataSource进行JNDI查找
  3. dataSourceJndiName变量可控,导致JNDI注入攻击

SimpleJDBCConnectionPool

另一种实现,但文中未详细描述其利用方式。

攻击链构建

完整的攻击链可以这样构建:

  1. 通过反序列化触发PropertysetItem#toString
  2. 精心构造对象使调用AbstractSelect#getValue
  3. 设置multiSelect为true,控制返回值类型
  4. 使items指向SQLContainer实例
  5. 配置SQLContainerqueryDelegateTableQuery实例
  6. 设置TableQueryactiveConnection为null
  7. 配置connectionPoolJ2EEConnectionPool实例
  8. 设置dataSourceJndiName为恶意JNDI地址
  9. 最终触发JNDI注入攻击

防御建议

  1. 对反序列化操作进行严格限制
  2. 更新Vaadin到最新安全版本
  3. 限制JNDI查找功能
  4. 实施Java安全管理器策略
  5. 对网络通信进行加密和认证

总结

本文详细分析了Vaadin组件中存在的反序列化漏洞链,重点是通过getValue方法调用链最终实现JNDI注入的攻击路径。理解这些关键类和方法的交互对于防御此类攻击至关重要。

Vaadin组件反序列化链分析与利用 前言 Vaadin是一个用于构建现代Web应用程序的Java框架。本文详细分析Vaadin组件中存在的反序列化漏洞链,特别是通过 getValue 方法实现的攻击路径。 反序列化流程概述 Vaadin反序列化的基本流程可归纳为: 找到一个反序列化入口,调用 PropertysetItem#toString 方法 在 toString 方法中,能够调用任意类的 getValue 方法 通过精心构造的 getValue 方法实现恶意操作 关键类分析 NestedMethodProperty类 这是之前研究中使用的类,其 getValue 方法可以调用任意属性的getter方法,常与 TemplateImpl 链结合使用。 AbstractSelect类 AbstractSelect#getValue 方法流程: 首先调用父类 AbstractField#getValue 方法获取 retValue 根据不同情况返回不同属性值(这些值均可控) 如果 multiSelect 属性为true(可控),进入if语句 如果 super.getValue 返回的值不是 Set 或 Collection ,进入else语句 由于 items 属性可控,可以调用任意 containsId 方法 SQLContainer类 SQLContainer#containsId 方法分析: 如果传入的 itemId 是 RowId 实例且不是 TemporaryRowId 实例 调用 queryDelegate.containsRowWithKey(((RowId) itemId).getId()) queryDelegate 属性可能包含数据库执行功能 TableQuery实现 TableQuery 类的关键行为: 使用 generateSelectQuery 动态生成查询语句 如果 activeConnection 属性为null: 进入 if (!isInTransaction()) 语句 调用 beginTransaction 方法 beginTransaction 最终调用 connectionPool.reserveConnection JDBCConnectionPool实现 J2EEConnectionPool J2EEConnectionPool#reserveConnection 的关键点: 如果 dataSource 为空 调用 lookupDataSource 进行JNDI查找 dataSourceJndiName 变量可控,导致JNDI注入攻击 SimpleJDBCConnectionPool 另一种实现,但文中未详细描述其利用方式。 攻击链构建 完整的攻击链可以这样构建: 通过反序列化触发 PropertysetItem#toString 精心构造对象使调用 AbstractSelect#getValue 设置 multiSelect 为true,控制返回值类型 使 items 指向 SQLContainer 实例 配置 SQLContainer 的 queryDelegate 为 TableQuery 实例 设置 TableQuery 的 activeConnection 为null 配置 connectionPool 为 J2EEConnectionPool 实例 设置 dataSourceJndiName 为恶意JNDI地址 最终触发JNDI注入攻击 防御建议 对反序列化操作进行严格限制 更新Vaadin到最新安全版本 限制JNDI查找功能 实施Java安全管理器策略 对网络通信进行加密和认证 总结 本文详细分析了Vaadin组件中存在的反序列化漏洞链,重点是通过 getValue 方法调用链最终实现JNDI注入的攻击路径。理解这些关键类和方法的交互对于防御此类攻击至关重要。