2024春秋杯冬季赛day3writeup_cyi

cyi WRITEUP

个人信息

个人名称:cyi

个人排名:112

解题情况

解题过程

misc Infinity(fail)

操作内容:

Png后藏zip,提出来

随便解压几个发现是无限,解压缩有7z,zip,tar格式,gpt整个jio本

得到最后的secret文件,内容是Inf1nityIsS0CoOL,结合BASE58-Ripple、SM4-ECB提示

赛中:卡在解密了,我想着是文件名base58,然后密文再sm4解一下,死活解不出来,不知道漏了那个,文件名反着来也试过了

赛后:gg

https://products.groupdocs.app/zh/scanner/scan-datamatrix

如该题使用自己编写的脚本代码请详细写出,不允许截图

import os
import zipfile
import tarfile
import py7zr
import io


def extract_zip(file_path):
"""解压 .zip 文件到内存"""
with zipfile.ZipFile(file_path, 'r') as zip_ref:
return {name: zip_ref.read(name) for name in zip_ref.namelist()}


def extract_tar(file_path):
"""解压 .tar 文件到内存"""
with tarfile.open(file_path, 'r') as tar_ref:
return {member.name: tar_ref.extractfile(member).read() for member in tar_ref if member.isfile()}


def extract_tar_gz(file_path):
"""解压 .tar.gz 文件到内存"""
with tarfile.open(file_path, 'r:gz') as tar_ref:
return {member.name: tar_ref.extractfile(member).read() for member in tar_ref if member.isfile()}


def extract_7z(file_path):
"""解压 .7z 文件到内存"""
with py7zr.SevenZipFile(file_path, mode='r') as seven_zip_ref:
return {name: data.read() for name, data in seven_zip_ref.readall().items()}


def recursive_unzip(file_path, output_names=None):
"""递归解压缩文件,并记录所有解压的文件名(不带后缀)"""
if output_names is None:
output_names = []

if file_path.endswith('.zip'):
print(f"解压 ZIP 文件: {file_path}")
extracted_files = extract_zip(file_path)
elif file_path.endswith('.tar'):
print(f"解压 TAR 文件: {file_path}")
extracted_files = extract_tar(file_path)
elif file_path.endswith('.tar.gz'):
print(f"解压 TAR.GZ 文件: {file_path}")
extracted_files = extract_tar_gz(file_path)
elif file_path.endswith('.7z'):
print(f"解压 7Z 文件: {file_path}")
extracted_files = extract_7z(file_path)
else:
print(f"不支持的文件格式: {file_path}")
return output_names

for name, data in extracted_files.items():
print(f"处理文件: {name}")
# 去掉文件后缀并记录文件名
file_name_without_ext = os.path.splitext(name)[0]
output_names.append(file_name_without_ext) # 记录解压的文件名(不带后缀)

if name.endswith(('.zip', '.tar', '.tar.gz', '.7z')):
# 如果是压缩包,递归解压
with io.BytesIO(data) as buffer:
buffer.seek(0)
temp_file = os.path.join(os.path.dirname(file_path), name)
with open(temp_file, 'wb') as f:
f.write(buffer.read())
recursive_unzip(temp_file, output_names)
os.remove(temp_file) # 删除临时文件
else:
# 如果是普通文件,保存到磁盘
output_path = os.path.join(os.path.dirname(file_path), name)
os.makedirs(os.path.dirname(output_path), exist_ok=True)
with open(output_path, 'wb') as f:
f.write(data)

return output_names


if __name__ == "__main__":
start_file = r"" # 替换为你的压缩包路径
all_extracted_files = recursive_unzip(start_file)

# 输出所有解压的文件名(不带后缀)
print("\n所有解压的文件名(不带后缀):")
for file_name in all_extracted_files[::-1]:
print(file_name,end='')

flag值:

flag{a72dd260-f64d-4116-ab50-b26b40d69883}

 

misc EzMisc(fail)

操作内容:

ftp流量,一个enc,一个flag.7z,一个秘钥证书,然后就没有然后了,解密失败

misc 音频的秘密

操作内容:

提示:deepsound弱密码(无敌了,找半天key没找到)

密码123

flag.zip,爆破无果,发现加密算法zipcrypto store,且是png,字节充足,用明文攻击

得到的png图片,zsteg

flag值:

flag{Y1_Shun_jian_Fa_ZE_Dian_Fu}

 

我哪会密码,我只会打原题和gpt-_-

crypto funny_rsa

操作内容:

Gpt秒了,fake flag字符串都出来了,怎么可能是fake

中间那串long_to_bytes就行

如该题使用自己编写的脚本代码请详细写出,不允许截图

import random

import math

from Crypto.Util.number import bytes_to_long, long_to_bytes

# 假设我们已经得到了 funny1, funny2, funny3, funny4

funny1 = -17696257697673533517695215344482784803953262308315416688683426036407670627060768442028628137969719289734388098357659521255966031131390425549974547376165392147394271974280020234101031837837842620775164967619688351222631803585213762205793801828461058523503457022704948803795360591719481537859524689187847958423587638744086265395438163720708785636319741908901866136858161996560525252461619641697255819255661269266471689541673348377717503957328827459396677344554172542244540931545166846117626585580964318010181586516365891413041095399344533013057011854734701706641516027767197631044458866554524544179750101814734153116374

funny2 = 23686728880494758233026798487859622755203105120130180108222733038275788082047755828771429849079142070779731875136837978862880500205129022165600511611807590195341629179443057553694284913974985006590617143873019530710952420242412437467917519539591683898715990297750494900923245055632544763410401540518654522017115269508183482044872091052235608170710105631742176900306097734799793264202179181242015892763311753674799273300604804820015447161950996038795518844564861004398396796284113803759208011

funny3 = 419166458284161364374927086939132546372091965414091344286510440034452974193054721041229068769658972346759176374539266235862042787888391905466876330331208651698002159575012622762558316612596034044109738533275009086940744966244759977014078484433213617582101347769476703012517531619023366639507114909172774156647998737369356116119513795863130218094614475699956104117183821832339358478426978211282822163928764161915824622224165694904342224081321345691796882691318330781141960650263488927837990954860719950761728580780956673732592771855694502630374907978111094148614378212006604233062606116168868545120407836000858982789824582335703891535021579560434875457656655941164757860852341484554015214879991896412137447010444797452119431147303295803678311972500421396900616845556636124424993090559354406417222700637726789045926994792374756038517484548544506630672251868349748176389591615802039026216656891403871728516658502023897343287181822303758976641229952646993446276281728919020747050486979968215989594984778920359425264076558022228448529089047021814759587052098774273578311709416672952218680244714492318709603579024

funny4 = 13541898381047120826573743874105965191304100799517820464813250201030319771155430755606644860103469823030581858410957600027665504533335597988508084284252510961847999525811558651340906333101248760970154440885012717108131962658921396549020943832983712611749095468180648011521808106480590665594160479324931351996812185581193608244652792936715504284312172734662364676167010674359243219959129435127950232321130725013160026977752389409620674167037650367196748592335698164875097139931376389630867192761783936757260359606379088577977154378217235326249540098268616890307702288393952949444753648206049856544634755301197410481479

# 推导 n

n = (funny3 + 1025) // funny2

# 恢复 p + q

# 由于 random.randint(-1025, +1025) 是一个小范围的随机数,我们可以尝试多次

for delta in range(-1025, 1026):

p_plus_q = funny1 + n - delta

# 解二次方程 x^2 - (p + q) * x + n = 0

discriminant = p_plus_q**2 - 4 * n

if discriminant < 0:

continue

sqrt_discriminant = math.isqrt(discriminant) # 使用 math.isqrt 计算整数平方根

p = (p_plus_q + sqrt_discriminant) // 2

q = (p_plus_q - sqrt_discriminant) // 2

if p * q == n:

break

# 计算 phi(n)

phi_n = (p - 1) * (q - 1)

# 计算私钥 d

d = pow(65537, -1, phi_n) # 使用 pow 计算模逆

# 解密 hint

hint = pow(funny4, d, n)

hint = long_to_bytes(hint)

print(hint)

# 恢复 m

m_times_hint = funny2

m_times_n_times_hint = funny3 + 1025

m_times_n = m_times_n_times_hint // bytes_to_long(hint)

m = m_times_n // n

m = long_to_bytes(m)

print("Decrypted message:", m.decode())

print(long_to_bytes(5044833682931814367881036090727702841234957943094051805420875375031047763007750978962055801191968383860156687597666360268370292861))

flag值:

flag{aB3-CdE7_FgH9-iJkLmNoPqRsT-UvWxYz1234567890}

crypto signtime

操作内容:

屯flag差点翻车

好像只能打The time is 1:1

如该题使用自己编写的脚本代码请详细写出,不允许截图

import socket
from hashlib import sha1
from Crypto.Util.number import bytes_to_long
from ecdsa.ecdsa import generator_192

# 服务器地址和端口
HOST = "47.93.12.9"
PORT = 36876

# 椭圆曲线的阶
n = generator_192.order()

def recv_until(sock, delimiter):
"""接收数据,直到遇到指定的分隔符"""
data = b""
delimiter_bytes = delimiter.encode() # 将分隔符转换为字节类型
while delimiter_bytes not in data:
data += sock.recv(1)
return data.decode() # 将接收到的字节数据解码为字符串

def send_option(sock, option):
"""发送选项到服务器"""
sock.sendall(option.encode() + b"\n")

def extract_signature(response):
"""从服务器响应中提取签名信息"""
import re
r = re.search(r"'r': '([^']+)'", response)
s = re.search(r"'s': '([^']+)'", response)
time = re.search(r"'time': '([^']+)'", response)
if r and s and time:
return {
"r": int(r.group(1), 16),
"s": int(s.group(1), 16),
"time": time.group(1),
}
return None

def derive_private_key(r, s, message):
"""推导私钥"""
message_hash = bytes_to_long(sha1(message.encode()).digest())
for k in range(100, 160): # k 的范围是 [100, 159]
try:
r_inv = pow(r, -1, n)
d = (s * k - message_hash) * r_inv % n
if 1 <= d < n:
return d, k
except:
continue
return None, None

def main():
# 连接到服务器
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))

# 接收欢迎信息
print(recv_until(sock, "Enter your option: "))

# 第一次输入:获取签名
send_option(sock, "sign_time")
response = recv_until(sock, "Enter your option: ")
print(response)

# 提取签名信息
signature = extract_signature(response)
if not signature:
print("无法提取签名信息!")
return

r, s, message = signature["r"], signature["s"], signature["time"]
print(f"提取的签名信息: r={hex(r)}, s={hex(s)}, message='{message}'")

# 推导私钥
d, k = derive_private_key(r, s, message)
if not d:
print("无法推导私钥!")
return

print(f"推导出的私钥: {hex(d)} (k={k})")

# 第二次输入:提交私钥
send_option(sock, "I kown the secret")
print(recv_until(sock, "Enter the secret: "))

# 发送私钥
sock.sendall(hex(d).encode() + b"\n")

# 接收 flag
flag_response = recv_until(sock, "\n")
print(flag_response)

# 关闭连接
sock.close()

if __name__ == "__main__":
main()

flag值:

flag{54dec758-c8a9-4513-8a42-4dd5f0a586c1}

 

pwn riya

操作内容:

(不会pwn)本身是瞎打出来的,看到ida几个数字就开打了

输入n时会进label10,里面直接sh执行文件了

flag值:

flag{b654b328-9443-457d-b960-b3b1b7e97f99}

 

web easy_php

操作内容:

点一下,源码到手

本身看题目想打phar 的,结果发现这么多人秒出,感觉不对劲

File.php是读文件的

本身../../../flag,会ban,写hacker

flag值:

flag{a16dcb7549915546893a27a6d7927615}

posted @   ^cyi^  阅读(98)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2024-01-19 压缩包
点击右上角即可分享
微信分享提示