Summary of our Auditing AD Series

Rich
9 min readAug 20, 2022

Background

Welcome to the summary of our Auditing AD series. Parts I — XV are linked below:

Part I: 3 warm up questions to get us started

Part II: Who can reset the CISO’s password?

Part III: Who can execute DCSync?

Part IV: Who can modify the Domain Admins group?

Part V: Domain dominance in minutes via ACL abuse (i.e. why auditing AD matters)

Part VI: Why Allow statements matter a LOT more than Deny ones

Part VII: Sneaky persistence via hidden objects in AD

Part VIII: SDDL, what is it, does it matter?

Part IX: Do you know who owns your domain?

Part X: Who can push ransomware via Group Policy?

Part XI: Free ways to simplify auditing AD

Part XII: Sidenote on arcane rights like Self

Part XIII: Sidenote on the ScriptPath right

Part XIV: Self & so called “Effective Permissions”

Part XV: Inheritance Explained & an Example

Part XVI: Summary of our Auditing AD Series

Lessons Learned

I decided to make a summary as the lessons learned is a bit lengthy and covers Parts I — XII. Some are bullet points, others are more paragraph length. So without further ado, let’s sum this all up.

Effective permissions

The first lesson is that while there is such a thing as ‘effective permissions’, the term is a bit subjective. Microsoft has a tab in Active Directory User & Computers (ADUC) labeled Effective Access, but their definition of the term is a bit lacking in their online documentation.

Personally I prefer ADUC’s term, but that’s just my opinion. Since Microsoft doesn’t seem to have defined the term I’ll go with it.

Effective Access is not just what permissions a user currently has. It includes what permissions they can give themselves. If they have WriteProperty with ObjectType 00000000–0000–0000–0000–000000000000 on the ACL of the Domain Admins group then they are effectively a Domain Admin. If they have WriteDACL or WriteOwner on the group then the same applies. In fact if one has WriteOwner on any object then they can do whatever they want. If they are the owner then the ACL doesn’t even matter to them as they have implicit WriteDACL.

Bear in mind that there are other factors in play here too. It is an easy example, but valid nonetheless; if you have a DC that is unpatched against something like EternalBlue than anyone who can connect to it effectively owns your domain.

To recap, the table below shows the privileges that really matter in a security context:

If a Domain User has GenericAll, GenericWrite, WriteOwner, or WriteDACL rights on the Domain Admins group then they are effectively a Domain Admin. If they have WriteProperty or Self than it depends on what the exact ObjectType is, and it should probably be examined and revoked.

Conflicting statements in an ACL

In Part VI we ran through a scenario wherein our malicious insider was in two groups. One group was allowed WriteDACL on the domain root, the other was denied it.

However there was nothing stopping them from simply leaving one of those groups. Our insider leaves the denied group, and now they can modify the ACL on the domain root. This is obviously bad juju and will lead to a complete domain compromise. They also could have simply seized ownership and then taken the action.

In Part IX we ran through another scenario where a user was placed in two groups. One group had GenericAll allowed on the domain root. The other group had a couple of ExtendedRight ObjectTypes set to Deny and WriteDACL set to Deny. The user simply seized ownership of the object, removed the ExtendedRight Deny statement, and ran secretsdump.

Therefore relying on conflicting ACL statements to save your bacon is risky, to say the least. Microsoft states best practice is to give privileges to groups, not individual users. Everyone is already checking, or should be, that users and nested groups in a group belong in that group. Add the step of checking what groups have been given rights on a high value AD object such as the domain root. If a group should not have rights on it then simply remove the Allow statement. AD ACLs are like most ACLs, they have an implicit deny. If a group is not allowed a privilege then they do not have it.

This vendor’s product apparently would take an example ACL that contains GenericAll set to Allow, WriteDACL set to Deny, and ExtendedRight set to Deny and state that effectively the attacker cannot successfully execute secretsdump. However as we saw here the attacker would simply seize ownership and then do whatever they want. It bears repeating; the owner has implicit WriteDACL regardless of what is or isn’t in the ACL.

Monitor for changes to high value objects

The ACL on your domain root should rarely change, if ever. The same goes for objects such as the AdminSDHolder. Many SMEs such as Sean Metcalf do not recommend using the builtin groups such as Domain Admins or Backup Operators at all. They recommend carefully delegating the exact least privilege required to custom groups. Obviously the ACLs on these groups should also rarely change, and any change should be the result of planning and a change management process.

Therefore once Misconfiguration Debt is cleaned up, put an alert system in place for any changes to these privileges. There’s plenty of tools out there for this.

Defenders think in lists. Attackers think in graphs

The vendor who so kindly provided the pre-built AD environment in a VM seems to harbor a deep seated hatred towards BloodHound, as well as Netwrix, PowerShell, and a couple other things. I have no idea why. They called BloodHound “bloody inaccurate”. Presumably this is because BloodHound only enumerates Allow statements in ACLs, not Deny ones, as the tool’s authors have stated. This vendor also said things like

“In fact, some of these enthusiasts may have gotten a little too excited and even released some infantile tooling, which I believe goes by the name Bloodhound, and lo and behold it is one of the hottest pen-test tools today, even though it is massively inaccurate!”

As we saw in Part VI though, relying on Deny statements is risky. If a group should not have permissions then remove the Allow statement. If a user should not have permissions then remove them from the group. We saw in Part V how an attacker used nothing but BloodHound and PowerShell to pivot through the domain and escalate to Domain Admin. They did this in spite of explicit Deny statements regarding the user they initially compromised.

The vendor never said exactly why they think BloodHound is supposedly “bloody inaccurate”, but it seems they are accusing it of showing false positives. Are they really false positives though? I would remove an allow statement that shouldn’t be there. Additionally, false positives aren’t nearly as dangerous as false negatives.

BloodHound is a great free tool for visualizing escalation paths. It allows you to pick a user, pick a high value object in AD, and then see graphically what paths exist between them, if any. It also takes more than just ACLs into account.

Attackers don’t care about making tidy lists. They don’t care about your pre-conceived notions, what your job title is, how much the tools you are using cost, or if they have to pivot through C to get from A to B. If there is a path open then they will take it. Don’t give them a path.

Basic stuff, still bears repeating

The below is least privilege 101 stuff. I know this fictional org’s AD deployment was meant to practice auditing on, but I will still state the following since it did not follow best practices:

  • Proper hierarchy in AD matters
  • Plan out your architecture carefully
  • Use separate privileged user accounts for admins, helpdesk, etc
  • Put these separate privileged users in their own OU IOT aid tracking
  • Delegate carefully
  • Use privilege tiers

This is all stuff that SMEs such as Sean Metcalf advocate. None of this is new. It is important though. Attackers hardly need to exploit vulnerabilities or figure out how to escalate privileges if they can simply phish a Domain Admin.

Best practice dictates separate accounts for normal user activities and administrative ones. Administrative accounts should not have email addresses, obviously.

AD security is a bit of a misnomer

I believe Sean Metcalf uses the term simply because ‘AD Security’ is more succinct than saying ‘Windows domain security’. He discusses and shows how to attain comprehensive Windows domain security, so in that case the terms are interchangeable.

AD security is important, but it’s a component of overall Windows domain security. You can tighten up your delegations in AD and still get breached if you don’t fix the other things such as disabling the builtin Administrator or setting it to local only login, mitigating name poisoning, mitigating MITM6, limiting macros, etc and of course patching as things like SAMAccountName Spoofing pop up. These are just easy examples, not a complete list. Social engineering awareness training and identity verification are critical as well. Without it an attacker can just call up the helpdesk, impersonate an administrator, and get a password reset. This is why AD security assessments look at more than ACLs.

Summary

Overall I agree with this vendor, and I’m grateful that they provided the VM with a pre-built AD environment. It made for good auditing practice and finding the answer to their questions was a great learning experience. They are right that auditing is critical, even though it is not very exciting or sexy.

I am just not sure that I agree with their definition of ‘effective permissions’.

There is also more to auditing AD than just ACLs. Are stale user accounts being disabled and eventually deleted? After how long? Are users in AD tracked in the right org’s ATCTS? Are they compliant? If not compliant, are they being disabled automatically? Are users configured for smartcard login? Are privileged users? Are domain workstations on the current baseline? The list goes on. The good news is that if your IA folks learn simple querying syntax and how to effectively Google then they can audit all this.

In the end, follow best practices and audit. Effective auditing is really not much different than enumerating. You can use PowerView, BloodHound, builtin PowerShell, and other free tools or you can pay for a tool. The important thing is that you actually do it and fix what you find.

References

Microsoft on effective permissions: https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc772184(v=ws.11)?redirectedfrom=MSDN

One vendor’s criticism of a great free tool: https://www.active-directory-security.com/2020/02/bloodhound-for-ad-is-bloody-inaccurate.html

Info on BloodHound updates: https://wald0.com/?p=112

Sean Metcalf presentation on Windows domain security: https://adsecurity.org/wp-content/uploads/2019/02/2019-ITDefense-SecuringActiveDirectoryAdministration-Metcalf-Final.pdf

John Lambert’s advice: https://github.com/JohnLaTwC/Shared/blob/master/Defenders%20think%20in%20lists.%20Attackers%20think%20in%20graphs.%20As%20long%20as%20this%20is%20true%2C%20attackers%20win.md

John Lambert on Defender’s Mindset: https://medium.com/@johnlatwc/defenders-mindset-319854d10aaa

SAMAccountName spoofing: https://pentestlab.blog/2022/01/10/domain-escalation-samaccountname-spoofing/

Lapsus social engineering: https://www.techrepublic.com/article/microsoft-warns-destructive-attacks-lapsus-cybercrime-group/

Microsoft on DEV-0537, aka Lapsus$, TTPs: https://www.microsoft.com/security/blog/2022/03/22/dev-0537-criminal-actor-targeting-organizations-for-data-exfiltration-and-destruction/

Trimarc AD Security Assessment: https://www.trimarcsecurity.com/ad-security-assessment

Microsoft AD Security Assessment: https://docs.microsoft.com/en-us/services-hub/health/getting-started-adsecurity

--

--

Rich

I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.