Clean Your Active Directory
You have already learned that there can be thousands of objects in an Active Directory—and millions of permissions between these objects. Managing all these elements can be very challenging. What’s more, an information system tends to become more complex over time. New users, groups, or computers get added, but old ones are rarely deleted.
So, it’s time to give your Active Directory a spring clean!
Initially, it may be useful to make a list of objects that have not been used for a long time. It’s very likely that these objects are no longer in use and could be deleted. This will reduce the attack surface available to an attacker.
You can use the results generated by BloodHound to identify these accounts. In fact, the tool has already recorded all the objects of interest in a Neo4J database. You can write queries for this database to extract the information that interests you. For example, you could use the following query to find out which users or computers in your Active Directory have not logged in for more than a year:
MATCH (n {enabled:true}) WHERE ((n:User) OR (n:Computer)) AND n.lastlogontimestamp < (datetime().epochseconds - (365 * 86400)) AND n.lastlogon < (datetime().epochseconds - (365 * 86400)) and NOT (n.lastlogontimestamp IN [-1.0, 0.0] AND n.lastlogon IN [-1.0, 0.0]) RETURN DISTINCT n.name AS Name, CASE WHEN n.lastlogontimestamp > n.lastlogon THEN DATETIME({epochseconds: ToInteger(n.lastlogontimestamp)}) ELSE DATETIME({epochseconds: ToInteger(n.lastlogon)}) END AS LastUsed
You can also use BloodHound to identify and remove permissions that allow you to take control of the domain. For example, you can use the query to display the shortest paths to compromise the domain, and based on the results, you will see whether or not you had anticipated these paths. You must delete all permissions that are deemed redundant.
The same applies to service accounts. You seen that Kerberoasting is a very powerful attack technique that allows you to take control of accounts that may have elevated privileges. It is therefore important to identify these accounts and replace them with either machine accounts or gMSAs (Group Managed Service Accounts).
You previously identified these accounts using Impacket’s GetUsersSPN.py utility. You can also use the following Neo4J database query to extract them:
MATCH (n:User {enabled:true,hasspn:true}) RETURN DISTINCT n.name AS Name, n.serviceprincipalnames AS SPN
Administration accounts are prime targets for attackers. If they’ve been compromised, it allows attackers to elevate their privileges within the domain and potentially compromise it. This is why you should limit the number of privileged accounts on your domain.
The following Neo4J query allows you to compile a list of all users who are members of privileged groups. Obviously, there are domain administrators and enterprise administrators, but there are also other groups that can perform administrative actions on the domain.
MATCH (u:User)-[:MemberOf*1..]->(g:Group {admincount:true}) RETURN u.name AS Name, COLLECT(g.name) AS Group;
This list should be kept to a strict minimum to further reduce the scope of the attack.
Unconstrained delegation accounts present a particularly high risk because, once they are compromised, attackers can quickly compromise the domain. They should be converted into constrained delegation accounts by specifying the services that require delegation.
Secure Your Passwords
The password policy plays an essential role in the security of an Active Directory environment. You must check that this password policy is properly set up in order to ward off any password spraying attacks. In the first part of this course, you learned how to retrieve this policy using Get-ADDefaultDomainPasswordPolicy.
Make sure to request that passwords be at least 12 characters long and enforce password complexity. The policy should also temporarily lock an account after a certain number of failed login attempts. A common setting is three failed attempts in a 30-minute window before the account is locked for 30 minutes.
You can also conduct regular password audits. This involves extracting user NT hashes from the domain controllers and then attempting to break these hashes over a few hours. Any recovered passwords are considered weak and must be changed. This will allow you to refine your password policy, while simultaneously raising employee awareness of the importance of strong passwords.
Harden the Protocols
Protocol attacks can often be avoided by correctly configuring clients and servers.
Flow signing protects against relay attacks, for example. SMB signing is available on all versions of Windows, but only domain controllers require it by default. Requiring all SMB flows to be signed will protect you from man-in-the-middle attacks, especially when the NTLM relay uses SMB. There is a Microsoft article on this subject. It explains how to configure the signature by editing registry keys or by GPO.
Similarly, LDAP signing can be requested on domain controllers. This can also be configured using GPO.
Regarding NTLM, I briefly mentioned that there were two versions of the protocol: NTLMv1 and NTLMv2. Be aware that the first version is obsolete and not at all secure. It’s important to make sure that version two of the protocol is installed. This is the default version, but for reassurance, you can check this registry key on the domain controllers here:
HKLM\System\CurrentControlSet\Control\Lsa\LmCompatibilityLevel
If the value is 0, 1, or 2, this means that NTLMv1 can be used by connecting to a domain controller, which poses a real risk. The different values for this key are explained in a Microsoft article. It is crucial that this value is set to 3 or more. You can also change this setting by using GPO.
Finally, the NBT-NS and LLMNR protocols are very dangerous if they are enabled. They allow an attacker to take a man-in-the-middle position, making it possible to either relay an authentication or attempt to crack user passwords. Disabling them on workstations will prevent these attacks.
To disable LLMNR, you need to enable the Turn off multicast name resolution parameter, which can be accessed here: Computer Configuration > Administrative Templates > Network > DNS Client
It’s not quite as easy for NBT-NS. There is no GPO that allows you to easily disable this setting. That said, you can call for this script to run when the machines start. It will recover the network interfaces on the workstations and disable NetBIOS:
# Recover the network cards
$regkey = "HKLM:SYSTEM\CurrentControlSet\services\NetBT\Parameters\Interfaces"
# Disable NetBIOS on each card
Get-ChildItem $regkey |foreach { Set-ItemProperty -Path "$regkey\$($_.pschildname)" -Name NetbiosOptions -Value 2 -Verbose}
Let’s Recap!
To protect your Active Directory environment correctly, there are a number of points to consider:
Clean up your environment by removing unused objects and permissions to limit the attack surface for a threat actor.
Secure your passwords by imposing a strong password policy.
Harden the standard protocols to limit the attacks that exploit them, most importantly, by implementing flow signing and disabling obsolete protocols such as LLMNR and NBT-NS.
Other areas can be addressed, such as implementing an administration template using silo administration. That’s what we’ll be looking at in the next chapter.