Active Directory Enumeration is a challenge for even some of the seasoned attackers and it is easy to miss some key components and lose the change to elevate that initial foothold that you might receive. In this article, we bring you methods that you can use to enumerate AD using PowerShell.
We have configured an Active Directory Lab that mimics a Real-Life Environment with a bunch of Users, Machines, and Vulnerabilities. In this Article/Demonstration, we are focused on our ability to Enumerate Information that can be then further be used to elevate privileges or be able to help with Lateral Movement. A tool by the name of PowerView was developed and integrated by Will Schroeder (a.k.a harmj0y). It soon became an integral toolkit to perform Active Directory Attacks and Enumeration. For this demonstration, we will assume that we have gained the initial foothold. Now we will use PowerShell with PowerView to enumerate the machine and the Domain. In case you run into difficulties running any of the commands depicted use the Official GitHub for the Installation Process.
In our Active Directory Lab Setup, we created 7 users with different roles and privileges. We can confirm this by Viewing the Active Directory Users and Computers as shown in the image.
This was to show and co-relate the information that we are about to enumerate using PowerShell. The attacker has transferred the PowerView to the Target System. To run the PowerShell Script on the System, the Execution Policy must be set to Bypass as shown in the image. Next, Importing the Modules from the PowerView Script. This was a one-time process. After this, the attacker can directly use the Modules to perform Enumeration. To get the Users that are active on the Network the attacker ran the following command.
Users that are enumerated are not just restricted to Usernames. Data collected consist of logoncount that can give an idea of an active or inactive user in the network. Next, there is a badpasswordtime which tells the last time and date that an attempt to log on was made with an invalid password on this account. Then a small description of the user with the names of groups that this particular user is part of. At last, it shows the date and time since the last password change. All this information is very important when the attacker is trying to learn about the User Behavior.
Similar Information is available for the users Yashika and Geet.
To get an abstract list of users created on the Network, Grab the Common Name by using the select command on the output of the Get-NetUser Module.
Administrator, Yashika, Geet, Aarti, Raj, Pavan, Jeenali, Japneet, etc. are the various users in this Network Environment.
Similarly to gather information about a particular user. For example, after the attacker extracted users in the previous section, a specific user is chosen to be targeted. Now, more information about a particular user is required. This can be done using a flag -Username with the username that the attacker wants to target. In this case, the attacker chose Yashika User.
Get-NetUser -UserName yashika |
A streamlined but detailed output regarding the Yashika User is extracted by the attacker.
When working with the Users and their properties, we see that there is a variable by the name pwdlastset. We can use this to check which user is reluctant to change their passwords. This can be configured to any of the property that was extracted in the previous. For this demonstration, we will be extracting the password last set property of all the users.
Get-UserProperty -Properties pwdlastset |
There are times where there are so many users in the network that it becomes very difficult for the Domain Administrator to keep track of all users or their credentials. This is where they resort to some of the risky techniques to save the credentials information. A good example that I have seen more than ever in the real environment is saving the credentials or important information about the user in their description. This can be extracted by the use of Find-UserField with a search term. In this demonstration, we used the term pass to search for potential passwords. The user Yashika has their password written and saved in their description. This is not limited to this type of information. Lots of different data can also be extracted by using the right set of keywords such as built. This will extract the attacker from the accounts that are Built-in Accounts.
Find-UserField -SearchField Description -SearchTerm "pass" Find-UserField -SearchField Description -SearchTerm "built" |
The information that is extracted using UserField is the information stored at the Properties of that user. While on the Server this can be viewed by opening the list of users and then right-clicking on any particular user. Then choose Properties. This will lead to a window similar to the one shown in the image below. Here, we can see that the Administrator has provided the password in their Description Field. This goes without saying that this should not be done at all. From the attacker’s point of view, always check for such descriptions as they will contain some clue that can help you get further.
While enumerating the Domain, the attacker that has a targeted approach will be able to extract more data and that faster. The setup at home servers that we practice on doesn’t have a time constrain that attackers have to adhere to. In real-life red teaming assessments, if the attacker is taking their sweet time to extract data, they pose a risk to be detected and get thrown out of their initial access or even get captured. This is where some Reconnaissance comes in handy. During the Recon, the attacker can have a list of specific users that take priority to enumerate first and it is possible that those users will help the attacker to elevate access and they won’t need to enumerate other users. This reduces the time as well as the noise and logs that will be created when the attacker enumerates users. This is solved using the Invoke-UserHunter. It helps the attacker search or as its name suggests “hunt” for those specific users. It will accept usernames and if the attacker has a handy list of usernames, it will graciously accept it as well. It accepts the domain group and host lists as well. It uses a mix of Get-NetSessions and Get-NetLoggedon against every server and then compares the result against the target user set. Then again it raises the question of the amount of noise it will generate. But giving it a smaller number of usernames in the list or even giving it a single username will help the attacker reduce the noise significantly. It is worth noting that Invoke-UserHunter will run without any Administrator Privileges. Moving to the demonstration, the attacker runs the Invoke-UserHunter directly without any users or options. It will run against all users that it could find that usually is the Administrator. It can be observed that the information extracted is pretty basic but useful in the case of profiling a user.
A pretty nifty feature that was interesting enough to add was the CheckAcess function. This feature allows the attacker to check for the Local Administrator Access of that particular user or list of users that they provided. In the demonstration, the attacker tested the Access of the Administrator which without surprise comes to be True.
Invoke-UserHunter -CheckAccess |
When the attacker needs to extract the domain-related information directly from the target server, Get-NetDomain got them covered. It pretty much extracts the Domain data that includes the Forest Name, Domain Controllers with Children (that might be configured in a real environment server). Then there is the Name of the Parents with the RidRoleOwner which is a DC Object that holds the relative identifier (RID) master role and PdcRoleOwner another DC Object that holds the PDC emulator role for that specific Domain.
In case the attacker wanted to go against a specific domain, they can use a domain option by providing the name of the exact domain that they are looking for and Get-NetDomain will extract the data for that particular domain.
Get-NetDomain -domain "ignite.local" |
Next on the lineup, we have the Get-NetDomainController. This provides the information of the particular server device instead of the domain. When an attacker wants to extract the data about the Domain Controller Machine then this tool can be used. It extracts the Forest Information, with the Time and Date configured on the Server. IT tells the OS Version that can help constraint the search for Kernel Exploits for the attacker. Then the attacker has the IP Addressing data with the Inbound and Outbound connections.
Similar to the Get-NetDomain the attacker can configure Get-NetDomainController to be targeted to a specific domain. The scenario that the attacker might be looking at multiple domains set up with multiple server setup so the attacker can use the -Domain option to target that specific Domain Controller inside the Domain.
Get-NetDomainController -Domain ignite.local |
What seems to be a pretty simple option can turn out to be one of the most used tools to extract a huge amount of data from either the Domain Controller or even a single device. If the attacker runs the Get-NetComputer directly on the Domain Controller machine as demonstrated, it will reveal the Computer Names of all the devices connected in the Domain.
Moving on, if the attacker decides to use -Ping Option then they can get the list of all the devices that can be pinged from the machine they are running the Get-NetComputer from.
If the attacker doesn’t want to extract the data one parameter at a time there is an option to extract all the data from the Machine. This can be done with the FullData option, but keep in mind that a large amount of data extraction leads to large chances of getting detected.
Get-NetComputer -FullData |
Moreover, if the attacker decides to use the -OperatingSystem option with the Get-NetComputer and provide the Name of the OS as a parameter then they can extract all the machines that are running that specific Operating System.
Get-NetComputer -Operatingsystem "Windows Server 2016 Standard Evaluation" |
Next on the list is the UserProperty. Up until now, the attacker can extract the users and very little information about them. This was limited but this problem is solved using UserProperty. With it, the attacker can aim to those niche details about any particular property. Some of the information extractable is check for Administrator Level Access, Password Time, Password Change Date, Description of the User, check what group the different users are a part of, and much more.
To target a specific Property, the attacker can use the Properties option and specify the property they want to inquire about. For the demonstration, the property that was inquired here was badpwdcount. This tells the attacker about the unsuccessful attempts that were made against all the users.
Get-UserProperty -Properties badpwdcount |
The attacker can focus on the logoncount property to get an understanding as to which of the users are dormant and which among them are active. In a real-life scenario, inactive users might be the users in a network of ex-employees that have been overlooked by the Administrator. This can create a problem as firstly these accounts would not adhere to change their password also the attack mounted on these accounts won’t raise flags being these users are legit.
Get-UserProperty -Properties logoncount |
Apart from the domain information and the user information, the attacker can also gain information about the forests and there can be multiple forests inside a domain. To procure information about the forest in the current user’s domain is to use Get-NetForest.
Forests typically have different global catalogs that can help the attacker to get some precarious information about the domain. This can be observed from the following demonstration of extracting all the global catalogs of the current forest using the Get-NetForestCatalog.
Moving on from the catalogs, the attacker can also work on extracting the various domains of the forest the current user is located in. This can be done by running Get-NetForestDomain as shown in the demonstration.
That’s enough Forest, getting back to the users on the local or remote machine the attacker can take advantage of the NetLoggedon module. It should be noted that Administrative Rights are required to use this module. This module executes NetWkstaUserEnum Win32API call to extract the users that are currently logged on. If the attacker is in a bit of a hurry, they can enumerate all the uses that are logged on for all the machines in the domain by using the Get-DomainComputer and then running the Get-NetLoggedon on that data. This can be concatenated using a pipe.
Get-DomainComputer | Get-NetLoggedon |
In this demonstration, however, it is shown how to enumerate users that are loggedon on a particular machine with the help of the ComputerName option and providing the Name.
Get-NetLoggedon -ComputerName DC1 |
Amongst other information, the Domain Policy of a Domain can also reveal some pretty good information. The attacker can use the Get-Domain to extract the policy of the current domain. It reads the default domain policy or the domain controller policy for the current domain or a specified domain/domain controller. To get more focused on a particular domain the Domain option. To extract Domain or Domain Controller using the Source Option or Server option to bind to a particular Active Directory server.
To enumerate Kerberos details, the attacker can try and go after the Kerberos Policy which contains data such as the Max Ticket Age, Max Renew Age, and several Ticket Validation Client. This kind of information can come in handy if the attacker is trying to perform a ticket forging attack or similar attack.
(Get-DomainPolicy)."KerberosPolicy" |
To extract the data regarding the System Access such as the password data that we extracted earlier like Password Age, Password Complexity and Password Length, etc.
(Get-DomainPolicy)."SystemAccess" |
OUs are the smallest unit in the Active Directory system. OU is abbreviated from is Organizational Unit. OUs are containers for users, groups, and computers, and they exist within a domain. OUs are useful when an administrator wants to deploy Group Policy settings to a subset of users, groups, and computers within your domain. OUs also allows Administrators to delegate admin tasks to users/groups without having to make him/her an administrator of the directory.
To Enumerate, run the following command on PowerShell.
It can be observed that there are 4 OUs on the Target Server. Namely, Tech, VPN, Sales, and HR.
During enumeration that the attacker is trying to perform extracting the Group, information is one of the most important that the attacker can enumerate. To get all the groups in the current domain, the attacker can use the Get-NetGroup as demonstrated.
When the attacker requires to extract the groups that consist of the admin keyword as those might be important or might contain some information regarding the administrator as this would give all kinds of administrator groups as demonstrated.
Suppose the attacker wanted to check for the membership of a particular user then they can use the UserName option. This also can be checked as shown in the image below. The attacker extracted the information for the Yashika User.
Get-NetGroup -UserName yashika |
To target a specific domain the attacker can use the Domain option with the domain name provided against as shown in the demonstration.
Get-NetGroup -Domain ignite.local |
Furthermore, if the attacker wanted to extract all the data regarding the groups working on the Domain, they can use the FullData option and extract all the users with their group details. In the demonstration, it can be observed that information enumerated such as there is an Admin in this domain which is a part of Administrator Group and then other User Groups.
There is a Member name Japneet that is a member of the Tech Group and looking for more information about the user groups, it can be observed that the is a user by the name of geet that is a part of the Tech group as well.
Moving on from the user-based Group Enumeration to the Group Based Enumeration by providing the Group Name as shown in the image below.
Get-NetGroup "Domain Admins" |
The attacker can also use multiple options to target a particular Group and enumerate all data about that group as shown in the demonstration.
Get-NetGroup "Domain Admins" -FullData |
There are more possible solutions for the attacker to streamline their enumeration process by providing a bunch of options and parameters to target the exact information. This includes a particular Group Name option and a Domain option.
Get-NetGroup -GroupName *admin* -Domain ignite.local |
In the enumeration, if the attacker gets to a stage where they have successfully enumerated the group names then they can use that in collaboration with the Get-NetGroupMember to extract the members of that group. In the demonstration, we extracted the members of the group Domain Admins.
Get-NetGroupMember -GroupName "Domain Admins" |
As discussed earlier Get-NetGroupMember also supports some options to run along such as the Recurse. It helps the attacker extracts significant amounts of data about all the users of the group they provided. As it can be observed from the screenshots of running Get-NetGroupMember with and without Recurse there is some significant difference between them both.
Get-NetGroupMember -GroupName "Administrators" -Recurse |
Group Policy is very interesting to figure out how the Domain is set up and what set of rules and policies are designed by the Administrator to govern on the Domain. This can be enumerated using the Get-NetGPO. It will extract all the information regarding Group Policies that are configured on the Target System.
As it can be observed from the previous iteration of running the Get-NetGPO, the amount of information is overwhelming. Hence to get a clean and easy-to-understand output selection can be used to get those specific names of the policies.
Get-NetGPO | select displayname |
Getting the GPO location is a good way to map the abilities of a specific user. It takes the username that is provided to it and checks for the permissions for that users. This means that it will return the locations that are accessible for that user. In this demonstration, we use the Yashika user and we choose the verbose option as well to elaborate the result to get the most out of it.
Find-GPOLocation -UserName yashika -verbose |
Invoke-EnumerateLocalAdmin does exactly what the names say. It searched for the Local Administrators for the domain. In our demonstration, we see that we have extracted the Administrator, Enterprise Admins and Domain Admins for our domain ignite. local.
Invoke-EnumerateLocalAdmin |
Enumerating the running process is one of the most things that the attacker should. It can tell so much about the target machine. It can extract information about any services that might be vulnerable. It can tell if any process is running with elevated privileges. It also tells the Process ID of the process so if the attacker has access to that process, they can tinker around with it such as stopping or restarting such process.
Any inexperienced attacker can tell that why is there a need for enumerating the shares when that can be done externally using the SMB enumeration. But an experienced attacker will know that some shares are not visible for all. It can be configured as to if that particular share is visible and accessible to all or some specific user. Hence, to enumerate the shares in a domain use Invoke-ShareFinder.
Searching on the machine that the attacker has an initial foothold is not that difficult task. But to search a specific file across the network in the domain can be done using the Invoke FileFinder. It will search for sensitive files such as the Credentials files and other files that can lead to a serious compromise.
ACL or Access Control Lists can be scanned on a domain that will return the weak permissions on the files. Bear in mind that Domain Permission can be a bit challenging to wrap your head around and the permission that you might find using Invoke-ACLScanner can be difficult to exploit. However, this does not mean that any attacker should not check for those. In simpler terms, Invoke-ACLScanner finds the permissions that the users and group have which are possible subject to exploitation. It determines this by separating the default permission and showing the list of permissions that do not default or new defined by the Administrator.
Invoke-ACLScanner -ResolveGUIDs |
Find-LocalAdminAccess also is pretty self-defined. It enumerated for machines on the local domain that have the users who have the local administrator access. It checks if the user has local administrator access using Test-AdminAccess. Then it checks for the Credential option. If passed, then it uses Invoke-UserImpersonation to impersonate the specified user before enumeration.
At last, it’s time to shine some light on the Sessions that are generated inside a Domain. This can be enumerated with the help of the Get-NetSession tool. Upon running this the attacker can extract the session information for the local or a remote machine. This function executes the NetSessionEnum Win32API call for extracting the session information. It can be used bare as demonstrated or it can be used with a ComputerName Option to target a specific host.
Active Directory is extensive and can be confusing for novice security professionals. We provide this detailed resource so that you can enumerate your Active Directory Deployment and understand the information that an attacker can extract. It will also help our Blue Teamers to understand how this kind of information can be extracted and what kind of alerts they need to set up to restrict the attacker.
Author: Pavandeep Singh is a Technical Writer, Researcher, and Penetration Tester. Can be Contacted on Twitter and LinkedIn