Abusing empty passwords during your next red teaming engagement
Abusing empty passwords during your next red teaming engagement
Blog by: Tijme Gommers & Jules Adriaens
Introduction
In this blog, we focus on a well-known attack vector: authentication, and specifically passwords. For many red team operators, as well as cybercriminals, weak passwords are an easy vector for initial access to an organisation. Even with a password policy, there is still the possibility of weak passwords being assigned to user accounts in the environment. One such vulnerable type of “password”, which has often been neglected to date, is an empty password. That's right, an account that is basically accessible to anyone. It can inadvertently give a threat actor the ability to move horizontally through the Active Directory environment, or worse, to the organisation's crown jewels.
Background story
During one of our adversary simulations, we exfiltrated the NTDS file on one of the domain controllers, as our final objective was to perform password usage analysis on all domain user accounts. During the analysis of the NT hashes in this adversary simulation, it turned out that there were more than 100 users who used the same NT hash: “31D6CFE0D16AE931B73C59D7E0C089C0”.
This string is the well-known NT hash for an empty password. Usually, this concerns disabled accounts, such as the Guest account. As red team operators, we never looked much further into it, because with disabled accounts you can't progress any further. Or can you?
On a recent assignment, we encountered a mature environment: full segmentation and filtering, fully patched, in short: no low-hanging fruit. My colleague looks at me and casually says: “What if there are empty passwords set on active accounts”? At first, we didn't take this idea seriously. But a few commands later we had a PowerShell prompt open as domain admin. How did this even happen!?
Why do accounts with empty passwords exist?
Let's investigate why empty passwords (may) exist in Active Directory. And how do you configure them? Usually, it is not possible to configure an empty password for an account. If the default password policy is active, a minimum number of 7 characters, as well as password complexity are required for every domain user account. Configuring an empty password would result in the following error message:
However, there are two ways (known to us) to configure an empty password. One of them is a very weak password policy. It is possible to change the default password policy via Group Policy or via PowerShell with the ActiveDirectory module, specifically setting the ‘MinPasswordLength’ to 0 and ‘ComplexityEnabled’ to $False. After a reboot, it is possible to set an empty password for an account:
The other situation in which empty passwords are allowed is when the domain user has the flag " PASSWD_NOTREQD " set to “True” in the "useraccountcontrol" attribute.
Why would anyone set an empty password for a user account? A Google search shows that there are several vague reasons why empty passwords are configured. According to Microsoft[1], the issue most frequently arises due to identity & access management (IAM) systems that create accounts with the flag set, set a password but fail the last step of removing the flag. After many adversary simulations, we can conclude that this happens from time to time.
How to find accounts with empty passwords
There are several ways to enumerate accounts that are allowed to have an empty password. Assuming there is a strong password policy in place, there is only one way to have empty passwords; the PASSWD_NOTREQD flag, a flag which we can query users on. For example, via PowerShell, WMI, or in BloodHound. Below are some examples of search queries for popular tooling.
# ActiveDirectory module Get-ADUser -Filter {PasswordNotRequired -eq $true -and Enabled -eq $true} | Select SamAccountName # WMI Get-WmiObject -Query "SELECT * FROM Win32_UserAccount WHERE PasswordRequired=False AND Disabled=False" | select Name # Ldapsearch ldapsearch (&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) cn # BloodHound MATCH (n:User {enabled: True, passwordnotreqd: True}) RETURN n
Follow-up
Not all existing tooling appears to be adapted for the testing of empty passwords. Although, to be fair, some tooling has been designed to allow for the spraying of empty passwords. For example, Rubeus’ spray option makes this possible by using double quotes (“”). Also, the StandIn toolkit included this as an explicit feature (https://github.com/FuzzySecurity/StandIn#passwd_notreqd). However, for the tools that do not yet support this, we have submitted pull-requests:
- We made a pull-request for Spray-AD: https://github.com/outflanknl/Spray-AD/pull/2
- As well as for SharpHose: https://github.com/ustayready/SharpHose/pull/7
- As well as for Kerbrute: https://github.com/ropnop/gokrb5/pull/1
- For DomainPasswordSpray we saw that a pull-request had already been made: https://github.com/dafthack/DomainPasswordSpray/pull/29
BloodHound
Maybe it's a bit ambitious, but it may be possible to extend the functionality of BloodHound. For example, it can be checked whether the attributes ‘PASSWD_NOTREQD’ and ‘ms-DS-User-Account-Disabled' both exist on an object. If so, this provides a potential attack surface, where attack paths can be accessed without having to compromise a single password. Note that the PASSWD_NOTREQD flag does not necessarily mean that no password has been set; only that this is possible to do.
Mitigation
For system administrators it is easy to retrieve the accounts with an empty password via PowerShell with the ActiveDirectory module. In the query below, a filter has been added to include only enabled accounts:
Get-ADUser -Filter {PasswordNotRequired -eq $true -and Enabled -eq $true} | Select SamAccountName
It is recommended to carry out regular audits on enabled accounts that have this attribute configured. Although these accounts may be set up for a legitimate purpose (e.g. debugging), in practice it often turns out that people forget to set a password.
Conclusion
Although passwords are a well-known attack vector, the possibility of empty passwords seems to have had little attention in the offensive arsenal. Through this blog we have shown that empty passwords in an environment are particularly dangerous, because they allow threat actors easy access to an organisation’s resources.