MozillaCTF 2012 SecureFileLock (250) Writeup

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.

Category: reversing
Summary: find out a xor cipher, use xortool to get the key

$ file securefilelock
securefilelock: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, for GNU/Linux 2.6.15, stripped

Here we a static linux x64 binary. Let’s look what it is about:

$ strace ./sec 
...
write(1, "Welcome to Secure File Lock\n", 28Welcome to Secure File Lock
) = 28
write(1, "Playing 'Ethereal Awakening' by "..., 67Playing 'Ethereal Awakening' by Project Divinity (CC BY-NC-SA 2.5)
) = 67
write(1, "Please enter your password. (max"..., 47Please enter your password. (max length = 32):
) = 47
...
read(0, mypassword
"mypassword\n", 1024)           = 11
write(1, "Processing......................"..., 680Processing.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
) = 680
getpid()                                = 11166
open("/tmp/sf.lWSi68", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
fcntl(3, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
fstat(3, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f248996d000
lseek(3, 0, SEEK_CUR)                   = 0
write(3, "]^*,\0332\37\27e(bAxJ\n\20_\336\32%\4i~iZ~\31m{`\0044"..., 6680576) = 6680576
write(3, "^/:\25\224K\36\334~~4e0\222\rB_^;w\5\374FS\371\346\236\202\264\3333\372"..., 1604) = 1604
close(3)                                = 0
execve("/usr/bin/vlc", ["/usr/bin/vlc", "--play-and-exit", "/tmp/sf.lWSi68"], [/* 33 vars */]) = -1 ENOENT (No such file or directory)

I have vlc removed, so it stops here. The program asks a password, generates a file and plays it. Let’s look into it’s contents:

$ xxd /tmp/sf.lWSi68 | head
0000000: 5d5e 2a2c 1b32 1f17 6528 6241 784a 0a10  ]^*,.2..e(bAxJ..
0000010: 5fde 1a25 0469 7e69 5a7e 196d 7b60 0434  _..%.i~iZ~.m{`.4
0000020: e7de 4b0a 6606 530c 4611 6c02 793d 6b2e  ..K.f.S.F.l.y=k.
0000030: 3a1d 4a10 5709 441b 670c 752a 6c38 6c18  :.J.W.D.g.u*l8l.

Yeah, looks it’s encrypted (bad password). Let’s try to see how password effects on it:

$ echo MYPASSWORD | strace ./sec
...
$ xxd /tmp/sf.Kqxidp | head
0000000: 7d7e 0a0c 3b12 3f37 4508 4261 586a 2a30  }~..;.?7E.BaXj*0
0000010: 7ffe 3a05 2449 5e49 7a5e 394d 5b40 2414  ..:.$I^Iz^9M[@$.
0000020: c7fe 6b2a 4626 732c 6631 4c22 591d 4b0e  ..k*F&s,f1L"Y.K.
0000030: 1a3d 6a30 7729 643b 472c 550a 4c18 4c38  .=j0w)d;G,U.L.L8

Hmm, looks like it doesn’t differ much. Let’s see what bits differ:

$ xor -h 5d5e2a2c1b321f1765286241784a0a10 -h 7d7e0a0c3b123f3745084261586a2a30 | xxd
0000000: 2020 2020 2020 2020 2020 2020 2020 2020

Hmm! The same as the difference between our passwords (the case bit is 0x20). Looks like it’s just a simple xor!

Decrypting XOR

Let’s try xortool then. It may take some minutes, but we can fasten it buy analyzing only some part of the file:

$ echo -n | strace ./sec  # get a 'clean' ciphertext
...
$ xortool <(head -c 65000 /tmp/sf.7t836b) -c 00
The most probable key lengths:
   1:   4.3%
   7:   11.3%
  14:   11.0%
  21:   10.9%
  28:   10.7%
  35:   10.6%
  42:   10.5%
  49:   10.3%
  56:   10.2%
  63:   10.1%
Key-length can be 7*n
1 possible key(s) of length 7:
\x86\x9c\x96\xb1\x97\xbe\x97
$ file xortool_out/0_\\x86\\x9c\\x96\\xb1\\x97\\xbe\\x97 
xortool_out/0_\x86\x9c\x96\xb1\x97\xbe\x97: Audio file with ID3 version 2.3.0, contains: MPEG ADTS, layer III, v1, 128 kbps, 44.1 kHz, JntStereo

Notice: some guys told me that they’ve got en encrypted file without additional xoring; then you can skip the next part and just get a key :)

Bingo! Audio file. It’s really valid MP3 file. But what is the key?
It’s not printable! All the high bits are set.
We can bruteforce each byte to the program, to find out what byte of the key must be to decrypt the appropriate cipher byte as the valid one.
But if we notice, that if it’s xor cipher (we’ve got a valid MP3 file), then the key may only be xored with one byte before xoring the ciphertext.

Finally, the real key is xored with 0xff:

$ xor -s '\x86\x9c\x96\xb1\x97\xbe\x97' -s '\xff'
yciNhAh

The whole algorightm can be found by reversing the binary, but this way of external analysis is a nice one too :)

The flag: yciNhAh

Links

Nice writeup by Eindbazen

Leave a Reply

Your email address will not be published.