使用codeql从0开始hutool 利用链挖掘
字数 1325 2025-08-30 06:50:35

使用CodeQL挖掘Hutool利用链 - 详细教学文档

1. Hutool利用链背景知识

Hutool是一个Java工具包,其中包含BeanUtil工具类可以调用对象的getter方法。攻击者可以利用这一特性构造特定的对象,通过getter方法触发危险操作。

关键发现:

  • Hutool的BeanUtil会调用对象的getter方法
  • 只要类中存在至少一个public字段或public getter方法,就会触发getter调用
  • 可利用的getter方法需要满足:
    • 方法没有参数 (method.getParameterCount() == 0)
    • 方法以"get"或"is"开头

2. CodeQL规则编写

2.1 基础规则编写

初始版本的CodeQL规则:

from Method m
where 
  m.getName().matches("get%") or m.getName().matches("is%") and
  m.getParameterCount() == 0 and
  m.isPublic()
select m

2.2 改进规则

初始规则存在问题:

  • 会遗漏继承自抽象类的子类方法
  • 需要包含抽象类的方法

改进后的规则:

from Method m
where 
  (m.getName().matches("get%") or m.getName().matches("is%")) and
  m.getParameterCount() == 0 and
  m.isPublic() and
  m.getDeclaringType().isNormalClass()
select m

3. 可利用方法分析

3.1 JDBC利用链

关键类:DSFactory.getDataSource()

调用链:

  1. DSFactory.getDataSource()
  2. createDataSource()
  3. newConnection()
  4. getConnection() (JDBC连接)

具体实现类:

  • PooledDSFactory
  • JndiDSFactory (还可用于JNDI注入)

PooledDSFactory分析:

  1. 构造函数调用newConnection()
  2. 最终调用getConnection()建立JDBC连接
  3. 可利用JDBC连接字符串实现RCE

JndiDSFactory分析:

  1. getJndiDs()方法触发JNDI连接
  2. 可用于JNDI注入攻击

3.2 实际利用问题

在尝试利用时发现的问题:

  • Hutool在匹配getter方法时有严格逻辑
  • 方法名必须严格匹配"get"+字段名的格式
  • 例如:字段名为dataSource,则方法名必须为getDataSource

4. 实际利用案例

4.1 失败利用尝试

尝试构造的POC:

// 需要Setting对象
// 但运行时未触发预期效果

失败原因:

  • getter方法名不严格匹配"get"+字段名的格式
  • Hutool内部isMatchGetter方法检查失败

4.2 成功利用方式

更有效的利用方式:

  • 结合其他组件的setter/getter逻辑
  • 例如通过H2数据库的JDBC连接实现RCE

调用栈示例:

...
getConnection()
newConnection()
createDataSource()
getDataSource()
...

5. 完整挖掘流程总结

  1. 使用改进后的CodeQL规则扫描所有可能的getter方法
  2. 重点关注返回敏感对象或执行敏感操作的方法
  3. 检查方法所在类的继承关系
  4. 验证方法是否会被Hutool实际调用
  5. 构造完整的利用链,考虑所有依赖条件
  6. 测试实际利用效果,调试解决匹配问题

6. 防御建议

  1. 避免使用Hutool的BeanUtil处理不可信对象
  2. 检查所有getter方法的安全性
  3. 限制JDBC连接字符串等敏感操作
  4. 禁用不必要的JNDI功能
  5. 使用最新版本Hutool并关注安全更新

7. 扩展思考

  1. 其他可能触发危险操作的getter方法模式
  2. 结合其他Java反序列化漏洞的利用方式
  3. 自动化识别整个利用链的CodeQL规则改进
  4. 静态分析与动态测试结合的挖掘方法
使用CodeQL挖掘Hutool利用链 - 详细教学文档 1. Hutool利用链背景知识 Hutool是一个Java工具包,其中包含BeanUtil工具类可以调用对象的getter方法。攻击者可以利用这一特性构造特定的对象,通过getter方法触发危险操作。 关键发现: Hutool的BeanUtil会调用对象的getter方法 只要类中存在至少一个public字段或public getter方法,就会触发getter调用 可利用的getter方法需要满足: 方法没有参数 ( method.getParameterCount() == 0 ) 方法以"get"或"is"开头 2. CodeQL规则编写 2.1 基础规则编写 初始版本的CodeQL规则: 2.2 改进规则 初始规则存在问题: 会遗漏继承自抽象类的子类方法 需要包含抽象类的方法 改进后的规则: 3. 可利用方法分析 3.1 JDBC利用链 关键类: DSFactory.getDataSource() 调用链: DSFactory.getDataSource() createDataSource() newConnection() getConnection() (JDBC连接) 具体实现类: PooledDSFactory JndiDSFactory (还可用于JNDI注入) PooledDSFactory分析: 构造函数调用 newConnection() 最终调用 getConnection() 建立JDBC连接 可利用JDBC连接字符串实现RCE JndiDSFactory分析: getJndiDs() 方法触发JNDI连接 可用于JNDI注入攻击 3.2 实际利用问题 在尝试利用时发现的问题: Hutool在匹配getter方法时有严格逻辑 方法名必须严格匹配"get"+字段名的格式 例如:字段名为 dataSource ,则方法名必须为 getDataSource 4. 实际利用案例 4.1 失败利用尝试 尝试构造的POC: 失败原因: getter方法名不严格匹配"get"+字段名的格式 Hutool内部 isMatchGetter 方法检查失败 4.2 成功利用方式 更有效的利用方式: 结合其他组件的setter/getter逻辑 例如通过H2数据库的JDBC连接实现RCE 调用栈示例: 5. 完整挖掘流程总结 使用改进后的CodeQL规则扫描所有可能的getter方法 重点关注返回敏感对象或执行敏感操作的方法 检查方法所在类的继承关系 验证方法是否会被Hutool实际调用 构造完整的利用链,考虑所有依赖条件 测试实际利用效果,调试解决匹配问题 6. 防御建议 避免使用Hutool的BeanUtil处理不可信对象 检查所有getter方法的安全性 限制JDBC连接字符串等敏感操作 禁用不必要的JNDI功能 使用最新版本Hutool并关注安全更新 7. 扩展思考 其他可能触发危险操作的getter方法模式 结合其他Java反序列化漏洞的利用方式 自动化识别整个利用链的CodeQL规则改进 静态分析与动态测试结合的挖掘方法