githubEditar

HackTheBox - CCTV

Writeup de la máquina CCTV de HackTheBox

  • Dificultad easy

  • Tiempo aprox. ~1.5h

  • Datos Iniciales: 10.129.3.35

Nmap Scan

Tras realizar un escaneo nmap completo, se encuentran los siguientes puertos abiertos:

$ nmap -sT -Pn --disable-arp-ping -p22,80 -sVC --open cctv.htb

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.6p1 Ubuntu 3ubuntu13.14 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|_  256 76:1d:73:98:fa:05:f7:0b:04:c2:3b:c4:7d:e6:db:4a (ECDSA)
80/tcp open  http    Apache httpd 2.4.58
|_http-title: SecureVision CCTV & Security Solutions
Service Info: Host: default; OS: Linux; CPE: cpe:/o:linux:linux_kernel
#Nada en UDP

Tenemos 2 puertos:

  • 22/tcp (SSH): Nada relevante, versión no vulnerable.

  • 80/tcp (HTTP): Única alternativa que podemos mirar. Al parecer un servicio de cámaras de vigilancia (SecureVision CCTV).

HTTP

Al entrar, encontramos una página de un servicio SecureVision que se encarga, al parecer, de proporcionar "soluciones de seguridad" a sus clientes: CCTV, Control de acceso, consultas a profesionales, puertas de seguridad, keypads...

En la página solo encontramos los botones Staff Login y Get a Quote, pero el segundo nos lleva a mandar un email, así que pulsamos el primero a ver a dónde nos lleva.

Vemos que estamos en un panel de login de la aplicación ZoneMinder, si pulsamos del texto ZoneMinder arriba a la izquierda (naranja), se abre un desplegable con los botones ZoneMinder, Documentation y Support. Aunque los 3 botones nos lleven a páginas externas, desde ellas podemos saber qué es ZoneMinderarrow-up-right:

ZoneMinder is a free, open source Closed-circuit television software application developed for Linux which supports IP, USB and Analog cameras.

En Internet veo que es posible conseguir la versión con un solicitud a su API:

Pero, desgraciadamente, no tenemos permiso para verla. De todas formas, busco en Internet de nuevo y veo:

ZoneMinder's default credentials for the web interface are username admin and password admin. It is highly recommended to change these immediately upon setup via the Options > Users menu to secure the system.

Las pruebo y:

Ahora sí solicito la versión:

Así que tenemos delante a ZoneMinder 1.37.63, que, tras una búsqueda, cuenta con un CVE 9.9 CRITICAL: CVE-2024-51482arrow-up-right.

Blind Boolean-Based SQLi

Se trata de una boolean based SQLi, es decir, que si lo hiciésemos manualmente nos costaría un rato (bastante largo) conseguir los hashes de la DB, así que usamos SQLMap (que también usan en el propio report de la vulnerabilidadarrow-up-right en GitHub):

Como vamos a tardar años en que una blind boolean-based nos devuelva toda la DB y aprovechando que ZoneMinder es vulnerable, lo que podemos hacer es mirar el nombre de la DB y de la tabla en que se guardan las credenciales y hacer que sólamente se dumpee eso. Tras mirar en Internet:

ZoneMinder saves user credentials (usernames and hashed passwords) in a MySQL/MariaDB database named zm. The table name is Users and the column names are Username and Password

Crackeando los hashes

Los hashes son BCrypt ($2y$) con 1024 iteraciones ($10$ = 2102^{10}), con salt de 22 caracteres y hash de 31.

Los metemos a hashcat:

Tenemos admin:admin y mark:opensesame

Privesc - SSH

admin:admin son las credenciales por defecto que nos han permitido enumerar la versión, pero mark:opensesame son más "personales". Probamos a conectarnos por ssh:

Ejecutamos LinPEAS, anotamos lo siguente:

  • Muchas interfaces de red vethb9136e0, veth54ff6b7, br-3e74116c4022, etc.

    • Posiblemente sean containers de Docker, de hecho LinPeas ha detectado Docker, pero no que estuviésemos en un container, así que es posible que haya containers ejecutándose.

    • br-... es un puente para que los containers se comuniquen entre ellos.

    • veth... son interfaces para unir cada container al puente

  • Puertos en local:

  • Forwarding: net.ipv4.ip_forward = 1

    • IP forwarding, necesario para que los containers se comuniquen con el exterior.

  • Files with capabilities:

En las capabilities tenemos 3 cosas: snap (con setuid), que no nos sirve de mucho; ping, con permiso cap_net_raw=ep (que permite abrir sockets) y tcpdump, con cap_net_raw=eip.

cat_net_raw es una capability que permite abrir y crear sockets a medida desde cero, los flags son:

  • p: Permitted, el binario tiene autorización para usar el cap, pero no necesariamente está activado por defecto.

  • e: Effective, el cap está encendido y activo desde el instante en que se ejecuta el programa.

  • i: Inheritable, si este programa crea un proceso hijo, el hijo hereda el cap.

Identificando servicios de red

No tenemos nada que parezca un vector de escalada de privilegios directo, pero podemos usar tcpdump para ponernos en escucha y capturar info de las interfaces de red, que no son pocas. Primero tenemos que ver qué hace cada una.

Hacemos port forwarding a los puertos locales y los analizamos:

Si desde la máquina víctima hacemos curl a cada uno de los puertos (ignorando 3306,33060 que son de MySQL):

Si accedemos a los puertos desde Firefox, podemos encontrar cosas interesantes:

  • Puerto 9081 (el que respondía con imagen):

  • Puerto 8888 (MediaMTX): Si conseguimos encontrar el endpoint correcto podríamos conseguir poder ver otra cámara tan interesante como la anterior.

  • Puerto 8765 (motionEye)

De momento, y tras una búsqueda de los servicios en Internet, tenemos lo siguiente:

  • 127.0.0.1:7999: Motion 4.7.1 (Githubarrow-up-right)

    • Motion is a program that monitors the signal from video cameras and detects changes in the images.

  • 127.0.0.1:1935: MediaMTX (RTMP Publishing)

  • 127.0.0.1:9081: ? Pero devuelve imágenes, posible CCTV.

  • 127.0.0.1:8765: motionEye/0.43.1b4 (Githubarrow-up-right)

    • motionEye is a web frontend for the motion daemon, written in Python.

  • 127.0.0.1:8888: MediaMTX (Githubarrow-up-right)

    • MediaMTX is a ready-to-use and zero-dependency live media server and media proxy. It has been conceived as a “media router” that routes media streams from one end to the other.

  • 127.0.0.1:8554: MediaMTX (Conexiones RTSP)

Miramos si hay vulnerabilidades para alguna:

  • Motion 4.7.1 no es vulnerable

  • motionEye/0.43.1b4 es vulnerable a CVE-2025-60787 y CVE-2025-47782 (RCE en función add_camera)

    • Hay incluso módulos de Metasploit: exploit/linux/http/motioneye_auth_rce_cve_2025_60787

  • De MediaMTX no tenemos versión así que no podemos saberlo

CVE-2025-60787

Vamos a por motionEye:

Necesitamos contraseña para ejecutarlo, así que buscamos credenciales por defecto, que resultan ser admin:"" (contraseña vacía), pero probamos y sale Invalid credentials.. Buscamos en otros archivos:

Probamos con user:"", y:

Ahora volvemos a Metasploit

Posiblemente sea porque con cuenta de usuario no nos deja explotar la vulnerabilidad, aunque, de todas formas, si admin_password y admin_username están comentados (#), debería dejarnos iniciar sesión con las credenciales admin:"", pero no nos deja. Posiblemente las verdaderas credenciales no estén en el disco pero estén en caché, aunque es raro porque el hash 989c5a8ee87a0e9521ec81a79187d162109282f0 no parece poderse descifrar fácilmente (Crackstation no lo consigue descifrar). Además, si metemos el hash a hashid:

Pero ni siquiera con hashcat consigo descifrarlo. Tras un rato, pruebo a usar el "hash" no como hash, sino como contraseña, con la combinación admin:989c5a8ee87a0e9521ec81a79187d162109282f0:

Y confirmamos que no era un hash, sino que se trataba de la contraseña en texto plano. Así que volvemos a Metasploit:

Y tenemos root.

Última actualización