HTB: Fluffy
This machine is built on Active Directory and shows how a set of seemingly limited privileges can be chained to compromise a domain.
Introduction
I’ll keep the initial enumeration and straightforward steps brief, and focus this write-up on the parts I found most interesting and the new techniques I learned, especially the BloodHound ACL attack path, Shadow Credentials, and AD CS / ESC16 exploitation.
The main attack path was:
j.fleischman
│
▼
SMB / IT
│
▼
NTLM Hash Leak
│
▼
p.agila
│
▼
Service Account Managers
│
│ GenericAll
▼
Service Accounts
│
├──────── GenericWrite ────────► winrm_svc
│ │
│ ▼
│ WinRM
│ │
│ ▼
│ user.txt
│
└──────── GenericWrite ────────► ca_svc
│
▼
ESC16
│
▼
Administrator
│
▼
root.txtInitial Enumeration
The target was an Active Directory Domain Controller for:
Domain: fluffy.htb
DC: dc01.fluffy.htb
IP: 10.129.232.88I started with the usual service enumeration and SMB discovery.
Since SMB was accessible, I enumerated the available shares and found an interesting share IT
The share contained a PDF that provided information about a vulnerability relevant to the environment.
The interesting part was that this vulnerability could be abused to trigger an NTLM authentication attempt, allowing an NTLM hash to be captured.
This eventually gave me credentials for: p.agila
At this point, I moved from basic enumeration to Active Directory enumeration.
Active Directory Enumeration
With valid domain credentials, I used BloodHound to map users, groups, and ACL relationships
bloodhound-python -d fluffy.htb -u 'p.agila' -p '[redacted]' -ns 10.129.232.88 -c allOnce I had Neo4j and BloodHound installed, I imported my collected data and started to analyze the Active Directory graph to find interesting relationships and potential attack paths.
The interesting part wasn’t a single vulnerable account, but the way several permissions could be chained together.
The first relevant relationship was:
p.agila
│
│ MemberOf
▼
Service Account Managers
│
│ GenericAll
▼
Service AccountsThis immediately gave me an interesting direction to investigate.
BloodHound ACL Chain
GenericAll
BloodHound showed that:
Service Account Managers
│
│ GenericAll
▼
Service AccountsSince p.agila was a member of Service Account Managers, this meant that p.agila could exercise the control inherited from that group over Service Accounts.
The important point here was that the target of the GenericAll permission was a group, not an individual user.
That made the group membership itself part of the attack path.
GenericWrite over winrm_svc
BloodHound also showed:
Service Accounts
│
│ GenericWrite
▼
winrm_svcSo the complete path became:
p.agila
│
│ MemberOf
▼
Service Account Managers
│
│ GenericAll
▼
Service Accounts
│
│ GenericWrite
▼
winrm_svcwinrm_svc was also a member of:
Remote Management Userswhich made WinRM the relevant remote access mechanism once authentication as the account was obtained.
Shadow Credentials — First Attempt
Because Service Accounts had GenericWrite over winrm_svc, I tried to abuse the account using Shadow Credentials.
The idea behind Shadow Credentials is to add a new Key Credential to an AD account and then use the corresponding private key for authentication.
However, my first attempt failed:
Could not update Key Credentials for 'winrm_svc' due to insufficient access rights
...
00002098
INSUFF_ACCESS_RIGHTSInitially, this looked confusing because BloodHound clearly showed the GenericWrite relationship.
I went back through the attack path and checked the effective permissions.
The important detail was that p.agila was not yet a member of Service Accounts
Therefore, although BloodHound showed:
Service Accounts
│
│ GenericWrite
▼
winrm_svcthat permission was not yet effective for my current security context.
Resolving the Permission Issue
The previous ACL in the chain was:
p.agila
│
▼
Service Account Managers
│
│ GenericAll
▼
Service AccountsSince Service Account Managers had GenericAll over Service Accounts, I used that control to add p.agila to the Service Accounts group.
After the membership change, the effective path became:
p.agila
│
│ MemberOf
▼
Service Accounts
│
│ GenericWrite
▼
winrm_svcThis resolved the INSUFF_ACCESS_RIGHTS issue and allowed me to continue with the attack against winrm_svc
Lesson Learned
This was one of the most useful parts of the machine for me.
BloodHound shows potential attack paths, but seeing an ACE does not necessarily mean that the final privilege is immediately usable.
When the Shadow Credentials attempt returned: INSUFF_ACCESS_RIGHTS
I went back through the graph and checked each relationship in the chain.
The actual problem was one step earlier in the path: I needed to obtain the effective group membership first.
winrm_svc and Remote Access
Once the required access to winrm_svc was established, the account's membership in:
Remote Management Usersprovided the path to remote management through WinRM.
The attack path was therefore:
p.agila
↓
Service Account Managers
↓
GenericAll
↓
Service Accounts
↓
GenericWrite
↓
winrm_svc
↓
Remote Management Users
↓
WinRMThis allowed me to obtain the user-level foothold and retrieve:
user.txtThe interesting part here was that the initial account did not directly have administrative privileges.
Instead, the compromise was built through AD group relationships and delegated permissions.
Finding the Second Attack Path
Get Hadeer Amr’s stories in your inbox
Join Medium for free to get updates from this writer.
While analyzing the same Service Accounts group, I noticed another important relationship:
Service Accounts
│
│ GenericWrite
▼
ca_svcThis was even more interesting because ca_svc was associated with:
Cert PublishersThat suggested that the account could potentially be useful in an AD CS attack.
The attack path now had two branches:
Service Accounts
/ \
/ \
GenericWrite GenericWrite
/ \
▼ ▼
winrm_svc ca_svc
│ │
▼ ▼
WinRM AD CS
│ │
▼ ▼
user.txt ESC16AD CS Enumeration
I then enumerated the Active Directory Certificate Services configuration using Certipy:
certipy-ad find -u 'p.agila@fluffy.htb' -p '[redacted]' -dc-ip 10.129.232.88 -target dc01.fluffy.htb -stdoutThe CA was:
CA Name: fluffy-DC01-CA
DNS Name: DC01.fluffy.htbThe most interesting finding was:
Disabled Extensions:
1.3.6.1.4.1.311.25.2Understanding ESC16
The OID:
1.3.6.1.4.1.311.25.2is associated with the SID Security Extension.
This extension is important because it provides a binding between a certificate and the security identity represented by the certificate.
In this environment, the extension was disabled globally on the CA.
This configuration corresponds to:
ESC16So instead of simply relying on Certipy’s vulnerability label, I could understand the actual misconfiguration:
SID Security Extension
│
│ Disabled globally
▼
CA misconfiguration
│
▼
ESC16This was the key AD CS finding that connected ca_svc to the final privilege escalation.
Exploiting ca_svc
Since Service Accounts had GenericWrite over ca_svc, I could modify attributes of the account.
The goal was to manipulate the account’s UPN before requesting a certificate.
I used:
certipy-ad account update -u 'p.agila@fluffy.htb' -p '[redacted]' -dc-ip 10.129.232.88 -target 'dc01.fluffy.htb' -user 'ca_svc' -upn 'administrator'The important output was:
[*] Updating user 'ca_svc': userPrincipalName : administrator
[*] Successfully updated 'ca_svc'This was a particularly interesting moment because it demonstrated the practical impact of the GenericWrite permission.
The BloodHound relationship:
Service Accounts
│
│ GenericWrite
▼
ca_svcwas no longer just a graph edge.
It allowed me to modify the target account in a way that became useful for the AD CS attack.
The state was now:
ca_svc
│
│ UPN modified
▼
administratorCertificate Request
The next step was to request a certificate from fluffy-DC01-CA
using the User template.
The command was:
certipy-ad req -u 'ca_svc@fluffy.htb' -hashes '<CA_SVC_NT_HASH>' -dc-ip 10.129.232.88 -target 'dc01.fluffy.htb' -ca 'fluffy-DC01-CA' -template 'User'The request reached the RPC stage, but I encountered:
[*] Requesting certificate via RPC
[-] Got error: The NETBIOS connection with the remote host timed out.So at this point, the certificate request itself had not successfully completed.
I would not describe the certificate issuance or Administrator authentication as completed until this connectivity issue is resolved.
The intended final ESC16 chain is:
ca_svc
│
│ UPN = administrator
▼
Certificate Request
│
▼
Administrator Certificate
│
▼
administrator.pfx
│
▼
Certificate Authentication
│
▼
Administrator
│
▼
root.txtFinal Attack Path
Putting everything together, the machine demonstrates two related privilege-escalation paths originating from the same AD group:
p.agila
│
│ MemberOf
▼
Service Account Managers
│
│ GenericAll
▼
Service Accounts
/ \
/ \
GenericWrite GenericWrite
/ \
▼ ▼
winrm_svc ca_svc
│ │
▼ ▼
Remote Management ESC16
Users │
│ ▼
▼ Administrator
WinRM │
│ ▼
▼ root.txt
user.txtWhat I Learned
The most interesting part of this machine for me was not a single vulnerability, but understanding how multiple Active Directory permissions can be chained together.
The key concepts I practiced were:
BloodHound Attack Paths
Instead of looking at individual users and permissions, I learned to follow the complete relationship:
User
↓
Group
↓
ACL
↓
Target Object
↓
Authentication / PrivilegeEffective Permissions
An ACE shown by BloodHound does not automatically mean that I can immediately exploit the final target.
The INSUFF_ACCESS_RIGHTS error was a good example.
I had to go back one step and make sure that the required group membership was actually effective.
GenericAll vs GenericWrite
I also got a clearer understanding of the difference between:
GenericAlland:
GenericWriteGenericAll provides broad control over an object, while GenericWrite allows modification of permitted attributes.
The impact depends on what object is being controlled and which attributes can be changed.
AD CS
The second major learning point was understanding that AD CS can become another privilege-escalation boundary inside an Active Directory environment.
In this case:
GenericWrite
↓
ca_svc
↓
AD CS
↓
SID Security Extension disabled
↓
ESC16The important part was understanding why the configuration created an attack path rather than simply running Certipy and copying its output.
Conclusion
Fluffy was a good example of how an Active Directory compromise can develop through several layers of delegated access.
The attack did not depend on one obvious administrative credential.
Instead, the path was built through:
Initial Access
↓
Credential Discovery
↓
Active Directory Enumeration
↓
BloodHound
↓
GenericAll
↓
GenericWrite
↓
Service Account Control
↓
WinRM
↓
AD CS Enumeration
↓
ESC16
↓
Certificate-Based Privilege EscalationThe most valuable takeaway for me was learning to treat BloodHound as an attack-path analysis tool, rather than simply a tool for finding interesting ACEs.
When an exploitation attempt failed, such as INSUFF_ACCESS_RIGHTS the solution was not to randomly try another technique. I went back through the graph, identified which permission in the chain was not yet effective, fixed that prerequisite, and continued from there.
واخيرا اللهم علمني ما ينفعني و انفعني بما علمتني
Wishing This Is Helpful










