Exclusive

#!/usr/bin/env python3
import os

def splitit(n):
	return (n >> 4), (n & 0xF)

def encrypt(n, key1, key2):
	m, l = splitit(n)
	e = ((m ^ key1) << 4) | (l ^ key2)
	return e

FLAG = open('flag.txt').read().lstrip('wormcon{').rstrip('}')
alpha = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'

assert all(x in alpha for x in FLAG)

otp = int(os.urandom(1).hex(), 16)
otpm, otpl = splitit(otp)

print(f"{otp = }")
cipher = []

for i,ch in enumerate(FLAG):
	if i % 2 == 0:
		enc = encrypt(ord(ch), otpm, otpl)
	else:
		enc = encrypt(ord(ch), otpl, otpm)
	cipher.append(enc)

cipher = bytes(cipher).hex()
print(f'{cipher = }')

open('out.txt','w').write(f'cipher = {cipher}')

Everyone loves XOR because it's easy to use but the cipher becomes vulnerable if you use only a single byte Key. We can easily brute-force the Key and recover our plaintext!

  • Split the otp byte into two halves i.e. otpm = upper nibble(upper 4 bits), otpl = lower nibble(lower 4 bits)

  • Split the plaintext byte into two halves i.e. m = upper nibble, l = lower nibble

  • Makes the XOR encryption and finally joins the ciphertext bytes.

Thus, we can

  • Reverse this and make our decryption function

  • Brute-force the key

  • Try to decrypt the ciphertext and check if all the characters are in the character space or not

Solve Script: solve.py

Flag: wormcon{x0r_n1bbl3_c1ph3r_15_4_h0m3_br3w3d_c1ph3r}

Last updated