Home Writeups Contact

Dump - Seccon Beginners CTF 2019


I didn't get to spend as much time as I would have liked on this ctf, but I found this challenge pretty fun.

ctf introduction and challenge description
After opening the provided file in wireshark, the first thing I did was follow the tcp streams. the first stream doesn't have much important except give us some context. There is a type of web shell that allows the client to execute commands, and then the server will return the response to the command
stream 0

The second tcp stream is where the challenge starts.

second steam

By url decoding the command passed in the GET param, we can see it more clearly as
hexdump -e '16/1 "%02.3o " "\n"' /home/ctf4b/flag
In hexdump, the -e flag means you are going to specify a format string.

(The 16/1 isn't very important, but it means 16 iterations with a 1 byte count)

Format strings have the following syntax:
I found this link very helpful
Therefore, the %02.3o format string is broken down like this:

0 == left pad the number with 0 instead of spaces
2 == 2 minimum digits to be written (left padding with 0s)
.3 == 3 digits minimum to be written 
o == type is unsigned octal

Essentially this all boils down to telling us that the response is octal (base 8). You might have already known this just by looking at it, but this format string is confirmation.
By going to file > export objects > HTTP > save, we can save the response for that command into a file.

After quickly cleaning up the file by removing all the extra html tags and such, we can begin to work with it. My first thought was to write the decoded bytes into a file, so I wrote a python script to do that.

with open('octal_file', 'r') as o:
    r = o.read().replace('\n', ' ').split(' ')
    ar = [x for x in r if x]

First, I open the file and get rid of all possible new line characters that might mess things up, and then split it into a list so I can easily iterate through each one. Then I remove all empty strings, because I realized that for some reason there was a few that remained in there.

with open ('output', 'wb') as f:
    f.write(bytearray(int(b, 8) for b in ar))

Now, I write each octal byte into my output file by looping through each one in the list and writing it as a bytearray.

By running file on it, we can see that it's (most likely) a gz file
For some reason for gunzip to work you need to have the .gz file extension, so after renaming that you can gunzip it.

>file output
output: gzip compressed data, last modified: Sun Apr  7 10:46:34 2019, from Unix
[17:00:38] nullpxl@ubuntu-18-04 [~/security/ctfs/seccon/dump]:
>gunzip output
gzip: output: unknown suffix -- ignored
[17:04:24] nullpxl@ubuntu-18-04 [~/security/ctfs/seccon/dump]:
>mv output output.gz
[17:05:05] nullpxl@ubuntu-18-04 [~/security/ctfs/seccon/dump]:
>gunzip output.gz

After using gunzip and running file again, it's now a tar archive. So with tar -xf output we can extract it.

>file output 
output: POSIX tar archive
[17:05:24] nullpxl@ubuntu-18-04 [~/security/ctfs/seccon/dump]:
>tar -xf output

Now if you use ls, you'll see flag.jpg, upon opening that you'll receive the flag!

second steam