Cryptography
krotate (463 pts)
Description
We managed to intercep communication with a critical mission. We can't decipher it but managed to break into the system and recover what looks like part of the communication and an algorithm for it.
Can you get the full message?
Solution
Given source code below.
from Crypto.Random import get_random_bytes
KEY_LEN = 100
key = get_random_bytes(KEY_LEN)
R = 0x01
def RGEN():
global R
R = ((R << 1) ^ (0x71 if (R & 0x80) else 0)) & 0xFF
return R
def xor_text(text, key):
return bytes([text[i] ^ key[i] for i in range(len(text))])
def next_key(key):
return bytes([key[i] ^ RGEN() for i in range(len(key))])
def encrypt(text, key):
ciphertext = b""
blocks = [text[i : i + KEY_LEN] for i in range(0, len(text), KEY_LEN)]
for block in blocks:
ciphertext += xor_text(block, key)
key = next_key(key)
return ciphertext
# ---
text = b""
with open("text.txt", "rb") as f:
text = f.read()
ciphertext = encrypt(text, key)
with open("ct.txt", "wb") as g:
g.write(ciphertext)Below is the program flow:
Generate random key with length 100 bytes
Split plaintext to block with each block length is 100 bytes
Loop until all encrypted
Xor block plaintext with key
Create new key based on previous key and RGEN function
So if we know the the first generated key we will decrypt the rest ciphertext because the next key is based on previous key. Since it is almost impossible to brute 100 bytes immediately so my idea is brute 4 bytes first key with assumption we can read partial valid "plaintext" that consist of 4 bytes then bruteforce 1 bytes semi automatically. To reduce the possibility we can loop through all blocks and validate only specific index on decrypted text, if those value on specific index on all blocks are printable so it is one of the possible key. For example if we want to get key on index 10 we only validate plaintext on index 10 on block1,block2,..block100, if there is 100 valid printable character at index 10 from all blocks it is one of the possible key.

After getting first 4 bytes key, lets do semi automatic bruteforce for each next byte key.
At the end we will get first 100 bytes key
Then just use it to decrypt the whole ciphertext.

Flag: CTF{cc64393474865290892e5197153ad6109151d8ee2fd5e316d81b80c3d825bd82}
sat1sf1 (463 pts)
Description
Made my own hashing function sah652.
Here the super-secure hash of my secret: 2033251f4b3161e4455a4c261e3f631e18653c3a6c136e30304037373e6e1f6c6f6448673e686b1e18603d10306d323f3a4b626eee636c3c3c62483592123e6d6c6c3a49ca
Feeling generous to share some hints about my secret that you definitely will not able to recover:
Text length: 69 characters
Flag regex: CTF{[a-f0-9]{64}}
Flag contains somewhere the text: beebeef
Solution
Given source code below
Below is the program flow:
Create delimiter at index 69 by xoring value on index 69
Split to block with each block consist of 8 bytes data
Loop 24 times
Xor all value on each block and store on C
Xor C on index (x+1) with (x + 4) and store on D
Xor original block value with D
Shift value on each row
Do something like mix row (xor value different row)
Xor first value with R
From above flow i assume that SAT/SMT solver can solve this challenge. The idea is trying to get the plaintext by utilizing z3. Below is my script

Flag: CTF{45adda2019d24619435fcb0a0b644f576c8baeffeeb603d1618cdbeebeefaead}
Last updated