Contempt - Fullpwn
Contempt was an hard rated Active Directory machine present at the HackTheBox Business CTF 2023. This article aims to write-up how I found two unintended ways that allowed me to get the root flag realy quickly. Thus, in both contempt and contempt - revenge (supposed to fix the unintended way).
Contempt
Recon
Ports
As always when we are in front of an HackTheBox machine, we need to enumerate it. To do so, i’ll use rustscan which is just some nmap overlay. This tool is pretty useful because it first scan for the open ports, then you can ask for the classic nmap options. Which is more optimize than just a basic nmap.
|
|
Here we can see a bunch of ports. But we might have a clear idea of what we have here.
- 53 : DNS
- 88 : Kerberos
- 135 : RPC
- 139 : Netbios
- 445 : SMB
- 389 / 636 / 3268 / 3269 : LDAP(s)
We can be confident by saying that we have to deal with some Windows Active Directory.
2179 ? Never saw this before, what is this ?
Alright we might have to deal with some HyperV, let’s keep that in mind.
FQDN
When attacking active directory, we always need to resolve its fully qualified domain name since this is how some protocols communicates between them.
First thing that we would like to do is to enumerate the domain name, the machine name and if we have access to some features or even some informations.
To do so I ran enum4linux-ng. It allows us to try different credentials such as Anonymous or Guest logins.
|
|
Let’s add those FQDNs to our hosts file like so :
|
|
We can note multiple things from here :
- Computer name : dc01
- Domaine name : contempt.htb
- The domain SID (could be useful for some attack paths)
- OS Version : Windows 2016 10.0
Windows Server 2016 ? 🤔 This is not brand new lmao.
Foothold
When I was attacking the machine for the first time, I ran too quickly the scan and the machine was not fully up. So I did not see all the ports above. This is what I tought the attack surface was :
|
|
I did not have HTTPS and WinRM.
As we saw earlier, we cannot log into the machine using default credentials or anonymously. But within an Active Directory environment, we quickly need some usernames and credentials in order to start exploiting it.
So I decided to try some quick wins, since this is some 2016 server. If I am lucky enough it may work and get some interesting access. Here is the very first command that I ran.
|
|
Root
Zerologon (CVE-2020-1472)
Zerologon is a well-known vulnerability that was disclosed in september 2020. It is exploiting the protocol NetLogon. This protocol is a remote session opening based on RPC calls. But it is also allowing a computer to update his domain computer password from a domain controller. Because of a weak cryptographic configuration, we can set all the challenges to 00000000000000000000000000000000
an impersonate the call to change the password of the computer domain account.
This is what we’ll do here, we’ll empty the password of DC01$
domain account. The accounts that ends with $
are the domain machine accounts.
|
|
So we can now login using DC01$
just as if we were a classical user and list the shares.
|
|
This means that our exploit worked properly. Unfortunately, nothing interesting here. I also tried to see if there is some GPO stored in the SYSVOL
share that has encrypted password in it.
|
|
But no passwords.
DCSync using empty DC01$
One very useful trick, now that we have the account machine, is that we have the extended privileges DS-Replication-Get-Changes
and DS-Replication-Get-Changes-All
. Which means that we can use DCSync to retrieve all the data from the domain controller such as :
- Domain account username & hashes
- Kerberos keys
- Passwords stored using reversible encryption
- LSA secrets
|
|
We now have all the hashes, we can impersonate anyone we want using pass-the-hash.
Getting a shell
Let’s grab the most privileged user : Administrator. Since I didn’t saw the WinRM port at the first time, we need to enumerate the SMB shares in order to see if we have access to C$
.
|
|
No C$
here, but no worries. We have the write permission on NETLOGON
! So we can use for exemple wmiexec.py
from impacket.
|
|
|
|
Hmmm, this is not quite common. Usualy when playing HackTheBox, you first have the user.txt and then the root.txt once you’ve finished the box ! Since I cannot locate the user.txt on the machine, I’ll ask to the admins.
Not on the Windows filesystem ? 🤔
User
Recon
Since we do not know yet where the user.txt is located, let’s do some enumeration once again.
We could use crackmapexec ioxidresolver module to scan the active interfaces of the machines, maybe there is another machine in the internal network.
|
|
Alright it makes sens, we need to find a linux system, but we’re on a windows machine. So there can be 2 hypothesis :
- There is another machine only reachable trought the DC
- The linux is virtualized on the Active Directory
Remember the ports discovered at the beggining ? Remember the port 2179 ? We said that there was some HyperV Virtual Machine involved.
When doing the box, I first saw an interesting directory :
In this directory we found the nextcloud configuration.
There is a reverse proxy that redirects nextcloud.contempt.htb
to 172.16.20.1
. If you remember correctly, I did not have the port 443 in my first nmap, so I missed that one. This is that miss, that made me think to use Zerologon, because I did not found a suitable attack surface.
Alright, but how to get into the VM ? We can use the HyperV Manager, but we need to get the GUI.
Enable RDP
We’ll enable RDP. And open the right port, since we did not see the port 3389 in our nmap results.
|
|
Add your account to Remote Desktop User
Since our user is Enterprise Admin, we can RDP without doing anything. But if we were a normal user or just Domain Admin, we might have to add our user to the Remote Desktop User
such as :
|
|
Log into the machine using RDP
But if you try to log into the machine using pass-the-hash it will throw you an error message saying that you cannot log into the machine using blank password.
In that case you can do two things :
- Change the policy to accept empty password logins
- Change the user password
The second one is the fastest since I know the command :
|
|
Now we can log into the machine using xfreerdp :
|
|
Get into the HyperV Manager
In order to reach the right panel, we’ll do this :
Windows -> Server Manager -> Tools -> HyperV Manager
Here we have our nextcloud VM !
But it’ll ask for some credential in the CLI. So I started struggling a lot. I missclicked on the “Checkpoint” feature that creates a snapshot and made the VM unusable. So I decided to erase the checkpoint and restart the machine. I then saw the Grub loader.
Bypass the authentication
I then remembered a root-me challenge that I solved a while ago. It is possible to bypass the authentication of a machine if grub is installed and the bootloader is not encrypted. By following this article.
At the grub startup, press “e” to edit the startup config. Then add init=/bin/bash
after the first UUID. Save the configuration using Ctrl + x
.
Continue the boot so you have a root shell.
|
|
Contempt - Revenge
A few hours after, we received a Discord notification saying that Contempt - Revenge
was released and fixed the unintended way.
Since I had no idea how to exploit what I’ve done in a proper maner, I decided to not go on it. But then I took a look at the number of solves…
It should not be that hard :)
Root
Since we already have a lot of informations from the previous machine, once again, if we’re lucky enough we can reuse them !
Hash spraying
It’s time to spray some hashes using crackmapexec.
|
|
Alright so the Administrator hash is not working on any users, let’s try other users. For exemple the hash of a domain user that do not have any special rights.
|
|
Since we know from the previous machine that aria.frost
and echo.rivers
are domain admins. Let’s see if we can get Domain Admin.
The Pwn3d! means that we are also local admin of the machine. Game over, we can just repeat the previous exploit steps from getting a shell.
To conclude
It is always fun to find an unintended way in a CTF Challenge. But we cannot blame the challenge maker, it is always hard to think about every exploit paths that can be possible.
Even if you make a hot fixe while the CTF is running, you cannot be sure that you’ve fixed the unintended ways.
Indeed, after the release of the supposed solution, I must admit that I’m glad that there was those fun unintended. Because I took pleasure to do this box in that way 😊