也是代表Sloth参加了,学长们没来,去了三个web手,我可以算半个密码手?两个web学弟干瞪眼……
还是太菜了,QWQ,最后放榜,好像排到了98……

爆零了这边,QWQ

明面上去打比赛,实际上去银川旅游(bushi)

初始谜题1

题目

from sympy import Mod, Integer
from sympy.core.numbers import mod_inverse

# 模数
N_HEX = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"
MODULUS = Integer(int(N_HEX, 16))
MSG_PREFIX = "CryptoCup message:"

# 加密函数
def encrypt_message(message, key):
# 添加前缀
message_with_prefix = MSG_PREFIX + message
message_bytes = message_with_prefix.encode('utf-8')
message_len = len(message_bytes)
num_blocks = (message_len + 15) // 16
blocks = [message_bytes[i * 16:(i + 1) * 16] for i in range(num_blocks)]

# 进行0填充
blocks[-1] = blocks[-1].ljust(16, b'\x00')

encrypted_blocks = []

k = key

# 加密每个分组
for block in blocks:
block_int = int.from_bytes(block, byteorder='big')
encrypted_block_int = Mod(block_int * k, MODULUS)
encrypted_blocks.append(encrypted_block_int)
k += 1 # 密钥自增1

# 将加密后的分组连接成最终的密文
encrypted_message = b''.join(
int(block_int).to_bytes(32, byteorder='big') for block_int in encrypted_blocks
)

return encrypted_message

# 解密函数
def decrypt_message(encrypted_message, key):
num_blocks = len(encrypted_message) // 32
blocks = [encrypted_message[i * 32:(i + 1) * 32]
for i in range(num_blocks)]

decrypted_blocks = []

k = key

# 解密每个分组
for block in blocks:
block_int = int.from_bytes(block, byteorder='big')
key_inv = mod_inverse(k, MODULUS)
decrypted_block_int = Mod(block_int * key_inv, MODULUS)
decrypted_blocks.append(decrypted_block_int)
k += 1 # 密钥自增1

# 将解密后的分组连接成最终的明文
decrypted_message = b''.join(
int(block_int).to_bytes(16, byteorder='big') for block_int in decrypted_blocks
)

# 去除前缀
if decrypted_message.startswith(MSG_PREFIX.encode('utf-8')):
decrypted_message = decrypted_message[len(MSG_PREFIX):]

return decrypted_message.rstrip(b'\x00').decode('utf-8')

# 测试
initial_key = Integer(
0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0)
message = "Hello, this is a test message."
print("Original Message:", message)

# 加密
encrypted_message = encrypt_message(message, initial_key)
print("Encrypted Message (hex):", encrypted_message.hex())

# 解密
decrypted_message = decrypt_message(encrypted_message, initial_key)
print("Decrypted Message:", decrypted_message)

根据给定的明文前缀b'CryptoCup messag',进行key的还原
exp如下

from Crypto.Util.number import *
from Crypto.Util.number import *
from sympy import Mod, Integer
from sympy.core.numbers import mod_inverse
N_HEX = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"
MODULUS = Integer(int(N_HEX, 16))
MSG_PREFIX = "CryptoCup message:"

def decrypt_message(encrypted_message, key):
num_blocks = len(encrypted_message) // 32
blocks = [encrypted_message[i * 32:(i + 1) * 32]
for i in range(num_blocks)]

decrypted_blocks = []

k = key

# 解密每个分组
for block in blocks:
block_int = int.from_bytes(block, byteorder='big')
key_inv = mod_inverse(k, MODULUS)
decrypted_block_int = Mod(block_int * key_inv, MODULUS)
decrypted_blocks.append(decrypted_block_int)
k += 1 # 密钥自增1

# 将解密后的分组连接成最终的明文
decrypted_message = b''.join(
int(block_int).to_bytes(16, byteorder='big') for block_int in decrypted_blocks
)

# 去除前缀
if decrypted_message.startswith(MSG_PREFIX.encode('utf-8')):
decrypted_message = decrypted_message[len(MSG_PREFIX):]

return decrypted_message.rstrip(b'\x00').decode('utf-8')

initial_key = Integer(
0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0)
test = 0x534ed400954f43256f50e9224595608726b3f016f8cece29ad868085526be54b1449d8eb3400703f429ae51b9675ce74aa8548240f176fe65b4ae4632f00eb157d852e4662abbb84a8a8914519beca68dbd6c138283a67d2b677c148ad396006
test = long_to_bytes(test)
for i in range(0, len(test), 32):
block = b'CryptoCup messag'
block_int = int.from_bytes(block, byteorder='big')
inv = mod_inverse(block_int, MODULUS)
test_key = Mod(bytes_to_long(test[i:i+32]) * inv, MODULUS)
break

if test_key == initial_key:
print("yes ! the key is right !")

key = 43655547535019309311915020807035649695231180783817469867892363164058723476078
enc = 0x7c1a0a2335fb3aff5262a4bf18af5fa928dd51895fe7ccc5307a275accbe0a6ef6f4f304a0e7cbc20a178ca9c2c19fe241d39d42c197e496c5ccd80969969d4c541e7dc2012205c051093de21f93799b3fe5cc65a5313c84deecde7dcdcc32eb15476181252d7d16a9996c96c5668f96d0139c22bcf7569a77ace1d25ae33d7d
enc = long_to_bytes(enc)
decrypted_message = decrypt_message(enc, key)
print("Decrypted Message:", decrypted_message)

初始谜题2(未解)

题目

import binascii
from gmssl import sm3

# 读取HMAC key文件
def read_hmac_key(file_path):
with open(file_path, 'rb') as f:
hmac_key = f.read().strip()
return hmac_key

# 生成token
def generate_token(hmac_key, counter):
# 如果HMAC_KEY长度不足32字节,则在末尾补0,超过64字节则截断
if len(hmac_key) < 32:
hmac_key = hmac_key.ljust(32, b'\x00')
elif len(hmac_key) > 32:
hmac_key = hmac_key[:32]

# 将计数器转换为字节表示
counter_bytes = counter.to_bytes((counter.bit_length() + 7) // 8, 'big')
# print("counter_bytes:", binascii.hexlify(counter_bytes))

tobe_hashed = bytearray(hmac_key + counter_bytes)

# print("tobe_hashed:", binascii.hexlify(tobe_hashed))

# 使用SM3算法计算哈希值
sm3_hash = sm3.sm3_hash(tobe_hashed)

# 将SM3的哈希值转换为十六进制字符串作为token
token = sm3_hash

return token

current_counter = 0

def verify_token(hmac_key, counter, token):
# 生成token
generated_token = generate_token(hmac_key, counter)
global current_counter
# 比较生成的token和输入的token是否相同
if generated_token == token:
if counter & 0xFFFFFFFF > current_counter:
current_counter = counter & 0xFFFFFFFF
print("current_counter: ", hex(current_counter))
return "Success"
else:
return "Error: counter must be increasing"
else:
return "Error: token not match"

# 假设HMAC key文件路径
hmac_key_file = 'hmac_key.txt'
# 假设计数器值
counter = 0x12345678

# 读取HMAC key
hmac_key = read_hmac_key(hmac_key_file)

# 生成token
token = generate_token(hmac_key, counter)
print("Generated token:", token)
print(verify_token(hmac_key, counter, token))
# counter: 0x7f802490
# token: 0x01aa2370b68bbb01bff7b1e09afe67938d83d33c650c14de91e60c6350f2b8e2

目的是伪造token,提示哈希长度拓展攻击,这个暂时没认真钻研过……

初始谜题3

题目

import sympy as sp
import random

# 设置参数
n = 16 # 向量长度
q = 251 # 模数

# 生成随机噪声向量e
e = sp.Matrix(sp.randMatrix(n, 1, min=0, max=1)) # 噪声向量

# 生成随机n维私钥向量s和n*n矩阵A
s = sp.Matrix(sp.randMatrix(n, 1, min=0, max=q - 1)) # 私钥向量
Temp = sp.Matrix(sp.randMatrix(n, n, min=0, max=q - 1)) # 中间变量矩阵Temp
A = Temp.inv_mod(q) # 计算矩阵Temp在模 q 下的逆矩阵作为A

# 计算n维公钥向量b
b = (A * s + e) % q # 公钥向量b = A * s + e

# 加密函数
def encrypt(message, A, b):
m_bin = bin(message)[2:].zfill(n) # 将消息转换为16比特的二进制字符串
m = sp.Matrix([int(bit) for bit in m_bin]) # 转换为SymPy矩阵
x = sp.Matrix(sp.randMatrix(n, n, min=0, max=q // (n * 4))) # 随机产生一个n*n的矩阵x
e1 = sp.Matrix(sp.randMatrix(n, 1, min=0, max=1)) # 随机产生一个n维噪声向量e
c1 = (x * A) % q # 密文部分c1 = x * A
c2 = (x * b + e1 + m * (q // 2)) % q # 密文部分c2 = x * b + e1 + m * q/2
return c1, c2

# 解密函数
def decrypt(c1, c2, s):
m_dec = (c2 - c1 * s) % q
m_rec = m_dec.applyfunc(lambda x: round(2 * x / q) % 2) # 还原消息
m_bin = ''.join([str(bit) for bit in m_rec]) # 将SymPy矩阵转换为二进制字符串
m_rec_int = int(m_bin, 2) # 将二进制字符串转换为整数
return m_rec_int

# 测试加解密
message = random.randint(0, 2 ** n - 1) # 要加密的消息,随机生成一个16比特整数
c1, c2 = encrypt(message, A, b) # 加密

print("原始消息: ", message)
print("公钥A=sp.", A)
print("公钥b=sp.", b)
print("密文c1=sp.", c1)
print("密文c2=sp.", c2)

decrypted_message = decrypt(c1, c2, s)
print("解密后的消息: ", decrypted_message) # 输出解密后的消息

c1 = (x * A) % q无噪声干扰
x = (c1*A.inv_mod(q)) % q得到x
然后就可以尝试还原flag
exp如下

from Crypto.Util.number import *
import sympy as sp
n = 16 # 向量长度
q = 251 # 模数

A = sp.Matrix([[105, 89, 18, 60, 188, 191, 82, 52, 202, 219, 237, 130, 219, 182, 150, 188], [20, 238, 248, 53, 181, 54, 37, 165, 217, 214, 10, 97, 26, 159, 182, 229], [152, 138, 120, 12, 217, 142, 102, 35, 99, 30, 110, 87, 248, 126, 86, 244], [205, 87, 97, 108, 155, 244, 203, 146, 242, 58, 77, 42, 26, 11, 5, 61], [70, 37, 201, 185, 242, 154, 96, 146, 50, 108, 42, 186, 58, 44, 24, 199], [141, 189, 16, 171, 174, 38, 224, 9, 155, 221, 16, 136, 39, 28, 141, 142], [184, 6, 139, 103, 147, 187, 225, 163, 121, 34, 195, 66, 7, 234, 106, 228], [235, 136, 194, 7, 132, 173, 18, 242, 130, 136, 165, 73, 213, 141, 25, 0], [
31, 135, 155, 153, 54, 88, 155, 36, 240, 190, 75, 24, 180, 64, 117, 124], [178, 165, 202, 150, 240, 235, 130, 200, 171, 126, 2, 206, 66, 45, 69, 17], [9, 68, 29, 44, 111, 44, 130, 171, 83, 13, 249, 192, 119, 178, 32, 217], [243, 244, 47, 94, 100, 245, 234, 103, 222, 66, 73, 126, 226, 48, 94, 13], [222, 75, 7, 108, 70, 216, 203, 92, 173, 111, 149, 152, 140, 71, 242, 135], [241, 42, 202, 9, 29, 95, 174, 131, 104, 114, 209, 109, 111, 219, 61, 233], [98, 4, 19, 214, 55, 38, 183, 28, 98, 218, 79, 95, 208, 190, 142, 176], [78, 0, 13, 65, 10, 141, 76, 114, 207, 226, 141, 148, 131, 98, 4, 88]])

b = sp.Matrix([[21], [239], [87], [61], [160], [26], [229], [222], [
112], [216], [129], [91], [199], [181], [196], [19]])

c1 = sp.Matrix([[72, 91, 249, 87, 237, 196, 241, 146, 75, 108, 128, 192, 10, 105, 154, 140], [14, 131, 170, 198, 238, 120, 23, 242, 0, 83, 115, 64, 44, 241, 83, 112], [187, 132, 154, 137, 232, 165, 128, 2, 237, 239, 124, 184, 126, 188, 173, 150], [169, 178, 164, 177, 77, 35, 64, 63, 53, 82, 176, 141, 205, 7, 33, 72], [64, 206, 126, 198, 144, 42, 53, 183, 101, 218, 111, 39, 135, 164, 47, 181], [33, 2, 223, 70, 212, 131, 215, 155, 243, 15, 183, 227, 113, 66, 242, 38], [192, 210, 131, 161, 213, 68, 216, 168, 95, 18, 190, 174, 220, 148, 191, 230], [88, 216, 134, 40, 156, 95, 210, 87, 94, 74, 18, 31, 124, 191, 197, 92], [
151, 222, 133, 56, 240, 89, 220, 221, 23, 109, 162, 206, 225, 134, 44, 142], [25, 242, 210, 33, 250, 62, 85, 134, 189, 232, 86, 113, 56, 239, 57, 31], [220, 18, 168, 173, 139, 192, 185, 237, 169, 15, 39, 119, 205, 72, 237, 2], [178, 2, 215, 71, 58, 161, 154, 207, 45, 56, 186, 51, 25, 116, 81, 43], [20, 103, 20, 234, 145, 161, 156, 99, 114, 85, 16, 162, 34, 19, 45, 92], [193, 77, 56, 233, 34, 76, 47, 163, 106, 228, 66, 63, 100, 223, 211, 123], [69, 208, 156, 39, 236, 39, 25, 166, 242, 31, 103, 171, 154, 220, 140, 93], [72, 125, 173, 20, 70, 200, 101, 69, 74, 58, 143, 40, 117, 235, 124, 90]])

c2 = sp.Matrix([[1], [89], [8], [219], [220], [114], [73], [130], [
142], [147], [250], [167], [113], [237], [61], [201]])

x = (c1*A.inv_mod(q)) % q
cc = (x * b) % q
for i in cc:
print(i, end=' ')
print()
for i in cc:
print((i+125) % 251, end=' ')
print()
for i in c2:
print(i, end=' ')
print()
# 观察,手动恢复16位的flag
a = int('1111110100010010', 2)
print(hex(a)[2:])

压缩包密码加密代码(未解)

emmm怎么说呢,我不会逆这个代码QWQ,然后就摆烂了,差这一题应该就有奖了:(

#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>

#define ROUND 16

// S-Box 16x16
int sBox[16] =
{
2, 10, 4, 12,
1, 3, 9, 14,
7, 11, 8, 6,
5, 0, 15, 13};

// 将十六进制字符串转换为 unsigned char 数组
void hex_to_bytes(const char *hex_str, unsigned char *bytes, size_t bytes_len)
{
size_t hex_len = strlen(hex_str);
if (hex_len % 2 != 0 || hex_len / 2 > bytes_len)
{
fprintf(stderr, "Invalid hex string length.\n");
return;
}

for (size_t i = 0; i < hex_len / 2; i++)
{
sscanf(hex_str + 2 * i, "%2hhx", &bytes[i]);
}
}

// 派生轮密钥
void derive_round_key(unsigned int key, unsigned char *round_key, int length)
{

unsigned int tmp = key;
for (int i = 0; i < length / 16; i++)
{
memcpy(round_key + i * 16, &tmp, 4);
tmp++;
memcpy(round_key + i * 16 + 4, &tmp, 4);
tmp++;
memcpy(round_key + i * 16 + 8, &tmp, 4);
tmp++;
memcpy(round_key + i * 16 + 12, &tmp, 4);
tmp++;
}
}

// 比特逆序
void reverseBits(unsigned char *state)
{
unsigned char temp[16];
for (int i = 0; i < 16; i++)
{
unsigned char byte = 0;
for (int j = 0; j < 8; j++)
{
byte |= ((state[i] >> j) & 1) << (7 - j);
}
temp[15 - i] = byte;
}
for (int i = 0; i < 16; i++)
{
state[i] = temp[i];
}
}

void sBoxTransform(unsigned char *state)
{
for (int i = 0; i < 16; i++)
{
int lo = sBox[state[i] & 0xF];
int hi = sBox[state[i] >> 4];
state[i] = (hi << 4) | lo;
}
}

void leftShiftBytes(unsigned char *state)
{
unsigned char temp[16];
for (int i = 0; i < 16; i += 4)
{
temp[i + 0] = state[i + 2] >> 5 | (state[i + 1] << 3);
temp[i + 1] = state[i + 3] >> 5 | (state[i + 2] << 3);
temp[i + 2] = state[i + 0] >> 5 | (state[i + 3] << 3);
temp[i + 3] = state[i + 1] >> 5 | (state[i + 0] << 3);
}
for (int i = 0; i < 16; i++)
{
state[i] = temp[i];
}
}

// 轮密钥加
void addRoundKey(unsigned char *state, unsigned char *roundKey, unsigned int round)
{
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 8; j++)
{
state[i] ^= ((roundKey[i + round * 16] >> j) & 1) << j;
}
}
}

// 加密函数
void encrypt(unsigned char *password, unsigned int key, unsigned char *ciphertext)
{
unsigned char roundKeys[16 * ROUND] = {}; //

// 生成轮密钥
derive_round_key(key, roundKeys, 16 * ROUND);

// 初始状态为16字节的口令
unsigned char state[16]; // 初始状态为16字节的密码
memcpy(state, password, 16); // 初始状态为密码的初始值

// 迭代加密过程
for (int round = 0; round < ROUND; round++)
{
reverseBits(state);
sBoxTransform(state);
leftShiftBytes(state);
addRoundKey(state, roundKeys, round);
}

memcpy(ciphertext, state, 16);
}

void main()
{
unsigned char password[] = "pwd:xxxxxxxxxxxx"; // 口令明文固定以pwd:开头,16字节的口令
unsigned int key = 0xF0FFFFFF; // 4字节的密钥
unsigned char ciphertext[16]; // 16字节的状态

printf("Password: \n");
printf("%s\n", password);

encrypt(password, key, ciphertext);

// 输出加密后的结果
printf("Encrypted password:\n");
for (int i = 0; i < 16; i++)
{
printf("%02X", ciphertext[i]);
}
printf("\n");
}