CTF Team at the University of British Columbia

[UTCTF 2021] Tar Inspector

14 Mar 2021 by Vie

TL:DR

  1. <fileWithShellCommands__XXXX.tar> --to-command=bash -F .tar

Tar Inspector

The name is self-explanatory: you get a webpage that lets you provide a tar file to it and it’ll extract it to display the contents in a tree structure. A hint was provided that displayed the sanitization function that the filename of your provided file would go through - essentially removing all possible shell metachars, and barring against possible traversal attacks.

# creates a secured version of the filename
def secure_filename(filename):
    # strip extension and any sneaky path traversal stuff
    filename = filename[:-4]
    filename = os.path.basename(filename)
    # escape shell metacharacters
    filename = re.sub("(!|\$|#|&|\"|\'|\(|\)|\||<|>|`|\\\|;)", r"\\\1", filename)
    filename = re.sub("\n", "", filename)
    # add extension
    filename += '__'+hex(randrange(10000000))[2:]+'.tar'
    return filename

…Except, you could put spaces in your filename. Input some file with the filename te st.tar will give it an error, and it’s likely because the space forces the backend to interpret te and st as seperate commands, which will return an error. This tells us something very important - our filename is put into some sort of command line interface - likely a call to GNU tar to actually extract our file. So, if we can use whitespaces in our filename, can we add some arbitrary tar commands?

The answer is yes: inspect the tar man page for a bit and you’ll come across a particularly useful option called --to-command=COMMAND. Its usage is something like:

tar xvf <yourfile.tar> --to-command=bash

And the contents of yourfile.tar could then hold bash commands. The idea is that --to-command=COMMAND will extract the contents of your tar file and pipe it into the standard input of the command you stipulated. So, we have the ability to inject commands into the server, and with that, we can easily get the flag.

Make a simple .txt file to cat the flag: cat /flag.txt. Tar it (uncompressed! I wasted a bunch of time thinking my exploits weren’t working when really it was cause my tar files were compressed) and then submit that to the inspector. All archives exist in the same directory, which is a fact we’ll need for later.

We want to submit another tar file where the filename is a GNU tar command. Since we can access our earlier file, we can reference it (note that the challenge appends a weird randomized suffix to every tar archive you give it, so make sure you include that) and give it the option --to-command=bash. Due to the whole suffix appending issue, use the GNU tar -F option to absorb it. All in all, your second file should have the filename:

yourFirstFile__XXXXX.tar --to-command=bash -F .tar, then submit your second tar file (and the contents of the 2nd tar file don’t matter at all. Just needs the right filename).

tarinspectflag

ayo!