This past weekend I participated in the CSAW 2015 CTF on team ascii_overflow. Our team is relatively new; however, we managed to finish 15th on the qualifying scoreboard - just barely enough to send our undergraduate members to compete at the CSAW finals in NYC (Good luck guys!). I started on the Crypto 500 challenge early-on but got sidetracked helping out on the web and forensics challenges and didn't have a chance to finish it during the competition, instead wrapping it up the following day.
Crypto 500 - Bricks of Gold
We've captured this encrypted file being smuggled into the country. All we know is that they rolled their own custom CBC mode algorithm - it's probably terrible.
The challenge consisted of a single encrypted file and the challenge description above. We are given the clue that CBC mode is used; however, we don't know the actual encryption algorithm. Given that this is a challenge designed for undergraduate students, I surmised that we are probably dealing with XOR. Examining the file, a few items stand out. Firstly, the end of the file contains the text: THE_SECRET_IV=CASH. Not only does this give us the IV for CBC mode, but we can also assume the block size is 4, further confirmed by the fact that the file size is now an even multiple of 4 (when the IV message is removed). Secondly, near the end of the file we see multiple repeating patterns of encrypted bytes with very low entropy, giving more weight that a simple XOR operation is being used for encryption.
Reviewing CBC mode, it's apparent that since XOR is a reflexive operation, we can easily remove the chaining by simply XOR'ing each 4 byte ciphertext block with the previous block, leaving us with a standard 4 byte repeating XOR key cipher. Depending on the plaintext filetype, we can apply several methods toward breaking the cipher, including English frequency analysis or identifying the most frequently used bytes. However, in my case, when I was reviewing the first few bytes of the encrypted file, the pattern looked very familiar
0000000: 2458 4d54 4b20 393d 034c a782 b3e0 167f $XMTK 9=.L......
The first few bytes appeared very similar to the PDF file header of "%PDF-1.3%" and indeed XOR'ing this against the ciphertext and IV gives us the encryption key of "BIZZ", which can then be used to decrypt the rest of the PDF. The quick Ruby script below gave us the full PDF.
block_size = 4
iv = "CASH".bytes
key = "BIZZ".bytes
data = iv + IO.binread(ARGV).bytes decoded = 
block_size.upto(data.length - 1) do |i|
decoded << (data[i] ^ data[i - block_size] ^ key[i % block_size])
end print decoded.pack('c*')