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\\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
"Decrypted: " + DecryptString(EncryptString("fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=")))
Console.WriteLine(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.CBCDim encryptor As ICryptoTransform
= symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)As New IO.MemoryStream()
Using memoryStream As New CryptoStream(memoryStream, _
Using cryptoStream
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 UsingEnd 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
New IO.MemoryStream(cipherTextBytes)
memoryStream =
Dim cryptoStream As CryptoStream
New CryptoStream(memoryStream, _
cryptoStream =
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()
{
.WriteLine("Decrypting Admin Hash...");
Console.WriteLine(CR.DS("yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4="));
Console}
}
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);
= new Rfc2898DeriveBytes(passPhrase, bytes2, passwordIterations);
Rfc2898DeriveBytes rfc2898DeriveBytes byte[] bytes4 = rfc2898DeriveBytes.GetBytes(checked((int)Math.Round((double)keySize / 8.0)));
= new AesCryptoServiceProvider
ICryptoTransform transform {
= CipherMode.CBC
Mode }.CreateEncryptor(bytes4, bytes);
string result;
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
{
.Write(bytes3, 0, bytes3.Length);
cryptoStream.FlushFinalBlock();
cryptoStreambyte[] inArray = memoryStream.ToArray();
.Close();
memoryStream.Close();
cryptoStream= Convert.ToBase64String(inArray);
result }
}
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);
= new
Rfc2898DeriveBytes rfc2898DeriveBytes Rfc2898DeriveBytes(passPhrase, bytes2, passwordIterations);
checked
{
byte[] bytes3 = rfc2898DeriveBytes.GetBytes((int)Math.Round((double)keySize / 8.0));
= new AesCryptoServiceProvider
ICryptoTransform transform {
= CipherMode.CBC
Mode }.CreateDecryptor(bytes3, bytes);
= new MemoryStream(array);
MemoryStream memoryStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
CryptoStream cryptoStream byte[] array2 = new byte[array.Length + 1];
int count = cryptoStream.Read(array2, 0, array2.Length);
.Close();
memoryStream.Close();
cryptoStreamreturn 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