Skip to content

Latest commit

 

History

History
61 lines (50 loc) · 4.44 KB

File metadata and controls

61 lines (50 loc) · 4.44 KB

MysqlDataSource Mysql JDBC URL Attack(MysqlDataSource)

  • 类别:javanative 别名:— 优先级:—
  • 作者:—
  • 依赖mysql-connector-java

注:源码标注 @Deprecated,作为可选构件保留。

作用

构造一个 com.mysql.jdbc.jdbc2.optional.MysqlDataSource 并写入恶意 JDBC URL。当上游 Getter 型 gadget 触发它的 getConnection()(getter)时,MySQL 驱动会按该 URL 发起连接,转化为「恶意 MySQL 服务端 / JDBC URL 参数」利用(如 fake MySQL server 触发反序列化、allowLoadLocalInfile 任意文件读取等)。是 DataSource getter 触发链中的一环,恶意 URL 由内层链提供。

链接标签

  • 入口 tagsDataSourceChainsGetterEND —— 承接 DataSource 类利用链;Getter 表示它的触发点是一个属性 getter(getConnection);END 表示它可作为一环收尾。
  • 衔接 nextTagsMysqlJdbcUrl —— 之后需接一个产出「恶意 MySQL JDBC URL 字符串」的 gadget,即 MysqlJdbc
  • excludes:无。

源码剖析

private final String getterMethodName = "getConnection";
private final String getterPropertyName = "connection";

public Object getObject(String mysqlJdbcUrl) throws Exception {
    com.mysql.jdbc.jdbc2.optional.MysqlDataSource dataSource =
            new com.mysql.jdbc.jdbc2.optional.MysqlDataSource();
    Reflections.setFieldValue(dataSource, "url", mysqlJdbcUrl);   // 恶意 jdbc url
    Reflections.setFieldValue(dataSource, "explicitUrl", true);   // 让 getUrl() 直接返回该 url
    return dataSource;
}

public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    String jdbcUrl = (String)chain.doCreate(context);             // 内层链产出恶意 url
    context.put(ContextTag.SUPER_CLASS_NAME_KEY, DataSource.class);
    context.put(ContextTag.SPECIAL_METHOD_NAME_KEY, "getConnection");
    context.put(ContextTag.GETTER_PARAM_NAME_KEY, "connection");
    return this.getObject(jdbcUrl);
}

逐段解释:

  • getObjectnew MysqlDataSource() 后反射写 urlexplicitUrl=trueexplicitUrltrue 时,MysqlDataSource.getUrl() 会直接返回我们设置的 url 而非用 host/port/database 拼装——这是让恶意 URL 生效的关键。当外层 getter 链触发 getConnection() 时,驱动内部走 getUrl() → 用该 URL 建连,进入 MySQL JDBC URL 攻击面。
  • invokeGadgetContext 的注入:这三条 context.put 是本 gadget 与上游 Getter 触发器(如 CommonsBeanutils1)之间的协议——告诉上游:
    • SUPER_CLASS_NAME_KEY = DataSource.class:把本对象当作 javax.sql.DataSource 处理;
    • SPECIAL_METHOD_NAME_KEY = "getConnection":真正要触发的方法是 getConnection()
    • GETTER_PARAM_NAME_KEY = "connection":对应属性名 connectiongetConnection 的 bean 属性)。 上游的 getter 反射机制(如 BeanComparator/PropertyUtils)据此在反序列化时调用 getConnection(),从而启动本 sink。
  • jdbcUrl 来源chain.doCreate(context) 取内层链产物——一段由 MysqlJdbctags=MysqlJdbcUrl)生成的恶意 MySQL JDBC URL 字符串。

参数(@Param)

本类无 @Param;恶意 JDBC URL 由内层链(nextTags=MysqlJdbcUrl)提供,触发协议字段(getConnection/connection)在 invoke 中固定注入。

适用版本与原理要点

  • 依赖 mysql-connector-java(使用旧包名 com.mysql.jdbc.jdbc2.optional.MysqlDataSource,对应 5.x / 早期 6.x 驱动;8.x 的 com.mysql.cj.* 包名不同)。
  • 本 gadget 本身不触发命令执行,它只是「把 getter 调用转成一次 JDBC 连接」的桥;真正的危害取决于下游 MysqlJdbc 生成的 URL(fake server 反序列化、文件读取等)。
  • 需要上游提供 getter 触发能力(Getter 标签匹配),单独使用无法起链。

所属预设链

自由构件,未直接出现在 51 条预设链中。

关联

  • 上游(提供 Getter 触发,nextTags=Getter):CommonsBeanutils1、CommonsBeanutils2~5。
  • 下游(nextTags=MysqlJdbcUrl):MysqlJdbc(生成恶意 MySQL JDBC URL)。
  • 同族(DataSource getter → JNDI/JDBC 利用):OracleCachedRowSetPostgreSqlDataSourceDruidDataSource 等。