In this post we will use different tools to analyze an Active Directory environment, both from Linux and Windows.
This post is useful for both Pentesters and Blue Team members, as it identifies possible attack vectors and insecure configurations on a domain. Both to exploit from the attacker’s side, and to correct and monitor from Blue Team’s side.
We will use the previously deployed Active Directory to practice, the tools we will use are:
Windows:
- Powerview – https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1 (Archived, still useful however).
- RSAT Active Directory DLL – https://github.com/samratashok/ADModule.git (DLL signed by Microsoft to manage an Active Directory environment from Powershell)
- SharpHound – https://github.com/BloodHoundAD/BloodHound/tree/master/Collectors (Bloodhound ingestor tool, automates the process of enumerating the internal domain)
Linux:
- Ldapdomaindump – https://github.com/dirkjanm/ldapdomaindump.git (Previously used tool, Active Directory enumeration tool)
- bloodhound-python – https://github.com/fox-it/BloodHound.py.git (python based bloodhound ingestor)
For both cases, it’s necessary to have Bloodhound installed correctly, including the Neo4j database.
NEO4J/BLOODHOUND installation
Windows installation documentation:
https://bloodhound.readthedocs.io/en/latest/installation/windows.html
Linux installation documentation:
https://bloodhound.readthedocs.io/en/latest/installation/linux.html
Following the guides, we can start recollecting information with the ingestors and analyzing it through Bloodhound.
AD CONFIGURATION TO EXPLORE MULTIPLE ATTACK VECTORS THROUGH BLOODHOUND
We’re going to add a couple of insecure configurations through the ADSI Edit option in the DC.
The first time we start the console, we need to connect to our AD by clicking on Actions > Connect To.
We can leave the default values for this exercise.
Once the connection has been established, we expand our main tree until we identify the CN=Users folder, where we’ll see our domain groups and users.
Here we can modify the DACL properties for any domain object, in this scenario, we’ll give the hank.scorpio user privileges over the admin user.
Right click on the admin user object and we access to Properties.
We move to the Security tab and we click on Add.
In the new window, we write the desired username and click on Check Names so the object gets searched for within our Forest.
We click OK and then define which permissions we want to give the hank.scorpio over the admin user, for this post, we’re going to assign the Change Password privilege.
We apply the changes and switch to another user.
Repeating previous steps, we’re going to give the user Service_BD privileges over the Administrators group.
To identify the group, we move into the CN=Builtin folder on the main tree.
Modifying the group, we add the Service_BD user to the list.
We assign the Write privilege over the Administrators group.
Then, we can click on Update Schema Now to make sure the changes were applied.
With these configurations, we’ll proceed to extract information regarding possible attack paths using SharpHound/bloodhound-python.
SHARPHOUND EXECUTION
Sharphound comes both in exe and PS1, in this case, we’re going to use the Windows binary.
We’re going to use the TECNOLOGIA01 host to execute the ingestor since it’s a domain joined machine.
For simplicity sake, we’ll disable the antivirus to execute the binary.
Since we’re logged in as a domain user, the CMD window runs under the domain user’s context, so we don’t need to specify credentials unless we want to use a different user to run the enumeration tasks. (We’re going to explore options on how to execute the tool using a non domain joined machine)
We execute Sharphound with the flag “-c all” so it obtains as much information as possible (very noisy).
Once the extraction finishes, a compressed file is generated, which we can move into the host that has Bloodhound and Neo4j installed.
Using bloodhound-python from Linux is pretty similar, the only notable difference is that we would need to specify the domain controller and the credentials, or establish the domain controller as a DNS server on our Linux host.
We can edit the /etc/resolv.conf file to manually add a DNS server.
Executing bloodhound-python with the mentioned parameters, we start the enumeration process.
Once it finishes, we get 4 json files ready to be imported into Bloodhound.
We can drag and drop the files into the Bloodhound main window, where the data will start to get uploaded and analyzed.
Once it’s done, we can use pre-existing queries to find possible attack paths.
Find all Domain Admins.
It identifies members of the Domain Admins group.
There, we can observe multiple domain admins, including a machine account, indicating that if we get to compromise the TECNOLOGIA01 host and obtain the machine account NTLM hash, we could perform a DCSync attack to compromise the domain.
But this is a group membership problem, since we’re trying to explore ACL attack paths, we can use a different pre-built query in Bloodhound, Find Shortest Paths to Domain Admins, where we’ll see the following result.
Analyzing all of this possible paths can be overwhelming, but by doing so, we can identify if there’s a direct path to compromise a Domain Admin.
We observe that the PWNED, ADMIN, JSEC, ADMINISTRATOR users and the TECNOLOGIA01 host belong to the Domain Admins group, however, if we focus on the upper part, we can identify a different path.
We see that SERVICE_BD has a GenericWrite link pointing to the ADMINISTRATORS group, meaning that by compromising this user, we can modify this group’s properties.
Simplifying some Active Directory concepts, we can consider the existing users, groups, machines, group policies, organizational units and more as Objects, each with specific and different properties according to the type of object (a user object will have different properties than a group object), the identified link can be interpreted as a special privilege the Service_BD has over the ADMINISTRATORS group, even when the user is not a member of it, so we can use this privilege to add any domain user into this group.
The pre-build query identified this path, but I always recommend to find valuable users and explore their Explicit Object Controllers, since we can identify other possible attack paths.
Going back to Bloodhound, we explore all of the high privilege users, eventually reaching the admin user where we expand the Explicit Object Controllers property.
Here we can find a special privilege granted to the hank.scorpio user that allows it to forcefully reset the admin user password.
This is how we can identify a previously unknown attack path, which is why it’s recommended to carefully analyze Bloodhound results.
Now we can proceed with the exploitation.
ACL EXPLOITATION
We can use Powerview to exploit these misconfigurations, however, the tool is widely known and detected by most Antivirus solutions. We could disable the antivirus to proceed with the exploitation, but personally, I like to use the Microsoft signed Active Directory management DLL over Powerview to maintain a certain level of stealthiness, and since a common scenario during these types of engagements involves access to domain joined hosts where we can’t simply disable the antivirus, knowing how to use these legitimate tools can be advantageful.
We can download the DLL into the TECNOLOGIA01 host and import it through Powershell.
Sometimes we can get an error, but most of the time just importing again will work. We can proceed with the exploitation.
Service_BD user account with writing privilege over Administrators group.
For this scenario, we’re going to create a new low privileged user.
To list the available commands of the imported module, we can use the Get-Command cmdlet.
To obtain information about the target group, we use the Get-ADGroupMember cmdlet.
We can see we have 6 members, legendario.esquilax and Service_BD are not.
To keep things simple, we’re going to use the password for the Service_BD user we found before.
Firstly, we define a credential type object to execute commands under the Service_BD user context, without the credential object, we would be running commands as cosme.fulanito user context, which is not useful given that Service_BD has the privileges we’ll exploit.
The $pass object stores the known password “P4ssw0rd123” as a secure string, which is required to use credential objects.
The $cred object will store logon information for the account we define, in this case, Service_BD referencing the $pass object as its password, allowing us to use the object to impersonate the respective user.
To exploit the ACL misconfiguration, we’ll use the Add-ADGroupMember cmdlet.
If we execute the command without parameters we’ll be prompted for the required information, however, we can also use a one-liner to execute the desired task.
The first line is adding the legendario.esquilax, defined by the parameter Members, into the Administrators group, defined by the Identity parameter, using the created credential object, defined by the parameter Credential.
The second line is querying the group members again, this time showing the user we just added to the group, confirming the privilege abuse worked.
We can easily confirm the validity of the user from our Kali host, successfully executing a DCSync and compromising the domain.
HANK.SCORPIO WITH PASSWORD RESET PRIVILEGES OVER THE ADMIN USER
The second attack path involves the hank.scorpio user, given that it can forcefully change the admin user’s password. We’ll be using the Active Directory signed DLL for this task.
Once again, we create the $pass and $cred objects in order to impersonate the hank.scorpio user.
Within our Kali host, we’ll try to login into the DC with the admin user and the password Test1234!!, the attempt fails.
To change the user’s password, we’ll use the Set-ADAccountPassword cmdlet, by defining a second secure string object named $newpass and the desired value.
The second line is the password change command, defining the target account through the Identity parameter, the user context through the Credential parameter and the new password, defined by the NewPassword parameter.
Once we execute the command, we don’t get any errors or output, however, if we try to authenticate to the domain once again with the set password, we obtain administrative access.
This is the first part of misconfigured or permissive ACL privileges, we’ll delve further on future posts (Attacks such as Resource Based Constrained Delegation and arbitrary SPN tickets registration for Kerberoasting attacks).
Also, we’re going to use a non-domain joined host to execute this attacks, through Powershell objects and running proceses under a different user context through runas.
For Blue Team members, it’s recommended to search for this type of misconfigurations in your internal infrastructure, analyzing Bloodhound in depth, mostly because these type of attack paths are slightly more complicated to exploit, but are also stealthier.