# Intro

This is my write-up of a Cryptography challenge My Magic Numbers on the CTF site 247CTF.com.

# Instructions

Can you recover the secret XOR key we used to encrypt the flag?

# Magic numbers

Magic numbers or magic bytes are usually used to tell the operating system what kind of a file it is dealing with.

A JPG file typically has magic number:

``````FF D8 DD E0
FF D8 FF DB
FF D8 FF E1
FF D8 FF E0 00 10 4A 46 49 46 00 01
FF D8 FF E0
``````

# XOR rules

https://en.wikipedia.org/wiki/Exclusive_or

``````A XOR B = C
C XOR B = A
A XOR C = B
``````

So file XOR jpg magic bytes = key

# Obtaining the key

``````FF D8 FF E0 00 10 4A 46 49 46 00 01 | jpg magic bytes |
b9 14 06 45 71 e0 b5 f7 37 07 cb 85 | encoded file    | XOR
46 cc f9 a5 71 f0 ff b1 7e 41 cb 84 | key             | =
``````

# Decoding the file

Dump the file to hex string file with `xxd` (xxd is a part of vim text editor package):

``````\$ xxd -p my_magic_bytes.jpg.enc > hex
``````

xxd has 16 octet limit per line by default in the output, so newlines will be present. There is -c parameter to control the number of octets per line, but max value is 256, so this would not help in our case.

So to remove the newlines:

``````\$ tr -d '\n' < hex > hexoneline
``````

Use the script to xor the hex with key (I have used it to guess the keys also, the commented out message var):

``````from itertools import cycle

def do_xor(key, message):
message = message.replace(' ', '').decode('hex')
key = ''.join(key.split()[::-1]).decode('hex')

return ''.join([chr(ord(a) ^ ord(b)) for a,b in zip(message, cycle(key))])

with open('hexoneline', 'rb') as f:
f.close()

#message = "FFD8FFE000104A4649460001"
key = "46ccf9a571f0ffb17e41cb84"

print do_xor(key,message).encode("hex")

#http://opentechnotes.blogspot.com/2014/08/xor-string-with-key-in-python.html
``````

Command:

``````\$python2.7 test.py > decodedhex
``````

Revert hex back to binary

``````\$ xxd -r -p decoded image.jpg
``````

Check if `image.jpg` is really an image:

``````\$ file image.jpg
image.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, progressive, precision 8, 500x500, frames 3
``````

Open it with your favourite image viewer and catch the flag.

``````\$ open image.jpg
``````

# Thanks

Special thanks goes to @Razvieu for kind support when I got stuck.