-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8db4067
Showing
15 changed files
with
483 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# 熵密杯附件整理-备注 | ||
|
||
## 题目信息 | ||
|
||
三道初始谜题(CTF)带交互机,解出任意一道可访问场景题目。 | ||
|
||
场景题目共4台机器,5个flag | ||
|
||
|
||
|
||
## 场景题目信息 | ||
|
||
### 网络拓扑 | ||
|
||
网络拓扑图不需要逐一解出即全部给出 | ||
|
||
![](网络拓扑.png) | ||
|
||
|
||
|
||
### 场景解题顺序 | ||
|
||
1. 在Gitea上下载到`shangmibei-master.zip`,在其中解出加密口令解压`协同签名源码文件.zip`,得到flag1 | ||
|
||
2. 然后通过`数据库管理系统数据.zip`中的文件破解数据库管理系统服务器,进入后台拿到flag3和附件 | ||
3. 在第一步解出后的附件中可破解协同签名服务器,交互得到flag2 | ||
4. 在第二步得到的附件中解密流量文件,找到flag4 | ||
5. 在完成上述步骤后伪造总经理签名提交给签名提交服务器,得到最终flag5 | ||
|
||
|
||
|
||
### 其他 | ||
|
||
1. 数据库管理系统服务器有用根密钥指定公钥派发证书的register接口 | ||
2. 协同签名服务器交互流程与`总经理协同签名流量包`相同 | ||
3. 签名提交服务器的给定 msg_hash 为`9e810778a6b177c6aa1799365977adfbeef605c19b5ea917527d1541c1339019` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
#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"); | ||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
99F2980AAB4BE8640D8F322147CBA409 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
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) | ||
|
||
|
||
|
||
|
||
|
||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
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)) | ||
|
||
|
||
|
||
|
Binary file not shown.
Oops, something went wrong.