RCSC Salami Contest 2025
Cryptography: Simple as you like
RCSC Salami Contest 2025
Cryptography: Simple as you like
Contest file: crypto_easy.zip
After analyzing the source code, you may discover that the flag is XORed with a randomly generated key of length 5. Since the key is random, recovering the exact key directly would be quite challenging.
However, we know that all flags follow the format rcscsalamictf{some_text}, meaning the first fourteen bytes of the plaintext are always rcscsalamictf{. This allows us to recover the first fourteen bytes of the key by XORing them with the corresponding encrypted bytes.
For the remaining fifteenth and sixteenth byte of the key, we can brute-force all possible values.
This script will bruteforce all possible value and then save to recovered_keys.txt file.
def recover_key(enc, known_plaintext):
key = bytearray(len(known_plaintext))
for i in range(len(known_plaintext)):
key[i] = enc[i] ^ known_plaintext[i]
return key
def bruteforce_15_16_byte(enc, known_plaintext):
with open("recovered_keys.txt", "w") as f:
for i in range(32, 127): # for 15th byte
for j in range(32, 127): # for 16th byte
candidate_plaintext = known_plaintext + bytes([i, j])
recovered_key_part = recover_key(enc[:16], candidate_plaintext)
result = f"{recovered_key_part.hex()}\n"
f.write(result)
known_plaintext = b'rcscsalamictf{' # The first 14 characters of the original message
enc = bytes.fromhex("5dfa063ecd32c430ade4e1b70ba91eda7dc6442ee13d98259fbef4a61fab76841cbe0602dd26d80ef0ebdd975ee619885aed2a3e8e3dcf23f4f9b1b032b4769870e04528cc0cdb24a3eee7b01eaf") # Replace with actual encrypted data
bruteforce_15_16_byte(enc, known_plaintext)
Using each potential key, we will decrypt the flag and obtain multiple possible outputs. Here is the script:
def xor_decrypt(ciphertext, key):
"""XOR the ciphertext with the given key."""
decrypted = bytearray()
for i in range(len(ciphertext)):
decrypted.append(ciphertext[i] ^ key[i % len(key)])
return bytes(decrypted)
def try_decrypt_with_keys(encrypted_hex, keys_hex, output_file):
"""Try to decrypt the encrypted text with all given keys and save results."""
encrypted_data = bytes.fromhex(encrypted_hex)
with open(output_file, "w", encoding="utf-8") as f:
for key_hex in keys_hex:
key = bytes.fromhex(key_hex)
decrypted_data = xor_decrypt(encrypted_data, key)
try:
decrypted_text = decrypted_data.decode('utf-8')
result = f"Decrypted with key {key_hex}: {decrypted_text}\n"
except UnicodeDecodeError:
result = f"Decrypted with key {key_hex}: (binary output) {decrypted_data.hex()}\n"
print(result.strip())
f.write(result)
if __name__ == '__main__':
encrypted_hex = "5dfa063ecd32c430ade4e1b70ba91eda7dc6442ee13d98259fbef4a61fab76841cbe0602dd26d80ef0ebdd975ee619885aed2a3e8e3dcf23f4f9b1b032b4769870e04528cc0cdb24a3eee7b01eaf"
with open("recovered_keys.txt", "r") as file:
keys_hex = [line.strip() for line in file.readlines() if line.strip()]
try_decrypt_with_keys(encrypted_hex, keys_hex, "decrypted_output.txt")
Since all valid flags follow the standard rcscsalamictf{…} format, we can manually analyze the results to identify the correct flag.

flag is marked here
After analyzing you can find the correct flag.
메타데이터
- post_id
- c46a4c11706d
- slug
- rcsc-salami-contest-2025-c46a4c11706d
- url
- https://medium.com/@MrX2025/rcsc-salami-contest-2025-c46a4c11706d
- canonical_url
- https://medium.com/@MrX2025/rcsc-salami-contest-2025-c46a4c11706d
- author_url
- https://medium.com/@MrX2025
- status
- ok
- fetched_at
- 2026-06-15 20:49:13