MozillaCTF Write-Up SecureFileLock (250)

January 27, 2012

This very secure locking mechanism encloses files and only gives them to you when you know the passphrase. Find it and you will have the flag.

Ok, let’s see. It’s a 64bit ELF binary, which means no easy “Press F5 in IDA”. Let’s run it

$:~/tmp/mozillactf$ ./securefilelock
Welcome to Secure File Lock
Playing 'Ethereal Awakening' by Project Divinity (CC BY-NC-SA 2.5)
Please enter your password. (max length = 32):

Ok, let’s see what it does in strace if we enter any password (boring stuff omitted).

$:~/tmp/mozillactf$ strace -eexecve ./securefilelock
execve("./securefilelock", ["./securefilelock"], [/* 37 vars */]) = 0
Welcome to Secure File Lock
Playing 'Ethereal Awakening' by Project Divinity (CC BY-NC-SA 2.5)
Please enter your password. (max length = 32):
a
Processing.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
execve("/usr/bin/vlc", ["/usr/bin/vlc", "--play-and-exit", "/tmp/sf.KpQB3w"], [/* 37 vars */]) = -1 ENOENT (No such file or directory)

Ok, so it writes to a temp file and tries to run it in vlc. Let’s try the same thing for password “b”. The get another file which differs in every bytes. Oh well, this sounds like XOR. Entering “ab” as a password results in a file that matches every second byte to the corresponding files for “a” and “b” – ok, its XOR.

Now, let’s once again look at the output we got when the programm started.


Welcome to Secure File Lock
Playing 'Ethereal Awakening' by Project Divinity (CC BY-NC-SA 2.5)

Googling for ‘Ethereal Awakening’ and the exact filesize, we find a torrent which lists multiple MP3 files. At this point, there are two ways to handle things. a) Download the MP3 or b) be lucky and have challenge authors that think ahead. Let’s go with b), the CTF was fun up until this point.

MP3? They will probably have a header! Looking at any given MP3 they all shared the same 7 bytes.

49 44 33 03 00 00 00

Ok, so we know the extracted file is an MP3 audio file and we know how the first 7 bytes look. Let’s hope for the condition of b) (challenge authors that think ahead) and guess that the XOR key is 7 bytes long. The idea now is to generate all possible outcomes of the file using just one byte long XOR keys.


import os
for i in range(ord('a'),ord('z')+1):
 os.system("echo %s | ./securefilelock" % chr(i))
 os.system("mv /tmp/sf.* /tmp/unpacked_%s" % chr(i))

for i in range(ord('A'),ord('Z')+1):
 os.system("echo %s | ./securefilelock" % chr(i))
 os.system("mv /tmp/sf.* /tmp/unpacked_%s" % chr(i))

for i in range(ord('0'),ord('9')+1):
 os.system("echo %s | ./securefilelock" % chr(i))
 os.system("mv /tmp/sf.* /tmp/unpacked_%s" % chr(i))

After we have generated this, let’s look at each byte until we have found the right key.


import base64
from itertools import izip, cycle
import sys
import glob

def xor_crypt_string(data, key):
 return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(data, cycle(key)))

orig = "ID3\x03\x00\x00\x00"
secret = dict()

for fn in glob.glob("/tmp/unpacked_*"):
 char = fn[fn.find("_")+1:]
 cont = open(fn,"r").read()
 for i in range(0,7):
 if cont[i] == orig[i]:
 secret[i] = char
sk = secret.keys()
sk.sort()
print ''.join(secret[s] for s in sk)

Which returns “yciNhAh” – 250 points.

Leave a Reply




Get Adobe Flash player