CSAW 2015 Bricks of Gold Problem Statement
We've captured this encrypted file being smuggled into the country. All we know is that they rolled their own custom CBC mode algorithm - its probably terrible. bricks
HINT: take a second look at the file for elements needed for the crypto
- The Initialization Vector was placed at the end of the file in plaintext. THE_SECTRET_IV=CASH
- The first 4 bytes have a similar hamming distance to the IV and the next 8 bytes
Using these observations it is safe to assume that repeating key xor is being used as a block cipher in CBC mode with a block length of 4. 
The theoretical encryption algorithm would work by xoring the first 4 bytes of plaintext with the Initialization Vector then with the key. Then xorring the next 4 bytes of plaintext with the previous 4 bytes of ciphertext and then with the key and so on.
Note: Most filetypes begin with a File header. For example PDF files begin with "%PDF" and Elf files begin with "\x7fELF"
Part OneCreate a list of every file header and then brute force every possible 4 byte KEY with the IV and check if there are any matches with the lists of file headers
#brute.py def xor_strings(a, b): la, lb = list(a), list(b) eb = "" for i in xrange(len(la)): eb += chr(ord(la[i]) ^ ord(lb[i])) return eb cipher = "$XMT" #First 4 bytes of ciphertext IV = "CASH" #Initialization vector magic_numbers = ["%PDF", "\x7fELF", "\x00\x00\x01\xBA", "\xca\xfe\xba\xbe", "etc."] possible_keys =  for a in xrange(ord("A"), ord("Z") + 1): for b in xrange(ord("A"), ord("Z") + 1): for c in xrange(ord("A"), ord("Z") + 1): for d in xrange(ord("A"), ord("Z") + 1): key = chr(a) + chr(b) + chr(c) + chr(d) undone = xor_strings(xor_strings(key, IV), cipher) if undone in magic_numbers: possible_keys.append((undone, key)) print possible_keys
Decrypt the file with every possible key
import sys def xor_strings(a, b): la, lb = list(a), list(b) eb = "" for i in xrange(len(la)): eb += chr(ord(la[i]) ^ ord(lb[i])) return eb with open("bricks") as f: w = f.read() IV ="CASH" key = sys.argv #CBC decryption prev = w[:4] plain = xor_strings(xor_strings(w[:4], key), IV) for i in xrange(4, len(w), 4): plain += xor_strings(xor_strings(w[i:i+4], key), prev) prev = w[i: i+4] sys.stdout.write(plain)
python decrypt.py BIZZ > flag.pdf
This resulted in a pdf