Screenshot 0

Challenge Description

We are provided with two files:

  1. script.py — Python script used for XOR encoding the flag.
  2. output.txt — Contains the XOR-encoded flag in hex format.

Our goal: Recover the original flag.


Provided Files

script.py

python
import random
import string
flag = "securinets{fake_flag}"

def send_message(message):
    print(message)

def setup(flag, key):
    xored = ""
    for i in range(len(flag)):
        xored += chr(ord(flag[i]) ^ ord(key[i % len(key)]))
    hex_encoded = xored.encode().hex()
    return hex_encoded

def start():
    key = ''.join(random.choices(string.ascii_letters + string.digits, k=12))
    hex_encoded = setup(flag, key)
    send_message("This XOR encoded text has flag : " + hex_encoded)

if __name__ == '__main__':
    start()

output.txt

python
This XOR encoded text has flag : 10070722081f2d213c2b181a53103b66092930772b2d11511e

First, let’s count the number of bits in the “securinets{“ text. Then, we’ll compare this number with the number of bits in the ciphertext that’s in the script’s output.

Screenshot 1
Screenshot 2

securinets{ == 11 bytes

10070722081f2d213c2b18 == 11 bytes

Screenshot 3

verification:

Screenshot 4

But here we have something important, which is that the key we found is 11 characters long, while the primary key consists of 12 characters.

Screenshot 5

Here we need to create a script that brute force the last character of the key.

python
l="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
xor_flag="10070722081f2d213c2b181a53103b66092930772b2d11511e"
key=""
def from_hex(hex_string):
    try:
        bytes_object = bytes.fromhex(hex_string)
        return bytes_object.decode('utf-8')
    except ValueError as e:
        return f"Error: {e}"
def xor_cipher(text, key):
    if isinstance(text, str):
        text = bytes(text, 'utf-8')
    if isinstance(key, str):
        key = bytes(key, 'utf-8') 

    key_length = len(key)
    extended_key = (key * (len(text) // key_length) + key[:len(text) % key_length])[:len(text)]
    result = bytes([b1 ^ b2 for b1, b2 in zip(text, extended_key)])
    return result
for k in l :
    key="cbdWzvCDHXc"+k
    hexi=from_hex(xor_flag)
    print(xor_cipher(hexi,key))
    print(key)
Screenshot 6

After running the script, we notice that the last character of the key is “b”.

Screenshot 7

Flag : securinets{x0r_1s_s3cur3}

Securinets ISITCOM Friendly-CTF Cicada-3301 Writeup
Whiterose CTF Writeup — TryHackMe