BullyBox Writeup - Proving Grounds
Created October 8, 2026 • Last updated October 8, 2026 • 3 min read
BullyBox exposes its .git directory over HTTP. Dumping the repository leaks the BoxBilling database credentials, which double as the admin panel login. From there, CVE-2022-3552 lets an authenticated admin inject a Twig server-side template that calls PHP's system(), giving a shell as yuki. A passwordless sudo rule then hands over root.
Reconnaissance
Nmap
Scan all TCP ports and fingerprint the services.
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3 80/tcp open http Apache httpd 2.4.52 (Ubuntu)
Explain command
| -p- | Scan all 65535 TCP ports. |
| -sC -sV | Run default scripts and probe service versions. |
| --open | Only show open ports. |
Only SSH and HTTP. Add the box to /etc/hosts as bullybox.local and browse it; it's a BoxBilling installation. whatweb returns nothing beyond that.
Directory Brute-Force
Fuzz the web root for hidden paths and files.
200 .git/HEAD # exposed git repository 301 bb-admin/ # BoxBilling admin panel 301 bb-themes/ 301 bb-modules/
Explain command
| -x | Also probe these file extensions. |
.git/HEAD returning 200 means the repository is exposed on the web server and can be reconstructed.
Enumeration
Dumping the exposed .git repository
Reconstruct the full repository from the exposed .git folder.
[-] Fetching .git/HEAD [-] Fetching .git/index <snip> [-] Running git checkout .
The dumped tree includes bb-config.php, BoxBilling's configuration file.
'db' => array (
'type' => 'mysql',
'host' => 'localhost',
'name' => 'boxbilling',
'user' => 'admin',
'password' => '$ADMIN_PASSWORD',
),
The config also reveals the admin panel prefix bb-admin. Log in at http://bullybox.local/bb-admin/staff/login with admin@bullybox.local and the leaked password; the footer confirms BoxBilling 4.22.1.5, which is vulnerable to CVE-2022-3552.
Exploitation
BoxBilling Twig SSTI (CVE-2022-3552)
BoxBilling <= 4.22.1.5 lets an authenticated admin inject a Twig template through the email template API. Twig evaluates it without sandboxing, so the map filter can call PHP's system() directly. Start a listener first.
listening on [any] $ATTACKER_PORT ...
Explain command
| -lvnp | Listen, verbose, no DNS resolution, on the given port. |
Open the browser dev tools after logging in and copy the PHPSESSID cookie, then send the payload to the email template update endpoint.
{"result":true}
The classic Twig 1.x payload (_self.env.registerUndefinedFilterCallback('exec')) fails on Twig 2.x/3.x because _self.env is no longer exposed; map('system') bypasses that restriction entirely. The listener catches a shell as yuki.
Privilege Escalation
Sudo NOPASSWD ALL
Check sudo rights.
User yuki may run the following commands on bullybox:
(ALL : ALL) ALL
(ALL) NOPASSWD: ALL
yuki can run any command as root with no password.
root@bullybox:~# id uid=0(root) gid=0(root) groups=0(root)
su - would still prompt for root's own password even under a NOPASSWD rule; sudo su (without the dash) drops straight into a root shell.
Related
References
-
BoxBilling authenticated Twig SSTI leading to remote code execution.
-
HackTricks - Twig SSTITOOL: HackTricks - Twig SSTI, book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection#twig-php (opens in new tab)
Twig SSTI payloads, including the map/filter bypass for Twig 2.x/3.x.