Nest fue una maquina, que en lo personal, me llevó más tiempo de lo que pensé. Esto por qué no soy un gran programador ni nada por el estilo, (es una debilidad mía), y la maquina en sí, exigía cambios en ciertas partes de un código que verán mas adelante.
Reconocimiento
Primero iniciamos corriendo un nmap en la maquina:
Nmap scan report for 10.10.10.178
Host is up (0.15s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE VERSION
445/tcp open microsoft-ds?
4386/tcp open unknown
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, SMBProgNeg, SSLSes
sionReq, TLSSessionReq, TerminalServer, TerminalServerCookie, X11Probe:
| Reporting Service V1.2
| FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, RTSPRequest, SIPOptions:
| Reporting Service V1.2
| Unrecognised command
| Help:
| Reporting Service V1.2
| This service allows users to run queries against databases using the legacy HQK format
| AVAILABLE COMMANDS ---
| LIST
| SETDIR <Directory_Name>
| RUNQUERY <Query_ID>
| DEBUG <Password>
|_ HELP <Command>
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cg
i-bin/submit.cgi?new-service :
SF-Port4386-TCP:V=7.80%I=7%D=1/27%Time=5E2F5538%P=x86_64-pc-linux-gnu%r(NU
SF:LL,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(GenericLin
SF:es,3A,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nUnrecognise
SF:d\x20command\r\n>")%r(GetRequest,3A,"\r\nHQK\x20Reporting\x20Service\x2
SF:0V1\.2\r\n\r\n>\r\nUnrecognised\x20command\r\n>")%r(HTTPOptions,3A,"\r\
SF:nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nUnrecognised\x20comma
SF:nd\r\n>")%r(RTSPRequest,3A,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\
SF:n\r\n>\r\nUnrecognised\x20command\r\n>")%r(RPCCheck,21,"\r\nHQK\x20Repo
SF:rting\x20Service\x20V1\.2\r\n\r\n>")%r(DNSVersionBindReqTCP,21,"\r\nHQK
SF:\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(DNSStatusRequestTCP,21,"
SF:\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(Help,F2,"\r\nHQK\
SF:x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nThis\x20service\x20allows\
SF:x20users\x20to\x20run\x20queries\x20against\x20databases\x20using\x20th
SF:e\x20legacy\x20HQK\x20format\r\n\r\n---\x20AVAILABLE\x20COMMANDS\x20---
SF:\r\n\r\nLIST\r\nSETDIR\x20<Directory_Name>\r\nRUNQUERY\x20<Query_ID>\r\
SF:nDEBUG\x20<Password>\r\nHELP\x20<Command>\r\n>")%r(SSLSessionReq,21,"\r
SF:\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(TerminalServerCooki
SF:e,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(TLSSessionR
SF:eq,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(Kerberos,2
SF:1,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(SMBProgNeg,21,
SF:"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(X11Probe,21,"\r\
SF:nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(FourOhFourRequest,3A
SF:,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nUnrecognised\x20
SF:command\r\n>")%r(LPDString,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2
SF:\r\n\r\n>")%r(LDAPSearchReq,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.
SF:2\r\n\r\n>")%r(LDAPBindReq,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2
SF:\r\n\r\n>")%r(SIPOptions,3A,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r
SF:\n\r\n>\r\nUnrecognised\x20command\r\n>")%r(LANDesk-RC,21,"\r\nHQK\x20R
SF:eporting\x20Service\x20V1\.2\r\n\r\n>")%r(TerminalServer,21,"\r\nHQK\x2
SF:0Reporting\x20Service\x20V1\.2\r\n\r\n>");
Host script results:
|_clock-skew: -58m52s
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2020-01-27T20:29:00
|_ start_date: 2020-01-27T19:50:09
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 789.14 seconds
Al analizar los resultados, vemos que el puerto 445 (SMB) se encuentra abierto, adicional de otros más. Por mi parte, decidí enfocarme por el momento en el 445 y hacer un poco mas de reconocimiento. OJO que el 4386 será util después.
Indagando en el Shared, encontré que HR tenía guardado un .txt de un correo electrónico, por lo que decidí agarrarlo y verificarlo:
Listo! ya tenemos TempUser con su contraseña: welcome2019.
Luego toca mas enumeración. Este usuario no tiene la bandera y tocará escalar.
Luego de ingresar con el usuario y contraseña anterior en la carpeta Data, logramos obtener el siguiente archivo XML que estaba en \IT\Configs
Intenté descifrar la contraseña pero fue inútil. No pude con ninguna herramienta.
Regresando a la enumeración, sabemos que no tenemos acceso a //10.10.10.178/Secure$. Sin embargo, en el directorio //10.10.10.178/Data/Carl/VB Projects, encontramos una carpeta llamada NotepadPlusPlus con 2 archivos XML. El config.xml decía lo siguiente:
<pre class="wp-block-code"><code> <History nbMaxFile="15" inSubMenu="no" customLength="-1">
<File filename="C:\windows\System32\drivers\etc\hosts" />
<File filename="\\HTB-NEST\Secure$\IT\Carl\Temp.txt" />
<File filename="C:\Users\C.Smith\Desktop\todo.txt" />
</History></code></pre>
Sabemos que el usuario TempUser logró ingresar a \HTB-NEST\Secure$\IT\Carl\Temp.txt”. Me conecté he hice un mget* para obtener todos los archivos posibles.
Bandera de User
Hasta este momento, ya supe qué tendría que hacer algo en VB (Visual Basic en Visual Studio). Ingresé a ver los archivos y acá esta lo que hice. Al no querer instalar Visual Studio, (sobretodo solo por 1 maquina en HTB), en los foros recomendaron que podiamos usar la pagina https://dotnetfiddle.net para correr las partes del código que necesitábamos. Luego de HORAS analizando, logré concluir que con este código:
Imports System.Text
Imports System.Security.Cryptography
Imports System.IO
Imports System
Public Class Utils
Public Shared Function DecryptString(EncryptedString As String) As String
If String.IsNullOrEmpty(EncryptedString) Then
Return String.Empty
Else
Return Decrypt(EncryptedString, "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256)
End If
End Function
Public Shared Function Decrypt(ByVal cipherText As String, _
ByVal passPhrase As String, _
ByVal saltValue As String, _
ByVal passwordIterations As Integer, _
ByVal initVector As String, _
ByVal keySize As Integer) _
As String
Dim initVectorBytes As Byte()
initVectorBytes = Encoding.ASCII.GetBytes(initVector)
Dim saltValueBytes As Byte()
saltValueBytes = Encoding.ASCII.GetBytes(saltValue)
Dim cipherTextBytes As Byte()
cipherTextBytes = Convert.FromBase64String(cipherText)
Dim password As New Rfc2898DeriveBytes(passPhrase, _
saltValueBytes, _
passwordIterations)
Dim keyBytes As Byte()
keyBytes = password.GetBytes(CInt(keySize / 8))
Dim symmetricKey As New AesCryptoServiceProvider
symmetricKey.Mode = CipherMode.CBC
Dim decryptor As ICryptoTransform
decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes)
Dim memoryStream As IO.MemoryStream
memoryStream = New IO.MemoryStream(cipherTextBytes)
Dim cryptoStream As CryptoStream
cryptoStream = New CryptoStream(memoryStream, _
decryptor, _
CryptoStreamMode.Read)
Dim plainTextBytes As Byte()
ReDim plainTextBytes(cipherTextBytes.Length)
Dim decryptedByteCount As Integer
decryptedByteCount = cryptoStream.Read(plainTextBytes, _
0, _
plainTextBytes.Length)
memoryStream.Close()
cryptoStream.Close()
Dim plainText As String
plainText = Encoding.ASCII.GetString(plainTextBytes, _
0, _
decryptedByteCount)
Return plainText
End Function
End Class
Public Class SsoIntegration
Public Property Username As String
Public Property Password As String
End Class
Public Class Module1
Sub Main()
Dim test As New SsoIntegration With {.Username = "c.smith", .Password = Utils.DecryptString("fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=")}
Console.Writeline("Decripted: {0}", test.Password)
End Sub
End Class
Se podia usar perfectamente en el sitio done pegué también la contraseña anterior que no pude descifrar.
La clave fue analizar el código poco a poco, agarrar los pedazos que iba necesitando y la misma plataforma me indicaba qué clases me faltaban. Todo fue fruto de copy-paste, google y paciencia.
Ahora tenemos la contraseña de c.smith, donde vamos directo a enumerar y a tomar la bandera.
El camino a root
Enumerando los directorios de C.Smith, encontramos 3 archivos importantes:
- Un HQL_Config_Backup.xml
-
Un archivo .EXE que no tengo ni idea para que sirve.
-
Un archivo Debug Mode Password.txt que esta vacío.
Regresando al foro, encuentro que el .exe lo podemos descompilar con esta herramienta: https://github.com/icsharpcode/AvaloniaILSpy
Adentro encontramos cosas raras que se parecen a lo mismo que usamos en nuestro compilador en linea:
De nuevo en el foro, decían que el archivo vacío realmente no lo estaba. Así que regresé al archivo “vacío” de texto y revisé todo para ver si en el SMB no lo había copiado mal. Aproveche a revisar el Data Stream del archivo para obtener mas información y para mi sorpresa, ahí estaba el detalle:
Ya abrimos el archivo y obtenemos lo que queríamos, una contraseña:
¿Se acuerdan que arriba mencioné los 3 archivos importantes? Pues si ven la captura de nuevo, vemos que hay un puerto 4386, el cual TAMBIEN nos salió cuando corrimos el NMAP. Yo intenté conectarme con NC pero no me daba ninguna respuesta. Siguiendo de nuevo otra recomendación del foro, probé con Telnet y funcionó de maravilla.
Ahora a realizar mas enumeración…
Luego de adecuarme a este nuevo servicio, navegué hasta donde pude hasta que encontré esto:
Enumerando aún mas, en la carpeta del LDAP, encontré finalmente algo que me pudiera servir. Una CONTRASEÑA:
En este punto, supe que correr mis herramientas en linea, John o lo que fuese, no iba a descifrarla. Esta contraseña era bastante parecida a la que teníamos inicialmente de C.Smith. Así que regresando a analizar el código del .exe qué descompilé, noté que tenia que cambiar unos parámetros en el código que ya había hecho.
Ojo acá! Para el user fué:
<pre class="wp-block-code"><code>Return Decrypt(EncryptedString, "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256)
</code></pre>
Esa fue la única parte que cambié para obtener la nueva contraseña. Pegamos los datos que encontramos en el .exe y abajo en las ultimas líneas del codigo, como hicimos con Smith, pegamos el password encontrado del Administrador.
Solo queda probar si funciona o no:
Y así fue cómo esta búsqueda llegó a su fin.
Gracias! Espero y todo esto te sirva en más de algo.