26
Jan
2012

MozillaCTF 2012 – SecureFileLock

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.

This challenge requires us to reverse engineer an executable and subsequently retrieve the decryption key for an embedded file.

We’re provided a file, which turns out to be a 64-bit Linux executable.

$ file securefilelock 
securefilelock: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, for GNU/Linux 2.6.15, BuildID[sha1]=0xfb8564ea463a52b6b072d3737243f87d89b7861e, stripped

Upon running the executable we’re prompted for a password, after which it appears to dump a file to /tmp which it then attempts to play using vlc.

$ strace -eexecve ./securefilelock 
execve("./securefilelock", ["./securefilelock"], [/* 50 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):
> -E_NOT_A_SINGLE_CLUE
Processing.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
execve("/usr/bin/vlc", ["/usr/bin/vlc", "--play-and-exit", "/tmp/sf.8emnhu"], [/* 50 vars */]) = 0
VLC media player 1.1.13 The Luggage (revision exported)

Unfortunately VLC is unable to play the gibberish in the dumped file – this would be the secure locking mechanism preventing us from listening to the song, unless we supply the correct password. Let’s see if we can figure that one out.

We fire up our favorite disassembler (IDA) and find something resembling a decryption loop at 0x401110. It also reveals the (encrypted) file is stored at physical offset 0xB5080 and has a length of 0x65F644. Let’s dump it:

$ dd if=securefilelock of=music.bin skip=741504 bs=1 count=6682180

Back to the decryption loop (that is, the interesting bits of it):

.text:0000000000401115                 movzx   eax, emb_file[rax]
.text:000000000040111C                 mov     r8d, eax
-----------------------------------------------------------------------------
.text:000000000040115A                 movzx   eax, byte ptr [rbp+rax+password]
.text:000000000040115F                 xor     eax, r8d
.text:0000000000401162                 mov     edx, eax
.text:0000000000401164                 mov     eax, [rbp+count]
.text:0000000000401167                 cdqe
.text:0000000000401169                 mov     emb_file[rax], dl

In this case, by examining the disassembly we suspect the algorithm is using the supplied password as a key to XOR the (embedded) file. I’ll show how you can leverage gdb’s scripting functionality to quickly verify your assumptions about said algorithm:

$ cat script 
break *0x40115F
commands 1
printf "EAX=%08x R8=%08x\n", $eax, $r8
c
end
break *0x401169
commands 2
printf "DL=%08x\n", $dl
c
end
run

$ gdb -q -x script ./securefilelock <<< "ABCD" | egrep "EAX|DL" | head -n 16
EAX=00000041 R8=00000030 DL=00000071
EAX=00000042 R8=00000027 DL=00000065
EAX=00000043 R8=0000005a DL=00000019
EAX=00000044 R8=0000004d DL=00000009
EAX=00000041 R8=00000068 DL=00000029
EAX=00000042 R8=00000041 DL=00000003
EAX=00000043 R8=00000068 DL=0000002b
EAX=00000044 R8=00000078 DL=0000003c

The trace shows our assumptions were correct – it’s indeed using the password as a XOR key (in the example above, the password bytes are reflected in EAX, the embedded file’s data in R8).

Now that we know the algorithm, we need to find the key. No real hints are provided (other than a length restriction of 32), so we’ll need to come up with a clever way to retrieve the key. Knowing we’re dealing with a music file, MP3 would be an obvious choice. Most MP3s contain metadata (an ID3v2.3 or ID3v2.4 tag), and from the ID3v2 specs we figure the first few bytes of the ID3v2.3 tag header should be a static sequence:

49 44 33 03 00 00 00

(Alternatively, the fourth byte could be a 04 in case of ID3v2.4)

XOR’ing these seven bytes with the first bytes of the dumped music.bin yields an ASCII-printable string: yciNhAh.

This turns out to be the key/password used, and as hinted by the challenge description, it’s also the flag.

*** Bonus ***

There are many more ways to derive a XOR key. In this specific case LAME was used to encode the MP3, which tends to pad the last frames using a single 0x58 byte. The (decrypted) MP3 also features series of nulls, directly exposing the key.

An image to illustrate these two observations:

{2 Responses to “MozillaCTF 2012 – SecureFileLock”}

  1. Hi, thanks for your write up. Just one small comment. The organizers have put big hint to retrieve the plain text : name of the song and its artist. The song is also mentionned as (CC BY-NC-SA 2.5).

    It was easy to find it on the internet 😉

    Gabriel

Trackbacks & Pings