glacier ctf 25
This commit is contained in:
138
2025/glacier/rev/c2/dec_rc5_chatgpt.py
Normal file
138
2025/glacier/rev/c2/dec_rc5_chatgpt.py
Normal file
@@ -0,0 +1,138 @@
|
||||
import hashlib
|
||||
import struct
|
||||
|
||||
|
||||
# ----------------------------
|
||||
# RC5 core parameters
|
||||
# ----------------------------
|
||||
W = 32 # word size in bits
|
||||
R = 12 # rounds
|
||||
B = 16 # key bytes (RC5-32/12/16)
|
||||
WORD_MASK = 0xFFFFFFFF
|
||||
BLOCK_SIZE = 8 # 2 * 32-bit words
|
||||
|
||||
|
||||
# ----------------------------
|
||||
# Utility: Rotate left/right
|
||||
# ----------------------------
|
||||
def rotl(x, n):
|
||||
return ((x << n) & WORD_MASK) | (x >> (32 - n))
|
||||
|
||||
|
||||
def rotr(x, n):
|
||||
return ((x >> n) | (x << (32 - n))) & WORD_MASK
|
||||
|
||||
|
||||
# ----------------------------
|
||||
# Key Expansion
|
||||
# ----------------------------
|
||||
def expand_key(key: bytes):
|
||||
# Constants for RC5 with w=32
|
||||
P32 = 0xB7E15163
|
||||
Q32 = 0x9E3779B9
|
||||
|
||||
# Convert key into c 32-bit words L[0..c-1]
|
||||
c = max(1, B // 4)
|
||||
L = list(struct.unpack("<" + "I" * c, key))
|
||||
|
||||
# Initialize S-array
|
||||
t = 2 * (R + 1)
|
||||
S = [0] * t
|
||||
S[0] = P32
|
||||
for i in range(1, t):
|
||||
S[i] = (S[i - 1] + Q32) & WORD_MASK
|
||||
|
||||
# Mix key into S
|
||||
i = j = 0
|
||||
A = Bv = 0
|
||||
for _ in range(3 * max(t, c)):
|
||||
A = S[i] = rotl((S[i] + A + Bv) & WORD_MASK, 3)
|
||||
Bv = L[j] = rotl((L[j] + A + Bv) & WORD_MASK, (A + Bv) & 31)
|
||||
i = (i + 1) % t
|
||||
j = (j + 1) % c
|
||||
|
||||
return S
|
||||
|
||||
|
||||
# ----------------------------
|
||||
# Block Encrypt/Decrypt
|
||||
# ----------------------------
|
||||
def rc5_encrypt_block(block: bytes, S):
|
||||
A, B = struct.unpack("<II", block)
|
||||
A = (A + S[0]) & WORD_MASK
|
||||
B = (B + S[1]) & WORD_MASK
|
||||
|
||||
for i in range(1, R + 1):
|
||||
A = (rotl(A ^ B, B & 31) + S[2 * i]) & WORD_MASK
|
||||
B = (rotl(B ^ A, A & 31) + S[2 * i + 1]) & WORD_MASK
|
||||
|
||||
return struct.pack("<II", A, B)
|
||||
|
||||
|
||||
def rc5_decrypt_block(block: bytes, S):
|
||||
A, B = struct.unpack("<II", block)
|
||||
|
||||
for i in range(R, 0, -1):
|
||||
B = rotr((B - S[2 * i + 1]) & WORD_MASK, A & 31) ^ A
|
||||
A = rotr((A - S[2 * i]) & WORD_MASK, B & 31) ^ B
|
||||
|
||||
B = (B - S[1]) & WORD_MASK
|
||||
A = (A - S[0]) & WORD_MASK
|
||||
|
||||
return struct.pack("<II", A, B)
|
||||
|
||||
|
||||
# ----------------------------
|
||||
# CBC mode + PKCS#7
|
||||
# ----------------------------
|
||||
|
||||
def rc5_cbc_encrypt(key: bytes, iv: bytes, plaintext: bytes) -> bytes:
|
||||
if len(iv) != BLOCK_SIZE:
|
||||
raise ValueError("IV must be 8 bytes")
|
||||
|
||||
S = expand_key(key)
|
||||
|
||||
blocks = []
|
||||
prev = iv
|
||||
|
||||
for i in range(0, len(plaintext), BLOCK_SIZE):
|
||||
block = plaintext[i:i + BLOCK_SIZE]
|
||||
x = bytes(a ^ b for a, b in zip(block, prev))
|
||||
enc = rc5_encrypt_block(x, S)
|
||||
blocks.append(enc)
|
||||
prev = enc
|
||||
|
||||
return b"".join(blocks)
|
||||
|
||||
|
||||
def rc5_cbc_decrypt(key: bytes, iv: bytes, ciphertext: bytes) -> bytes:
|
||||
if len(iv) != BLOCK_SIZE:
|
||||
raise ValueError("IV must be 8 bytes")
|
||||
if len(ciphertext) % BLOCK_SIZE != 0:
|
||||
raise ValueError("Ciphertext not aligned to block size")
|
||||
|
||||
S = expand_key(key)
|
||||
blocks = []
|
||||
prev = iv
|
||||
|
||||
for i in range(0, len(ciphertext), BLOCK_SIZE):
|
||||
block = ciphertext[i:i + BLOCK_SIZE]
|
||||
dec = rc5_decrypt_block(block, S)
|
||||
x = bytes(a ^ b for a, b in zip(dec, prev))
|
||||
blocks.append(x)
|
||||
prev = block
|
||||
|
||||
return b"".join(blocks)
|
||||
|
||||
KEY = bytes.fromhex("99 90 9c 9d d5 8c 81 82 91 98 94 95 dd 84 89 9a")
|
||||
ITERATIONS = 85454
|
||||
key_bytes = hashlib.pbkdf2_hmac("sha256", KEY, b"", ITERATIONS, dklen=16)
|
||||
|
||||
print(f"[+] Key: {key_bytes.hex()}")
|
||||
iv = bytes.fromhex("bb7cdd2e104c3410")
|
||||
with open("./output/85454_bb7cdd2e104c3410.enc", "rb") as f:
|
||||
ct = f.read()
|
||||
|
||||
dec = rc5_cbc_decrypt(key_bytes, iv, ct)
|
||||
print("decrypted:", dec)
|
||||
|
||||
Reference in New Issue
Block a user