PivotAPI: writeup oficial de los autores

Hoy os traemos un writeup especial, el de la máquina en Hackthebox "insana" y recientemente retirada PivotAPI que nuestros colegas CyberVaca & 3v4Si0N crearon.

Veréis que PivotAPI tenía un montón de pasos que ponían a prueba a cualquier ninja en Directorio Activo. Primero encontrábamos un nombre de usuario (el de mi sobrino! xD) en los metadatos de un PDF y lo usábamos para AS-REP Roast. Este usuario tenía acceso a algunos binarios relacionados con la gestión de una base de datos. Mediante un análisis dinámico obteníamos la contraseña y finalmente obteníamos acceso al servicio MSSQL. A partir de ahí, mediante mssqlproxy se hacía un túnel de WinRM y se obtenía un fichero KeePass. Las credenciales daban acceso SSH, donde explotábamos algunos privilegios vulnerables para obtener acceso a un recurso compartido de desarrolladores. Allí, otro binario se podía usar para obtener credenciales adicionales. Por último, a través de otros privilegios mal configurados, se obtenía acceso a la contraseña LAPS del administrador. Todo ello con un buen carrusel de nombres de usuarios de nicks de nuestro grupo L1k0rd3b3ll0t4. Grandes!!

Y sin más dilación os dejo con el writeup que me pasó tito Luis:

Reconocimiento

Antes de nada, se realiza un escaneo de puertos con la herramienta nmap para
encontrar los puertos que se encuentran expuestos

Seguidamente, se obtienen los puertos en forma de lista a través del uso del nmap en formato grepeable:

Se realiza un escaneo más profundo de los puertos encontrados utilizando los scripts y descubrimiento de versiones de nmap. Como se puede ver en la siguiente imagen, el script ftp-anon muestra que, a través del usuario anonymous, el inicio de sesión está permitido. Así mismo, se puede observar que existen dos archivos relevantes en el servidor FTP:

  • notes1.pdf
  • notes2.pdf

El script ms-sql-ntlm-info a través de la autenticación por NTLM ha obtenido información relevante como el nombre interno de la máquina y el dominio del Active Directory:

  • Domain -> licordebellota.htb
  • ComputerName -> pivotapi

Así mismo, usando la herramienta CrackMapExec se puede tener una idea del sistema operativo que se encuentra corriendo en la máquina:

Extracción del nombre de usuario de Active Directory

Después de enumerar cada uno de los servicios, es necesario volver al punto de partida.
Es posible descargar los tres archivos ya sea utilizando un programa como Filezilla o directamente realizando una petición al servidor FTP con la herramienta wget de forma recursiva:


A través del uso de la herramienta exiftool, es posible visualizar los metadatos de los archivos descargados. Como se puede ver a continuación, el archivo notes2.pdf tiene almacenado el nombre de usuario del Active Directory del creador del PDF (kaorz) en la variable Creator:

Ataque Asreproasting

A continuación, se inserta el nombre de dominio en el archivo /etc/hosts de la máquina atacante para poder realizar el ataque Asreproast:

En la siguiente imagen, se puede apreciar cómo haciendo uso del script GetNPUpsers.py de impacket es posible obtener el hash del usuario kaorz a través del ataque conocido a Kerberos como Asreproast:

Después de obtener el hash asrep del usuario kaorz, es posible crackearlo usando el diccionario rockyou. Como se puede ver a continuación la password del usuario kaorz es Roper4155:

Descarga de información por SMB

Una vez obtenidas las credenciales del primer usuario, se comprueba el acceso
permitido con este usuario. En este caso, se puede observar que dentro del recurso compartido NETLOGON se encuentra una carpeta del departamento HelpDesk donde están expuestos tres archivos para todos los usuarios del dominio:
  • Restart-OracleService.exe
  • Server MSSQL.msg
  • WinRM Service.msg


Como se puede ver en la siguiente evidencia, kaorz tiene permisos para descargar los tres archivos haciendo uso de la herramienta smbclient:

Interpretación de la información obtenida

Seguidamente, haciendo uso de la utilidad “file” en Linux, es posible saber que los archivos .msg son mensajes de Outlook:

Abriendo el archivo “Server MSSQL.msg” con la herramienta Outlook es posible leer el primer correo electrónico el cual muestra la primera pista. Como se puede ver a continuación, en el año 2010 se instaló el servicio Oracle para las bases de datos, pero debido a los problemas ocasionados, se decidió migrar a MSSQL a principios del año 2020. El ejecutable es utilizado para iniciar sesión en el servicio de Oracle, esto da a entender que existen credenciales hardcodeadas en el binario:

Por otro lado, en el segundo correo “WinRM Service.msg” se comenta que el BlueTeam de la empresa ha decidido no exponer el servicio WinRM al exterior debido a que es posible obtener una conexión remota haciendo uso de la herramienta Evil-WinRM. Esto da a entender que el servicio WinRM únicamente está disponible localmente:

Monitorizando el proceso Restart-OracleService.exe

Lo primero que haría cualquier pentester cuando se encuentra un ejecutable portable (PE) es realizar reversing al binario para obtener los datos hardcodeados. Es importante destacar que el binario se ha ofuscado utilizando la herramienta PEzor (https://github.com/phra/PEzor). Esta herramienta utiliza distintos tipos de técnicas para evitar que pueda ser debuggeado, hookear las funciones y entender el código.
También encodea el shellcode generado por donut con la herramienta sgn, almacena el shellcode en la sección .text en lugar de en .data y finalmente puede hacer uso de las syscalls para evitar la detección por parte de algunos EDR’s y AV’s.
Haciendo uso de herramientas convencionales no es posible realizar un reversing en un tiempo razonable. Para ello es importante utilizar la herramienta Procmon de Sysinternals para entender qué es lo que está realizando el binario.


En primer lugar, como se puede ver a continuación, se abre el procmon en la máquina atacante y se inserta una regla de filtrado indicando que únicamente muestre eventos relacionados con el nombre del proceso Restart-OracleService.exe:


Seguidamente se ejecuta el programa:

Finalmente, como se puede apreciar, el binario crea una estructura de ficheros en la carpeta %tmp% del usuario actual escribiendo un archivo “.bat”. Debido a que
únicamente se puede ejecutar desde unos usuarios determinados (frankytech,
cybervaca y 3v4si0n), si no se detecta cualquier de estos tres usuarios, el archivo .bat es eliminado automáticamente después de escribirse en la carpeta temporal.


Recuperando el BAT y el archivo restart-service.exe

Para interceptar el archivo creado en el directorio temporal, es necesario desarrollar un pequeño oneliner el cual espera de manera indefinida a que el fichero “.bat” exista en el directorio. Una vez el archivo existe, lo copia en la ruta C:\temp\filebat.bat.
Como se puede ver a continuación, después de ejecutar repetidas veces el ejecutable “Restart-OracleService.exe”, el archivo “.bat” es copiado satisfactoriamente a la ruta C:\temp\filebat.bat:

Como ya se dijo anteriormente, únicamente el bat es ejecutado si el usuario es
cybervaca, frankytech o ev4si0n:

Únicamente, es necesario borrar los condicionales para poder ejecutarlo:

Así mismo, al final del script, los archivos son eliminados. También es necesario borrar estas líneas para no perderlos:

Finalmente, el archivo “.bat” construye el ejecutable “restart-service.exe” en la ruta C:\programdata, el cual es el encargado de iniciar sesión en el servicio de Oracle:
 

Se ejecuta el archivo .bat y se espera hasta que haya terminado:

Como se puede observar, el BAT crea 3 archivos en la ruta C:\programdata\:

  • monta.ps1
  • oracle.txt
  • restart-service.exe

Monitorización de la API de Windows

Si se ejecuta el archivo, se puede observar que a los ojos del usuario no está ocurriendo nada, pero de manera transparente se está creando un nuevo proceso:

Si comprobamos el binario con programas de ingeniería inversa como IDA o Ghidra, no es posible obtener nada de información debido a que este ejecutable también se ha ofuscado utilizando la herramienta PEzor:

Buscando en Google es posible obtener un post del año 2013 el cual explica cómo se pueden capturar credenciales a través de la monitorización de llamadas a la API de Windows (https://micksmix.wordpress.com/2013/03/20/capturing-credentials-from-
encrypted-runas-software/
):

En este caso, se ha optado por utilizar el programa llamado API Monitor
(http://www.rohitab.com/apimonitor#Download). En primer lugar, se debe ejecutar el programa con permisos de administrador:

Seguidamente, marcar todos los checks que se encuentran en la pestaña Capture:

Abrir el ejecutable “Restart-Service.exe” para monitorizar las llamadas a la API:

Una vez abierto, se puede observar un gran volumen de llamadas a la API:

Si se realiza una búsqueda por la palabra clave “createprocesswithlogonw” como se explica en el post referenciado anteriormente, se encuentran credenciales
hardcodeadas en el binario:

A continuación, se muestran las credenciales hardcodeadas del servicio Oracle:


Con CrackMapExec se puede comprobar si las credenciales son válidas o no en el Active Directory. A continuación, se puede observar cómo las credenciales obtenidas para el usuario svc_oracle no son válidas actualmente:

Enumeración del Directorio Activo con BloodHound

Usando las credenciales válidas del usuario kaorz se puede dumpear el AD remotamente usando la herramienta bloodhound.py (https://github.com/fox-it/BloodHound.py):

Una vez se ha importado la información del BloodHound a la base de datos neo4j, se puede observar que existe un usuario en el AD llamado svc_mssql que se encuentra dentro del grupo Domain Users y WinRM:

Obteniendo las credendiales de MSSQL service

Haciendo hincapié en la información obtenida en el correo electrónico “Service MSSQL” podemos interpretar que la contraseña del usuario mssql es una modificación de la del usuario de Oracle, en este caso, #mssql_s3rv1c3!2020:

Aunque el usuario del Active Directory se llame svc_mssql, este usuario no tiene
permisos para acceder al servicio expuesto en el puerto 1433. El usuario por defecto de MSSQL con permisos elevados es “sa”. Como se puede ver a continuación, las credenciales son válidas para el usuario “sa” y tiene permisos de administrador:

Socks proxy a través de MSSQL service

Hace aproximadamente 6 meses, la empresa BlackArrow desarrolló una herramienta llamada mssqlproxy para realizar un túnel socks proxy a través de una conexión a una base de datos MSSQL (https://github.com/blackarrowsec/mssqlproxy):

La siguiente evidencia muestra en forma de diagrama de red cómo se comporta la herramienta:

En el siguiente cuadro de texto se exportan las variables necesarias para utilizar la herramienta mssqlproxy:

export usuario='sa'
export password='#mssql_s3rV1c3!2020'
export ip_mssql='192.168.1.50'

Seguidamente, en el siguiente cuadro de texto se muestran los commandos necesarios para levantar un socks proxy en la máquina atacante:

python mssqlclient.py $usuario:$password@$ip_mssql
enable_xp_cmdshell
enable_ole
upload reciclador.dll c:\windows\temp\reciclador.dll
python mssqlclient.py $usuario:$password@$ip_mssql -install -clr
Microsoft.SqlServer.Proxy.dll
python mssqlclient.py $usuario:$password@$ip_mssql -check -reciclador
'c:\windows\temp\reciclador.dll'
python mssqlclient.py $usuario:$password@$ip_mssql -start -reciclador
'c:\windows\temp\reciclador.dll'

A continuación, se muestra el output devuelto por mssqlclient.py del repositorio de la herramienta mssqlproxy cuando se ejecuta el comando upload para copiar el
reciclador.dll a la máquina objetivo. En este caso la DLL ha sido copiada en la ruta
C:\Windows\Temp\reciclador.dll:

Seguidamente, se instala el proxy DLL. En el repositorio se encuentra compilado con el nombre assembly.dll:

Seguidamente, se ejecuta el comando -check para comprobar que la herramienta se ha instalado correctamente:

Finalmente, ejecutando el comando –start se inicia el proceso de creación del túnel y en el puerto 1080 como se ha indicado en el comando, se levanta un socks proxy. Es necesario destacar que esta herramienta únicamente funciona con proxychains4.

Es necesario destacar que, aunque el usuario “sa” pueda habilitar xp_cmdshell y
ejecutar comandos en el sistema, no es posible obtener una Shell inversa en el equipo debido a que se ha bloqueado la comunicación hacia fuera en los protocolos de comunicación ICMP, UDP y TCP.

Shell usando el servicio WinRM

Una vez que el túnel se encuentra perfectamente levantado, se puede comprobar que el puerto 5985 de WinRM se encuentra abierto internamente utilizando nmap a través de proxychains4:

Finalmente, haciendo uso de la herramienta Evil-WinRM se obtiene shell a través del usuario svc_mssql:

Enumeration local

Descifrando el fichero KeePass

En el Desktop del usuario, se puede encontrar un KeePass cifrado con credenciales almacenadas:

A través de la utilidad download de winrm, se puede descargar fácilmente dicho archivo para su posterior análisis en la máquina atacante:

A partir de la herramienta keepass2john se obtiene el hash que puede ser utilizado para realizar un ataque de fuerza bruta y obtener la contraseña de cifrado:

A continuación, se usa la herramienta John The Ripper con el diccionario rockyou.txt para crackear el Hash. Como se puede ver a continuación, la clave de cifrado del KeePass es mahalkita:

Seguidamente, con la password obtenida se abre el archivo credentials.kdbx como se puede ver en la siguiente imagen:

Las credenciales almacenadas en el Password Manager son las del usuario 3v4Si0N:

Logging a través de SSH

Una vez obtenidas las nuevas credenciales, este nuevo usuario puede iniciar sesión a través del servicio SSH. Esta información ha sido recabada anteriormente en BloodHound:

 Finalmente, se inicia sesión por SSH con las credenciales del usuario 3v4Si0N:


Camino al Domain Admin

Analizando internamente la máquina se puede observar que existe una carpeta llamada Developers en la ruta C:\Developers:

Así mismo, se puede observar que existe un grupo de desarrolladores en el Active
Directory:

Observando la información proporcionada por BloodHound se puede ver que existen dos usuarios que pertenecen a este grupo:

Por otro lado, el usuario 3v4Si0N dispone del permiso GenericAll sobre el usuario
Dr.Zaiuss. Esto quiere decir que, el usuario 3v4Si0N puede modificarle la contraseña al usuario Dr.Zaiuss:


Abusando del privilegio GenericAll

Primero, se inicia sesión a través de evil-winrm con el usuario svc_mssql y se parchea AMSI para poder cargar PowerView sin que el Antivirus detecte actividad sospechosa:
 
Seguidamente, se carga PowerView en memoria:

 
Se modifican las credenciales del usuario Dr.Zaiuss con las funciones que proporciona PowerView:

 
Finalmente, con las credenciales modificadas, es posible acceder a través del servicio WinRM con el nuevo usuario:

 
Como se puede ver a continuación, el usuario Dr.Zaiuss también tiene el permiso
GenericAll sobre el usuario Superfume:


Realizando los mismos pasos que en el caso anterior, podemos modificar la contraseña del usuario superfume:

 
Finalmente, se tendría acceso por winRM con el nuevo usuario:

 
Recordemos que el usuario superfume se encuentra dentro del grupo Developers como se puede ver a continuación en la información proporcionada por BloodHound:

Obteniendo las credenciales hardcodeadas

Una vez disponemos del acceso a la máquina a través de un usuario que pertenece al grupo de desarrolladores, podremos tener acceso a la carpeta C:\Developers:

 
En ella, como se puede ver en la imagen anterior, se encuentra el programa compilado y el código fuente de dicho programa.
A continuación, se puede visualizar que existen credenciales hardcodeadas en el código fuente:

 
El siguiente paso es descargar el ejecutable para su posterior análisis. Para ello se utiliza la utilidad download de evil-winrm:

 
En este caso, como el programa aún se encuentra en fase de desarrollo no se le ha aplicado ningún tipo de obfuscación y se puede realizar ingeniería inversa utilizando la herramienta dnspy.

Como se puede ver a continuación, la contraseña del usuario Jari se encuentra cifrada en RC4:

 
Modificando el binario con dnspsy e insertando un Console.WriteLine se puede
visualizar la contraseña en texto plano antes de cifrar la contraseña con la función
SecureString:

 
Como se puede ver a continuación, la contraseña del usuario licordebellota\jari en texto plano es Cos@Chung@!RPG:

 
Finalmente, como el usuario Jari también se encuentra dentro del grupo WinRM, se puede iniciar sesión a través de evil-winrm:

Abusando del privilegio ForceChangePassword

Enumerando de nuevo con BloodHound, se puede observar que Jari dispone del permiso ForceChangePassword sobre el usuario Gibdeon, que a su vez este usuario pertenece al grupo Accounts Operators y el cual puede realizar cambios sobre el grupo LAPS debido a que dispone del permiso GenericAll:

 
Lo primero, como se hizo anteriormente con el usuario svc_mssql, es parchear AMSI y cargar en memoria PowerView:

 
Seguidamente, el usuario Jari le cambia la contraseña al usuario Gibdeon con la función de PowerView Set-DomainUserPassword:

Abusando del privilegio GenericAll sobre el grupo LAPS READ

Con las nuevas credenciales del usuario Gibdeon debido a que este usuario pertenece al grupo Account Operators, se puede crear un nuevo usuario del dominio con la función New-DomainUser de PowerView y asignarlo al grupo LAPS READ usando la función Add-DomainGroupMember:

 
Finalmente, se añade al nuevo usuario de dominio al grupo WinRM para poder tener acceso a través de evil-winrm:

Leyendo las credenciales del admin local

Una vez creado el nuevo usuario de dominio e insertado en el grupo WinRM y LAPS READ, se accede a través de evil-winrm como se dijo anteriormente:

 
Se carga la función de powershell Get-LAPSPasswords que se encuentra publicada en github
(https://github.com/kfosaaen/Get-LAPSPasswords/blob/master/Get-
LAPSPasswords.ps1
):

 
Para terminar, ejecutando la función Get-LAPSPasswords con las credenciales del
usuario creado anteriormente, se obtiene la contraseña del administrador local de la máquina:
 
Al disponer de las credenciales del administrador local, se puede acceder a través del servicio WinRM para leer la flag de root:

 
Cabe destacar que existe un servicio que se ejecuta cada 10 minutos que reinicia el AD al estado original evitando la persistencia de las acciones que realicen los usuarios.

Comentarios