Sunday, February 5, 2017

BITSCTF 2017 - Crypto [Banana Princess (20), Enigma (30), Beginner's Luck (40), Sherlock (60)]


This CTF was a lot of fun!  There were a lot of easier challenges, and had some inventive challenges!

For the Crypto challenges, they were mostly encoding based or very simple XOR ciphers.

Banana Princess


This first crypto challenge included a pdf file (MinionQuest.pdf) and description:

The princess has been kidnapped! It is up to you to rescue her now, with the help of the minions. They have provided you with a letter (which may or may not have touched the kidnappers hands on its way to you).

Authors - Speeeddy, Blaze


Initially checking the exifdata seemed like a good idea:

ExifTool Version Number         : 10.08
File Name                       : MinionQuest.pdf
Directory                       : .
File Size                       : 420 kB
File Modification Date/Time     : 2017:02:04 22:29:08-08:00
File Access Date/Time           : 2017:02:05 02:24:27-08:00
File Inode Change Date/Time     : 2017:02:04 22:29:11-08:00
File Permissions                : rw-r--r--
Error                           : File format error

Looks like the pdf is corrupted, maybe the bytes or xor'd or something. Looking at a normally formed pdf elsewhere we can find similar strings to the corrupted ones:

<</Yvarnevmrq 1/Y 430190/B 6/R 404343/A 1/G 429991/U [ 576 155]>>

This could possibly be a simple rotation, so going here (http://planetcalc.com/1434/) we can see it shows up at the ROT13 point:

<</Linearized 1/L 430190/O 6/E 404343/N 1/T 429991/H [ 576 155]>>

So now we just have to ROT13 the whole file!
At this point I just used python to do the rest:

# rot13 code from http://stackoverflow.com/questions/3269686/short-rot13-function
import string
rot13 = string.maketrans( 
        "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm",
        "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz" 
        )

# print string.translate("Hello World!", rot13)

x = open('./MinionQuest.pdf', 'rb').read()
y = open('./out.pdf', 'w')

y.write(string.translate(x, rot13))
print 'done.'



This drops a pdf called 'out.pdf' which contains some better data to check out, looks like a part of it is redacted!



At this point I tried a few things, including looking for PDF layers, importing into Gimp and checking for PSD layers (as the exifdata did mention Adobe Photoshop CC 2015 & Microsoft Word), then after those checks failed, the next was to try file carving.

For file carving I ended up using one of my favorite tools, hachoir & hachoir-subfile! - https://bitbucket.org/haypo/hachoir/wiki/hachoir-subfile

$ hachoir-subfile out.pdf files
[+] Start search on 430190 bytes (420.1 KB)

[+] File at 1738 size=34851 (34.0 KB): JPEG picture => files/file-0001.jpg
[+] File at 36872 size=3448 (3448 bytes): JPEG picture => files/file-0002.jpg

[+] End of search -- offset=430190 (420.1 KB)
Total time: 108 ms -- global rate: 3.8 MB/sec

Looks like it worked! Output two files in our output directory of 'files'. This also dropped the full image without the redacted bar layer:



Flag: BITSCTF{save_the_kid}


Enigma


This challenge ended up being solved faster than expected, but was nice to do, here's the description:

Its World War II and Germans have been using Enigma to encrypt their messages. Our analysts have figured that they might be using XOR-encryption. XOR-encrption is vulnerable to a known-plaintext attack. Sadly all we have got are the encrypted intercepted messages. Your task is to break the Enigma and get the flag.

The included encrypted.tar.zx file dropped six files which were scrambled a little, here's an example of one:

$ xxd 2e
00000000: 3630 3c35 362a 2642 6775 2651 6372 7263  60<56*&Bgu&Qcrrc
00000010: 7426 6f75 7226 6e63 7372 6326 6d6a 6774  t&our&ncsrc&mjgt
00000020: 2826 5463 6163 6826 676b 2647 6463 6862  (&Tcach&gk&Gdchb

Ended up using this tool for the majority of the challenges - https://wiremask.eu/tools/xor-cracker/ (Could probably do exactly the same using xortool, etc.)
On there we find the highest probability of the first file's XOR key has a length of 1, weighing in around 14.5% probability.
It also drops the most likely key as 0x06.

Wrote another small python program (which may have been overkill in hindsight):

from pwn import *

data = []
files = ['1e','2e','3e','4e','5e','6e']
key = '\x06'

for f in files:
  x = open(f, 'rb').read()
  data.append(x)

for x in data:
  print xor(data, key)


This printed out the conversions:

Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort

In this we find the flag:

BITCTF{Focke-Wulf Fw 200}


Beginner's Luck


This one had an interesting premise, one that is well known and holds a good message to carry on:

Derp just had his first class of cryptography, and he feels really confident about his skills in this field. Can you break his algorithm and get the flag?


The challenge included BITSCTFfullhd.png and enc27.py. Looking at enc27.py we see this:

#!/usr/bin/env python

def supa_encryption(s1, s2):
    res = [chr(0)]*24
    for i in range(len(res)):
        q = ord(s1[i])
        d = ord(s2[i])
        k = q ^ d
        res[i] = chr(k)
    res = ''.join(res)
    return res

def add_pad(msg):
    L = 24 - len(msg)%24
    msg += chr(L)*L
    return msg

with open('fullhd.png','rb') as f:
    data = f.read()

data = add_pad(data)


with open('key.txt') as f:
    key = f.read()
    
enc_data = ''
for i in range(0, len(data), 24):
    enc = supa_encryption(data[i:i+24], key)
    enc_data += enc

with open('BITSCTFfullhd.png', 'wb') as f:
    f.write(enc_data)



Looks like it takes a base image, 'full.png', adds some bytes to the end of the file, does a simple XOR with 'key.txt' and then writes it back out to 'BITSCTFfullhd.png'. So again, similar to the previous challenges, all this is doing is a XOR.

Again on this one, just used the XOR-Cracker online mentioned in the comments:
from pwn import *

# Used https://wiremask.eu/tools/xor-cracker/
key='726b68255150346730263367343640342a256628554e235c'.decode('hex')

srcImg = open('BITSCTFfullhd.png', 'rb').read()
out = open('out.png', 'w')
result = xor(srcImg, key)
print key

out.write(result)


This dropped the png:



BITSCTF{p_en_gee}


Sherlock


This one was the highest points, but ended up being the simplest to solve, this was just a one-liner:

cat final.txt | grep -Eo '[A-Z]' | tr -d '\n' | sed 's/ZERO/0/g;s/ONE/1/g' | perl -lpe '$_=pack"B*",$_'

To explain this a little, the final.txt contained a lot of very normal text, but certain characters were capitalized in a sea of lowercase chars. I forget the name of this exactly, book cipher? This was very quick to recognize, and could be extracted with some grep, tr, sed & perl. The capital letters spelled out binary using words 'ZERO' & 'ONE', which was converted and printed using perl.

BITSCTF{h1d3_1n_pl41n_5173}