To enumerate AD environment, there are 2 common tools:
1. PowerView
https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1
. .\PowerView.ps1
2. ActiveDirectory.psd1
- https://docs.microsoft.com/en-us/powershell/module/addsadministration/?view=win10-ps
- https://github.com/samratashok/ADModule
Import-Module .\Microsoft.ActiveDirectory.Management.dll
Import-Module .\ActiveDirectory.psd1
3. Bloodhound (C# and PowerShell Collectors)
https://github.com/BloodHoundAD/BloodHound
BloodHound uses Graph Theory for providing the capability of mapping the shortest path for interesting thigns like Domain Admins.
BloodHound has built-in queries for frequently used actions. It supports custom Cypher queries.
The following steps assume you are using BloodHound on Kali:
Step 1: Run ingestor/collector using PowerShell or C#
. .\BloodHound-master\Ingestors\SharpHound.ps1
Invoke-BloodHound -CollectionMethod All
Note we can avoid tools like MS ATA by using:
Invoke-BloodHound -CollectionMethod All -ExcludeDomainControllers
A file will be generated.
The remaining steps see Lab - BloodHound
Get Current Domain
- PowerView
Get-NetDomain
- AD Module
Get-ADDomain
Get object of another domain
- PowerView
Get-Domain -Domain techcorp.local
- AD Module
Get-ADDomain -Identity techcorp.local
Get domain SID of the current domain
- PowerView
Get-DomainSID
- AD Module
(Get-ADDomin).DomainSID
Get domain policy of the current domain
- PowerView
Get-DomainPolicyData
(Get-DomainPolicyData).systemaccess
Get domain policy of another domain
- PowerView
(Get-DomainPolicyData -Domain techcorp.local).systemaccess
Get a list of users in teh current domain
- PowerView
Get-DomainUser
Get-DomainUser -Identity studentuser64
- AD Module
Get-ADUser -Filter * -Properties *
Get-ADUser -Identity studentuser64 -Properties *
Note:
- For DC, it doesn't matter if the default Domain Admin is renamed - always identified by the SID
Note that properties of users in the current domain are very useful for situational awareness. For example,
-
it is abnormal that a user has
logoncount = 0
- this should be more like a decoy user; -
it is also interesting to see
pwdlastset
to be a very old date. -
PowerView
Get-DomainUser -Properties pwdlastset
- AD Module
Get-ADUser -Filter * -Properties * | Select -First 1 | Get-Member -MemberType *Property | Select Name
Get-ADUser -Filter * -Properties * | Select name, @{expression={[datetime]::fromFileTime($_.pwdlastset)}}
Search for a particular string in a user's attributes
- PowerView
Get-DomainUser -LDAPFilter "Description=*built*" | Select Name, Description
- AD Module
Get-ADUser -Filter 'Description -Like "*built*"' -Properties Description | Select Name, Description
Get a list of computers in the current domain
- PowerView
Get-DomainComputer | Select Name
Get-DomainComputer -OperatingSystem "Windows Server 2019 Standard"
Get-DomainComputer -Ping
- AD Module
Get-ADComputer -Filter * | Select Name
Get-ADComputer -Filter 'OperatingSystem -Like "*Windows Server 2019 Standard*"' -Properties OperatingSystem | Select Name, OperatingSystem
Get-ADComputer -Filter * -Properties DNSHostName | %{Test-Connection -Count 1 -ComputerName $_.DNSHostName}
Get-ADComputer -Filter * -Properties *
Get all the groups in the current domain
- PowerView
Get-DomainGroup | Select Name
Get-DomainGroup -Domain techcorp.local
- AD Module
Get-ADGroup -Filter * | Select Name
Get-ADGroup -Filter * -Properties *
Get all groups containing the word "admin" in the group name
- PowerView
Get-DomainGroup *admin* | Select Name
- AD Module
Get-ADGroup -Filter 'Name -like "*admin*"' | Select Name
Get all members of the Domain Admins group
- PowerView
Get-DomainGroupMember -Identity "Domain Admins" -Recurse
- AD Module
Get-ADGroupMember -Identity "Domain Admins" -Recursive
Get the group membership for a user
- PowerView
Get-DomainGroup -UserName studentuser64
- AD Module
Get-ADPrincipalGroupMembership -Identity studentuser64
Get all the local groups on a machine
-
Need Admin Privilege on non-dc machines
-
PowerView
Get-NetLocalGroup -ComputerName us-dc
Get members of all local groups on a machine
- Need Admin Privilege on non-dc machines
- PowerView
Get-NetLocalGroupMember -ComputerName us-dc
Get members of the local group "Administrator" on a machine
- Need Admin Privilege on non-dc machines
- PowerView
Get-NetLocalGroupMember -ComputerName us-dc -GroupName Administrators
Group Policy provides the ability to manage/changes configuration easily and centrally in AD. It allow configuration of:
- Security settings
- Registry-based policy settings
- Group policy preferences like startup/shutdown/logon/logoff scripts settings
However, GPO can be abused for various attacks like privesc, backdoors, persistence, etc.
Get list of GPO in the current domain
- PowerView
Get-DomainGPO
Get-DomainGPO -ComputerIdentity student64.us.techcorp.local
Get GPO(s) which use Restricted Group or groups.xml for interesting users
- PowerView
Get-DomainGPOLocalGroup
Get users which are in a local group of a machine using GPO
- Give interesting users to target
- PowerView
Get-DomainGPOComputerLocalGroupMapping -ComputerIdentity student64.us.techcorp.local
Get-DomainGPOComputerLocalGroupMapping -ComputerIdentity us-mgmt.us.techcorp.local
Get machines where the given user is a member of a specific group
Get-DomainGPOUserLocalGroupMapping -Identity studentuser64 -Verbose
Get OUs in a domain
- PowerView
Get-DomainOU
- AD Module
Get-ADOrganizationalUnit -Filter * -Properties *
Get GPO applied on an OU
- Read GPOname from gplink attribute from
Get-DomainOU
- PowerView
Get-DomainGPO -Identity '{FCE16496-C744-4E46-AC89-2D01D76EAD68}'
Get users which are in a local group of a machine in any OU using GPO
- PowerView
(Get-DomainOU).distinguishedname | %{Get-DomainComputer -SearchBase $_} | Get-DomainGPOComputerLocalGroupMapping 2>$null
Get users which are in a local group of a machine in a particular OU using GPO
- PowerView
(Get-DomainOU -Identity 'OU=Mgmt,DC=us,DC=techcorp,DC=local').distinguishedname | %{Get-DomainComputer -SearchBase $_} | Get-DomainGPOComputerLocalGroupMapping 2>$null
For older versions of PowerView, the below commands would also work:
Get-DomainGPOComputerLocalGroupMapping -OUIdentity 'OU=Mgmt,DC=us,DC=techcorp,DC=local'
Find-GPOComputerAdmin -OUName 'OU=Mgmt,DC=us,DC=techcorp,DC=local'
Access Control Model enables control on the ability of a process to access objects and other resources in AD based on:
- Access Tokens (security context of a process - identity and privs of user)
- Security Descriptors (SID of the owner, Discretionary ACL (DACL) and System ACL (SACL))
- Ref:
https://docs.microsoft.com/en-us/windows/win32/secauthz/access-control-model
Access Control List (ACL) is a list of Access Control Entries (ACE), which corresponds to individual permission or audits access.
- i.e. Who has the permission and what can be done on an object?
ACLs are vital to security architecture of AD. There are 2 types of ACL:
- DACL: Define the permissions trustees (a user / group) have on an object
- SACL: Log success and failure audit messages when an object is accessed
Get the ACLs associated with a specified object
- PowerView
Get-DomainObjectAcl -Identity student64 -ResolveGUIDs
Get the ACLs associated with the specified LDAP path to be used for search
- PowerView
Get-DomainObjectAcl -Searchbase "LDAP://CN=Domain Admins,CN=Users,DC=us,DC=techcorp,DC=local" -ResolveGUIDs -Verbose
Note:
- Active Directory Rights:
https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectoryrights?redirectedfrom=MSDN&view=dotnet-plat-ext-5.0 - Extended Rights:
https://technet.microsoft.com/en-us/library/ff405676.aspx
Search for interesting ACEs
- Use without
-ResolveGUIDs
for faster result - PowerView
Find-InterestingDomainAcl -ResolveGUIDs
Get the ACLs associated with the specified path
- PowerView
Get-PathAcl -Path "\\us-dc\sysvol"
In an AD environment, trust is a relationship between two domains or forests which allows users of one domain or forest to access resources in the other domain or forest.
Trust can be automatic (parent-child / same forest / etc.) or established (forest, external).
Trusted Domain Objects (TDOs) represent the trust relationships in a domain.
One-way Trust
- Unidirectional
- Users in the trusted domain can access resources in the trusting domain but the reverse is not true
Two-way Trust
- Bi-directional
- Users of both domains can access resources in the other domain
Transitivity
Transitive - can be extended to establish trust relationships with other domains. All the default intra-forest trust relationships (Tree-root / Parent-Child) between domains within a same forest are transitive 2-way trusts.
Nontransitive - cannot be extended to other domains in the forest. It can be 1-way or 2-way. This is the default trust (called external trust) between 2 domains in different forests when forests do not have a trust relationship.
Default/Automatic Trusts
-
Parent-child Trust - Automatically created betweem the new domain and the domain that precedes it in the namespace hierarchy, whenever a new domain is added in a tree. (e.g.
us.techcorp.local
is a child oftechcorp.local
). This trust is always2-way transitive
. -
Tree-root trust - Automatically created between whenever a new domain tree is added to a forest root. This trust is always
2-way transitive
.
External Trusts
It is between two domains in different forests when forests do not have a trust relationship. It can be 1-way
or 2-way
and is non-transitive
.
Forest Trust
Forest Trusts are:
- between forest root domain
- cannot be extended to a 3rd forest (no implicit trust)
- can be 1-way or 2-way
- can be transitive or non-transitive
Get a list of all domain trusts for the current domain
- PowerView
Get-DomainTrust
Get-DomainTrust -Domain techcorp.local
- AD Module
Get-ADTrust
Get-ADTrust -Identity techcorp.local
Get details about the current forest
- PowerView
Get-Forest
- AD Module
Get-ADForest
Get all domains in the current forest
- PowerView
Get-ForestDomain
- AD Module
(Get-ADForest).Domains
Get all global catalogs for the current forest
- PowerView
Get-ForestGlobalCatalog
- AD Module
Get-ADForest | Select -ExpandProperty GlobalCatalogs
Map trusts of a forest
- PowerView
Get-ForestTrust
- AD Module
Get-ADTrust -Filter 'intraForest -ne $True' -Server (Get-ADForest).Name
Find all machines on the current domain where the current user has local admin access
-
The following command queries the DC of the current or provided domain for a list of computers (
Get-DomainComputer
), and then use multi-threadedTest-AdminAccess
on each machine. -
PowerView
Find-LocalAdminAccess -Verbose
This can also be done with the help of remtoe admin tools like WMI and PS Remoting. Quite useful in cases ports (RPC and SMB) used by Find-LocalAdminAccess
are blocked. You can use:
Find-WMILocalAdminAccess.ps1
Find-PSRemotingLocalAdminAccess.ps1
Find computers where a domain admin (or specified user/group) has sessions
- PowerView
Find-DomainUserLocation -Verbose
Find-DomainUserLocation -UserGroupIdentity "StudentUsers"
This function queries the DC of the current or provided domain for members of the given group (Domain Admins by default) using Get-DomainGroupMember
, gets a lsit of computer Get-DomainComputer
and list sessions and logged on users Get-NetSession
/ Get-NetLoggedOn
from each machine.
Find computers where a domain admin session is available and curretn user has admin access
- Use
Test-AdminAccess
- PowerView
Find-DomainUserLocation -CheckAccess
Find computers (File Servers / Distributed File Servers) where a domain admin session is available
- PowerView
Find-DomainUserLocation -Stealth
Most of the enumeration mixes really well with the normal traffic to the DC. But local admin hunting and Domain Admins hunting leave Windows Security Event 4624 and 4634 on ALL the tested machines and additional 4672 in case of success.
Other than detection, hardening can be done on both DC and other machines to contain the information provided by the queried machine.
Netcease is a script which changes permissions on the NetSessionEnum
method by removign permission for Authenticated Users group. This fails many of the attacker's session enumeration and hence user hunting capabilities.
.\NetCease.ps1
Another interesting script from the same author is SAMRi10 which hardens Windows 10 and Server 2016 against enumeration which usees SAMR protocol (like net.exe).