Consider this situation and how you would respond: you come back from lunch to find thousands of your Active Directory user accounts locked because of bad login attempts. I recently had a tool run on my AD domain that had the potential to do just that, fortunately it only caused a single failed attempt for each account and did not lock them. But what if it had? It got me thinking about what I would do. The first thing I would have tried was a bulk selection of accounts in Active Directory Users & Computers, and then look for the option to mass-unlock them. Unfortunately that option isn’t there. You can bulk select accounts and Enable/Disable them, but there are no options for mass unlocking. Similarly, it appears the dsmod command line utility doesn’t support this option.
Unable to find a solution, I pieced together a script that will parse through AD accounts, and unlock any locked accounts that it finds. I also added a read only option that will just report on locked accounts. Thanks to those at the Minasi Forum for help in getting me started on this. You can get the script here. If you download it, replace the .doc extension with .vbs to run it. Keep in mind that I’m not a coder, so it may be messy, but it is tested and effective in a pinch.
In the process of working on all of this, it got me thinking about how easy it would be to mount this type of attack against an AD infrastructure, and what could be done to minimize the risks. As I mentioned above, this problem was the result of a legitimate tool that was incorrectly run. But what if someone wanted to deliberately lock all of your accounts? Imagine the damage this 12-line script would do:
On Error Resume Next
Set objFSO = CreateObject("Scripting.FileSystemObject")
acctsFile = "acct_list.txt"
Set objApp = CreateObject("WScript.Shell")
Set objNet = CreateObject("WScript.Network")
Set objFile = objFSO.OpenTextFile(acctsFile, 1)
Do While Not objFile.AtEndOfStream
acct = objFile.ReadLine
For count=0 To 2
objNet.MapNetworkDrive "", "\\server-dc01\c$", "false", acct, "badPasswd"
Next
Loop
That took me about half an hour to come up with, and it just loops through a text file listing of account names, attempting 3 logon attempts with each account, using a bad password. Depending on your account lockout policies, that would have just locked any accounts in the text file. This is basically a form of a denial of service attack. The fact that AD locks accounts after a number of incorrect login attempts is a desired behavior, it keeps resources safe from dictionary attacks and password guessing. But for someone who’s goal is a DoS attack, it makes things easy. All they need is your account names. If it’s an internal user, for the most part, you’re out of luck. They’re going to have the rights to read account names, all they need is Active Directory Users & Computers (downloaded from Microsoft) or any other number of LDAP query utilities. Using logfiles, you’re going to be able to find out who the culprit is. So you just have to hope the risk and repercussions outweigh the reward for any disgruntled employees. That statement holds true for most insider threats, whether related to technology or not.
Things are a little bit harder for an external attacker. It won’t shouldn’t be quite as easy for them to get a list of your account names. Hopefully your public email address format isn’t the same as your AD account format. If it is, you’ve made it a lot easier. Think about other potential areas of account info leakage specific to your environment. Protect your accounts & public AD exposure; 2003 AD in native mode doesn’t allow anonymous account enumeration, but if an attacker can compromise even one account, they can authenticate and enumerate account info. So what if an external attacker does get a list of your account names, the above script shouldn’t work from outside. What could he do? Do you have Outlook web access? Public web sites requiring AD authentication? Simple VPN remote access services? Any other publicly available resources that require AD authentication? It won’t be quite as easy to script those attacks, but it can be done.
So what can be done to minimize the risk? This isn’t a new problem by any means, and the traditional advice remains relevant. Guard your account information; use a different format for public email addresses; disable Guest accounts; don’t use shared accounts that can’t be audited back to a specific person; monitor your logs for suspicious activity; don’t expose unnecessary services, especially to the Internet; and make an effort to follow all other security best practices.
Disclaimer: I considered the decision whether or not to post the script snippet that causes account lockouts in this post, but feel that there was more benefit in doing so than not. If someone was truly intent on doing this type of attack, they would be able to do so without this post. Rather than describing potential risks and what “could” happen, I feel that showing how simple this could be done will be more effective in bringing it to the attention of IT professionals. That being said, don’t run that code in production.
Filed under: Active Directory, Security, Utilities | Tagged: Account Enumeration, Account Unlock, Active Directory, Bulk Account Unlock, Denial of Service, Scripting, Security |
Thanks, Very good article, Including Script.
After renaming the script to VBS, when I run it, I get an error:
Line:1
Char:1
Error: Invalid character
Code: 800a0480
Source: Microsoft VBScript compilation error
Any tricks to getting this to run?
Hi Joe, I think I’ve seen that error before when the script is saved with MS Word or a similar app that puts special hidden characters in the file. Try saving the file using notepad and see if that helps.
Nicely done – your script is keeping our network from sinking at the moment; dozens of accounts being locked repeatedly… indeed if I run your unlock script, I’ll find half a dozen accounts immediately re-locked again.
How the heck do I trace which server all the auth requests are coming from? The Security Event Log is just a sea of noise, and we have dozens of servers …
Hi Gavin, glad the script is of use to you. For researching the source of lockouts, I’ve found that the LockOutStatus tool from Microsoft is great for pinpointing which DC the lockout happened on. From there, you can search that DC’s security logs for the ultimate source. Hope that helps. You can find the lockoutstatus tool here: http://www.microsoft.com/downloads/details.aspx?FamilyID=D1A5ED1D-CD55-4829-A189-99515B0E90F7&displaylang=en
This issue has thankfully now been traced to a remote machine with a virus on a bridged VPN.
I did try Lockoutstatus.exe yesterday as part of the troubleshooting but found that it misreported thus adding confusion. We have 3 DCs, of which two were marked ‘Unlock (Auto Unlock)’ despite the fact that the account in question was definitely locked.
My stumbing was in the Windows security log – I was looking for one of the columns to show the locked username. My bad – in the end all I had to do was look in a couple of the ‘Failed Audit’ entries and I was presented with the most-recently locked username along with the IP of the workstation. I then firewalled it from everything but the DHCP server (fortunately DHCP is not run by the DCs!) so it would stick on the same IP.
I’m looking forward to slinging all hell at the sysadmins of that remote site on Monday since their incompetence damaged my Friday night. :)
Is this solution possible if I am log-in using the guest account? because our active directory administrator account was also locked.
Hi Joseph. This solution is still possible because the builtin Active Directory administrator account can never really be locked out. As long as you know the password, it is possible to log on to a domain controller with that account. This is one good reason to not disable that account, although renaming it and securing it with a strong password are a good idea. Hope that helps.
Just had to say thanks on this. Blew up my certs on my domain controllers and locked out everyone (21,000 accounts). fixed the cert and a frantically googled a way to mass unlock accounts. I was in the clear in 5 minutes. IOU one big beer.
Hey,
1st Thanks for th post and the script.
Problem,
when i ran this script it started unlocking all/every account it finds, That is something That I did not want to do.
I want to Only Unlock accounts first that gets locked in today and most important thing about those is I want to only Unlock specific account For Example
UNLOCK ALL Accounts WHERE Account_Name LIKE ‘DELL%’
Mean unlock all account where account name starts with ‘DELL’
I’ll greatly appreciate any help on this.
Thanks.
I have found the argument, below is how i restrict/filter the search.
ActFilter = “(&(&(ObjectCategory=person)(ObjectClass=user) (UserPrincipalName=MyAccounts*)))”
Thanks
AAA
Is this script run on the DC/
Thank you very much… it save me a lot..
Hell yeah, this post is really what I am looking for. I am really lucky today. Thank you admin!
Hi all,
Just a few questions i need answering:
Does this script need to be run from the DC?
Does the script need altering? eg. domain name needs entering.
Thanks
Ben
No, it does not need to be run from a DC, and no, it needs no modification.
@Ben/Clay:
The script currently only scans the domain of the account that runs it.
If you want to run this script against any other domain than the account you’re using to run it, it will require modification.
i ran the script, but double checking the same accounts that was reported to be unlocked, using the LockOutStatus tool, it still shows the same account as locked. any ideas what’s going on?
Are you using an account with permissions to unlock? There is no error checking in the unlock portion of the script, so for example if you run the script with an account that does not have the unlock account permissions, it will report the accounts as unlocked, even when they aren’t.
define “permissions to unlock”? because using the LockOutStatus tool or active directory, we are able to unlock those accounts which are still locked, even though reported by the scripted to have been unlocked.
I have a question: format of the file “acct_list.txt”
Thanks
Thanks for the great script.
I’ve been using it for a few months now whenever I need a good sledgehammer.
My question is this: How would you modify this script so that I could set specific user to look for, or even how could I make it only look for accounts in a specific OU?
Thanks again!
This was huge for us… This excerpt for the following webpage is the powershell code that helped (obviously you have to modify it to suit your needs):
.
IMPORT-MODULE ActiveDirectory
SEARCH-ADACCOUNT –lockedout
Now, we can just quickly UNLOCK all the accounts by piping the results into UNLOCK-ADACCOUNT.
SEARCH-ADACCOUNT –lockedout | UNLOCK-ADACCOUNT
@Tbailey, Optionally, search for & unlock accounts in a specific OU:
SEARCH-ADACCOUNT –searchbase ‘OU=Division31,OU=Locations,DC=Police,DC=Redmond,DC=Local’ –lockedout | UNLOCK-ADACCOUNT
Full article located here: http://blogs.technet.com/b/heyscriptingguy/archive/2011/09/11/batchman-uses-powershell-to-identify-and-unlock-user-accounts.aspx