Slippery Upload — 247CTF

TonyRahmos
5 min readNov 1, 2021

--

Today I encountered an interesting WEB challenge on 247CTF, so I would like to share with everyone. The challenge’s name is “Slippery Upload

Looking at the title, we may know that it’s some kind of upload vulnerability. Start the challenge and navigate to the website:

Website

We can see the source code of “/app/run.py”, which is the website itself. There’s 1 route to “/zip_upload”, and this route only accepts “POST” method. The “zip_upload()” method allow us to post a zip file. It will perform check on the upload filename and content-type before uploading it to server and extracting using “zip_extract()” method.

Looking carefully at “zip_extract()” , the last 2 lines of this function indicate it’s vulnerable to Zip Slip vulnerability. You can read more about it on Snyk.

vulnerable code

Zip Slip is a form of directory traversal that can be exploited by extracting files from an archive. The premise of the directory traversal vulnerability is that an attacker can gain access to parts of the file system outside of the target folder in which they should reside. The attacker can then overwrite executable files and either invoke them remotely or wait for the system or user to call them, thus achieving remote command execution.

Normally, the uploaded zip file will be extracted to ‘UPLOAD_FOLDER’, which is “/tmp/uploads”. But what if the zip file’s name is “../../evil.sh”? -> The ‘evil.sh’ will be extracted to ‘/’ directory (as we move up 2 level).

Knowing the vulnerability, I’ll make a malicious zip file to upload and test. A simple python script will help to create the zip file:

create Zip script

Let’s run the code:

I’ve had my zip file created. Open this zip file:

Pay attention to “Location”. You can see the “test.txt” is followed by “../../app” .

Now let’s upload it to the website using curl:

curl -X POST -F zarchive=@slip.zip -k https://bc44712445f146c2.247ctf.com/zip_upload

upload the zip file

The zip file has been uploaded successfully! Now we can confirm the Zip Slip vuln.

So let’s find a way to get RCE. As we know, the website itself is the “run.py” in “/app”. What if we can modify the “run.py” and add our own code? Let’s try!

Using the previous script, but this time, instead of “test.txt”, it will be “run.py”:

Create the zip file, then upload using curl again:

It has been uploaded! Reload the webpage:

Reload the webpage

As you can see, the website now cannot load, because there’s only “Test” in “/app/run.py”! Which means, it has been modified. So now, you have to stop and start the challenge again to reset it. After that, instead of writing only “Test” to our “run.py”, let’s copy the whole original code and paste into it, but of course add our own code to gain RCE.

I’ve modified my create zip script. Now, it will read the content of “src_new.py” and zip it. “src_new.py” contains original “run.py” code, along with my own code to execute command on server. Below is content of “src_new.py”:

src_new.py

You can see, I’ve added a comment and some code to execute “cmd” when I route to ‘/exec’. Again, run the code, and upload the zip file.

Upload finished. Let’s reload the webpage:

Reload the webpage

The content has been changed to my own “run.py” code.

So now, let route to “/exec” and execute some Server-Side template injection.

SSTI

As SSTI is executed, you can use some SSTI payload of Jinja to gain RCE. For example, the following payload execute “id” command by using “os” module:

{{request.application.__globals__.__builtins__.__import__(‘os’).popen(‘id’).read()}}

“id” executed

You can see above, the command “id” has been executed. So, just play with some “ls” and “cat” to get the flag!

ls
cat the flag

In order to prevent such kind of vulnerability, use “ZipFile.extract()” method, because:

If a member filename is an absolute path, a drive/UNC sharepoint and leading (back)slashes will be stripped, e.g.: ///foo/bar becomes foo/bar on Unix, and C:\foo\bar becomes foo\bar on Windows. And all ".." components in a member filename will be removed, e.g.: ../../foo../../ba..r becomes foo../ba..r. On Windows illegal characters (:, <, >, |, ", ?, and *) replaced by underscore (_).

based on ZipFile Documentation.

THE END

HAPPY HACKING

--

--