Account lockouts. I wont go into the pros and cons of setting this option
So this is an entry based on a recent case I debugged but the problem wasn’t a bug. There was a case open with PSS from a large government contractor. The case had to do with a single user who kept having their account locked out.
They had gone to great lengths to determine where the account lockout was coming from. The case was open in May and it was Sept mind you, and it appeared to be coming from the domain controller itself (based on the netlogon log) . One of the first things PSS will do is enable netlogon logging via the 2080ffff flags per
06/23 15:44:27 [LOGON] SamLogon: Network logon of DOMAIN\Baduser from DC01 Returns 0xC000006A
The 0xC000006A indicates bad password attempt and 0xC0000234 would indicate an attempt on a locked account.
So the assumption here is that a process on the DC itself may be attempting to logon via a bad password. Tracking the netlogon logs and parsing for this user led to an abnormal pattern with no rhyme or reason to it – not at certain times or a regular pattern like some automated malware trying to attack this user. Almost like a real person ( it would stop on weekends and such). They asked the user if he had any hints as to what may be calling the bogus password but he could not recall.
After taking some drastic measures, like deleting the users account and creating a new one, they approached me for ideas. They had eventually implemented a script to unlock this one specific user every so often, but still wanted root cause. Network traces had not revealed anything obvious ( but since it was a very busy DC these were very very large traces and something may have been missed).
I threw out ideas like alockout.dll and windows logon monitor ( which is a PSS distributed tool for account lockouts) and these were tried but did not log any events when the user was locked.
In the end – a live debug determined that the user in question had setup an application to do a simple ldap bind ( over ssl ) with the users DN and a bad password.
There is a function which basically says "hey was this guy locked out?" and returns true if he was locked.
The calling function looked something like:
546298f3 8d4d8c lea ecx,[ebp-0x74]
546298f6 51 push ecx
546298f7 50 push eax
546298f8 ff750c push dword ptr [ebp+0xc]
546298fb e888170200 call mod!AmILocked
54629900 84c0 test al,al
so I set a conditional breakpoint like just so we don’t catch all the bad passwords – just the actual lockout events:
bp 54629900 "j @eax = 0x1 '';'gc'"
So once that was set I told them to call me when it breaks in – sure enough it did and I got about 4 minutes in on the real debug and the ASR ( Automatic System Recovery ) kicked in and rebooted the machine. Doh! Just a tip - before a kernel debug disable this in the BIOS or you lose all the setup etc... you did to get to a good point in a debug 😉
So we tried again the next day – hit it again (luckily) and it was the same user. I could see he was using the NTLM SSP msv1_0 , and tracked the call back to an LDAP connection which included the IP of where it was coming from. Once they had the information ( username, bad password, and the machine where it originated from ) they confronted the user and he recalled where and when he had set this machine up for a simple ldap bind via some firewall settings and had never deleted the static setting.
I am pretty sure that alockout.dll shims certain authN calls like LogonUser etc.. and the windows logon monitor inserts a new dummy SSP to catch calls - for some reason ( not sure why )these were not catching the root cause here.. perhaps error on the end user when setting them up?
How could this have been made easier? Not sure right now --- any thoughts from the readers?
Thought I would add some value to this post 🙂
The person who was being locked out did not know which machine the lockout was coming from. It may have jogged his memory and we could have tracked it down faster.
Usually the netlogon logs will show this. Most times this is only half the battle though, because you still dont know which process, service etc.. is actually sending the bad creds. In this case, due to the debug , I could tell them the username, source machine, and the password being used. As soon as the end user found out the source machine and password - he remembered where he had set this.
Anyway -- in this situation we simply show the DC as the source:
user = ed
domain = crisco1
DC = 2k3entspat
Netlogon log shows:
12/24 17:15:46 [LOGON] CRISCO1: SamLogon: Network logon of CRISCO1\ed from 2K3ENTSPAT Entered
12/24 17:15:46 [LOGON] CRISCO1: SamLogon: Network logon of CRISCO1\ed from 2K3ENTSPAT Returns 0xC000006A
The ldap call somes into LSA and ends up calling into LogonUserW (advapi32) which then calls an LPC to itself , goes through netlogon and is eventually authenticated.
When it flows through netlogon it says "Hey, this call came from me! I'd better log that."
Ahh but it gets better. In Windows Server 2003, we will log an event:
Event Type: Failure Audit
Event Source: Security
Event Category: Logon/Logoff
Event ID: 529
Time: 5:15:46 PM
User: NT AUTHORITY\SYSTEM
Reason: Unknown user name or bad password
User Name: ed
Logon Type: 3
Logon Process: Advapi
Authentication Package: Negotiate
Workstation Name: 2K3ENTSPAT
Caller User Name: 2K3ENTSPAT$
Caller Domain: CRISCO1
Caller Logon ID: (0x0,0x3E7)
Caller Process ID: 436
Transited Services: -
Source Network Address: 126.96.36.199 --- this is the IP of the machine I used to do the LDAP bind from ( bad creds used )
Source Port: 1586
But ....they were on Win2k