Press "Enter" to skip to content

The PowerView PowerUsage Series #4

This is a short follow-up to my “A Guide to Attacking Domain Trusts” post, and the fourth post in my “PowerView PowerUsage” series. It follows the same Scenario/Solution/Explanation pattern as the previous entries, with the original post containing a constantly updated list of the entire series.

One of the methods for trust hopping that I briefly covered in the trust post (under the “Case 3: Foreign ACL Principals” section) was the enumeration of DACL/ACE entries on domain objects where the principal (i.e. the user/group that holds the right over the specified object) is in a different domain than the target object. As mentioned, most of the ntSecurityDescriptor property of Active Directory objects is: (1) accessible to any domain authenticated user, and (2) replicated in the global catalog. This means that you can query the DACLs for all objects in a trusting domain from your current trusted domain context and filter any ACE entries where a foreign security principal has the given right on the object you’re enumerating.

The Scenario

You want to figure out what DACL/ACE entries in a specified domain contain principals NOT located in that specified domain. That is, you want to find inbound cross-domain security descriptor relationships for a target domain. For this example, we’ll assume that we’re currently in testlab.local and are targeting dev.testlab.local.

The Solution

The Explanation

This snippet looks pretty similar to the one from the third post in this series. Before we do anything else, we grab the SID (security identifier) of the foreign domain with PowerView’s Get-DomainSid. This allows us to filter out ACE entries where the SecurityIdentifier of the trustee/principal (the object that has the rights) is in the same domain as the enumerated object. This lets us later filter for these cross-trust ACE relationships.

To kick everything off, we use PowerView’s Get-DomainObjectAcl to enumerate the ACEs for certain objects in a foreign domain, specified with -Domain ‘dev.testlab.local’. There’s more data about how this works under the hood in the “Data Enumeration Across Trusts With PowerView” section of my A Guide to Attacking Domain Trusts post. The -LDAPFilter differs from the third post, however. In this case we are searching for group policy, group, user, computer, and domain objects, i.e. objects we currently have takeover primitives for. Since computer objects also contain ‘user’ in their objectclass, we don’t need to explicitly specify ‘computer’. Like the last snippet, the -ResolveGUIDs flag indicates that any target GUIDs in the ACEs should be resolved to their human-readable names.

We then implement a custom filter with ? {…} (Where-Object), with lots of clauses:

  • First, we check to make sure that the AceType specifies an ALLOW entry.
  • Second, we again use the ‘^S-1-5-.*-[1-9]\d{3,}$’ regex against the SecurityIdentifier to return only results where the security identifier of the trustee has a relative identifier (RID) of -1000 and above. This filters out principals that are built, reducing some of the noise.
  • Third, we filter out principals from the same domain as the object by executing a negative regex match against the previously enumerated foreign domain SID.
  • Finally, the last clause matches for rights in the ACE that indicate some type of control relationship (generic all rights, rights to change the owner, or other “object takeover” primitive) that enables compromise of the target object. For more information on this type of relationship/attack, check out @_wald0’s and my “An ACE Up the Sleeve” whitepaper from Black Hat 2017.

Next, we process each ACE result on the pipeline by way of % {…} (ForEach-Object). Instead of extracting out specific properties and creating a new object, like in the third post, we resolve the SecurityIdentifier of the ACE to a distinguished name by using PowerView’s Convert-ADName with the -OutputType set to DN (distinguished name) and add this as a new property to the resulting ACE object returned on the pipeline.

Enumerating ACEs in a foreign domain that cross some type of trust boundary.

Note: this will likely take a while to run, because we’re enumerating and parsing the security descriptor information for a large number of objects.


Also published on Medium.

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *