This week we participated in the Hack.lu 2011 CTF, a Capture-The-Flag event organized by the FluxFingers team at Hack.lu. Even if we were only three with two other members playing at night, we placed 6th out of >100 teams! Congrats to FluxFingers for the wonderful work done, we enjoyed it so much.
This is our first write-up for this CTF, hopefully more will come.
The challenge consists of a single jpg file called “8c4f14e28155a2c3cf4b2538c1e0958b”:
and the following string:
“We got this file. Can you find the name of this planet?”
The jpg file name looks like an MD5 digest. Inside this file there’s a zip archive:
0 $ unzip -d src 8c4f14e28155a2c3cf4b2538c1e0958b
Archive: 8c4f14e28155a2c3cf4b2538c1e0958b
warning [8c4f14e28155a2c3cf4b2538c1e0958b]: 192407 extra bytes at beginning or within zipfile
(attempting to process anyway)
inflating: src/5IIUED7GheR
inflating: src/6JXtwsTTh9k
inflating: src/87F1s5POUJc
inflating: src/BPiIOASG_Z6
inflating: src/nLPA8X0UJqf
inflating: src/rySOWi4fZkA
inflating: src/uvlSlG3Tgow
inflating: src/Uw105aD3qYh
inflating: src/Yui5oq58hlx
One of these files is a wav with some Morse code in it. The other files are just pieces of the whole wav file containing the planet name Morse-encoded. We created a python script to compute all the possible wav files and compared each md5 checksum with the original file name. There are only 8 files we need to compute, so the total permutations are 8! = 40320:
#!/usr/bin/python
# Author: Marco Squarcina from c00kies@venice
# Description: Script for solving the Unknown Planet challenge of hack.lu CTF 2011
import os, hashlib, math, sys
from itertools import permutations
if len(sys.argv) != 3:
print("Usage: %s " % sys.argv[0])
sys.exit(1)
path = os.path.abspath(sys.argv[1])
fhash = sys.argv[2]
out = os.path.join(os.getcwd(), 'planet_name.wav')
flist = []
# open files
for f in os.listdir(path):
fh = open(os.path.join(path, f), 'r')
if(fh.read(4) == "RIFF"):
sample1 = fh
else:
flist.append(fh)
fh.seek(0)
count = 1
nsamples = len(flist)
nperms = math.factorial(nsamples)
# compute all the permutations and check md5 against fhash
for p in list(permutations(flist)):
print("\r" + str(count) + "/" + str(nperms)),
count += 1
sample = sample1.read()
sample1.seek(0)
for i in range(nsamples):
sample += p[i].read()
p[i].seek(0)
if hashlib.md5(sample).hexdigest() == fhash:
print("\nFound it! The correct wav is stored in " + out)
oh = open(out, 'w')
oh.write(sample)
oh.close()
break
# close files
for f in flist:
f.close()
sample1.close()
With this script, we got the correct wave file in a very short amount of time:
0 $ ./assemble.py src/ 8c4f14e28155a2c3cf4b2538c1e0958b
23876/40320
Found it! The correct wav is stored in /home/lavish/planet/planet_name.wav
Using audacity the Morse code become easily readable, so:
.--. .... . .. -.- -.-- --- ...
can be translated to:
Pheikyos
What a name for a planet 😉