Account Lockout mit Docker

Heute stand meiner meiner Entwickler bei mir und sucht nach einer Lösung, weil sein Konto immer wieder gesperrt wird. Wir haben zwar eine Policy, dass gesperrte Konten nach wenigen Minuten alleine wieder entsperrt werden aber störend ist das schon. Also habe ich gesucht.

Siehe dazu auch DoS mit Account Lockout und Account Lockout durch AzureVM

Gruppenrichtlinien und Auditing in der Domain

Natürlich habe ich auf meinen Servern das Auditing per Gruppenrichtlinie aktiviert. Am besten erfolgt das direkt auf der Domäne, so dass auch alle Clients erwischt werden.

Achten Sie darauf dass speziell auf den Domain Controllern keine andere Policy ihre Einstellung überschreibt. Die verschiedenen Einstellungen steuern unterschiedliche Anmeldeprozesse. Beachten Sie auch, dass einige "Probleme" dennoch als "Audit Success" geloggt werden können.

  • EventID 4625 auf dem Client, auf dem die Anmeldung schief gelaufen ist
  • EventID 4771 oder 4776: Auf dem DomainController
    Computer Configuration/Policies/WindowsSettings/Security Settings/Advanced Audit Policy Configuration/AuditPolicies/Audit Kerberos Authentication service>Enable Audit for failure
  • EventID 4776: Anscheinend bei Anmeldungen per RDP
    Computer Configuration/Policies/WindowsSettings/Security Settings/Advanced Audit Policy Configuration/AuditPolicies/Audit Credential Validation set to Failures
  • EventID 4625 auf DC, wenn der Client dort dort erst ein TGT oder Ticket besorgen muss.

Über eine zweite Richtlinie wird die Lockout-Policy eingestellt:

Das sieht so aus gut aus. Ein nach fünf Fehlversuchen gesperrtes Konto wird nach 1 Minute wieder freigegeben. Das begrenzt die maximalen "Versucht pro Zeit" auf 5 fehlerhafte Anmeldungen pro Minute. Genug um Brute Force Angriffe zu verhindern und zusammen mit der ADFS Extranet Lockout zu harmonieren.

Suchen im Eventlog des PDC-Emulators

Wenn Sie die verschiedenen Blogs und Microsoft Anleitungen lesen, dann sollte mit einer passend konfigurierten Überwachung im Eventlog die relevanten Einträge finden. Windows 2003 und früher hat dazu noch eine ganze Menge an Eventlog (529, 644 675, 676, 681) geschrieben. Bei Windows 2008 und höher ist es nur noch ein Event 4740, die im Security Eventlog erscheinen.

Per PowerShell können Sie sehr einfach auch diese Einträge finden:

get-winevent -FilterHashTable @{LogName = "Security"; ID = 4740; Providername="Microsoft-Windows-Security-Auditing"}

Hier ein Beispiel:

Log Name:      Security
Source:        Microsoft-Windows-Security-Auditing
Date:          23.01.2019 13:03:22
Event ID:      4740
Task Category: User Account Management
Level:         Information
Keywords:      Audit Success
User:          N/A
Computer:      DC1.uclabor.de
Description:
A user account was locked out.

Subject:
        Security ID:            SYSTEM
        Account Name:           DC1$
        Account Domain:         UCLABOR
        Logon ID:               0x3E7

Account That Was Locked Out:
        Security ID:            uclabor\user1
        Account Name:           user1

Additional Information:
        Caller Computer Name:	
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="Microsoft-Windows-Security-Auditing" Guid="{54849625-5478-4994-A5BA-3E3B0328C30D}" />
    <EventID>4740</EventID>
    <Version>0</Version>
    <Level>0</Level>
    <Task>13824</Task>
    <Opcode>0</Opcode>
    <Keywords>0x8020000000000000</Keywords>
    <TimeCreated SystemTime="2019-01-23T12:03:22.871287200Z" />
    <EventRecordID>2372356</EventRecordID>
    <Correlation />
    <Execution ProcessID="524" ThreadID="4544" />
    <Channel>Security</Channel>
    <Computer>d12.uclabor.de</Computer>
    <Security />
  </System>
  <EventData>
    <Data Name="TargetUserName">user1</Data>
    <Data Name="TargetDomainName">
    </Data>
    <Data Name="TargetSid">S-1-5-21-11949449-30417519-71842111-1234</Data>
    <Data Name="SubjectUserSid">S-1-5-18</Data>
    <Data Name="SubjectUserName">DC1$</Data>
    <Data Name="SubjectDomainName">UCLABOR</Data>
    <Data Name="SubjectLogonId">0x3e7</Data>
  </EventData>
</Event>

Das ist ein Eventlog auf meinem PDC Emulator. Leider sehe ich da nicht wirklich den Client, auf dem die Anmeldung versucht wurde. Das hilft so nicht weiter. Obwohl es selbst auch Microsoft Blogs anders steht:

All failed logon attempts get forwarded to the PDC Emulator (PDC) in the domain. Like I said earlier, the events that get logged depend on how auditing is configured. What is consistent is the event number that gets logged when the account is locked out. In an environment with domain controllers running Windows Server 2008 or later, when an account is locked out, a 4740 event is logged in the Security log on the PDC of your domain. With the 4740 event, the source of the failed logon attempt is documented
Quelle: https://blogs.technet.microsoft.com/heyscriptingguy/2012/12/27/use-powershell-to-find-the-location-of-a-locked-out-user/

Netlogon Debugging auf dem PDC-Emulator

Natürlich habe ich im Internet auch nach Hinweisen gesucht und bin auf das NETLOGON-Debugg gestoßen

Also Domänenadministrator habe ich das also auf dem PDCEmulator gestartet und mit PowerShell das Ende der "netlogon.log" verfolgt

# Debugging einschalten
nltest /dbflag:0x2080ffff 

get-content c:\windows\debug\netlogon.log -wait -tail 1

# Debugging abschalten
nltest /dbflag:0x0

Die Ausgabe war umfangreich aber ich habe schon einen Hinweis gefunden:

/23 12:43:49 [LOGON] [4660] UCLABOR: SamLogon: Transitive Network logon of UCLABOR\User1 from  (via DC2) Returns 0xC000006A
/23 12:43:51 [LOGON] [4660] UCLABOR: SamLogon: Transitive Network logon of UCLABOR\User1 from  (via DC2) Entered
/23 12:43:51 [LOGON] [4660] UCLABOR: SamLogon: Transitive Network logon of UCLABOR\User1 from  (via DC2) Returns 0xC000006A
/23 12:43:54 [LOGON] [4660] UCLABOR: SamLogon: Transitive Network logon of UCLABOR\User1 from  (via DC2) Entered
/23 12:43:54 [LOGON] [4660] UCLABOR: SamLogon: Transitive Network logon of UCLABOR\User1 from  (via DC2) Returns 0xC000006A
/23 12:43:56 [LOGON] [3044] UCLABOR: SamLogon: Transitive Network logon of UCLABOR\User1 from  (via DC2) Entered
/23 12:43:56 [LOGON] [3044] UCLABOR: SamLogon: Transitive Network logon of UCLABOR\User1 from  (via DC2) Returns 0xC000006A

Hier laufen dann schon einige Meldungen rein. Anscheinend nutzt der verdächtige Client den DC2, der die Meldung dann zum DC1 (PDC Emulator) weiterreicht. Die Datei wird maximal 20MB groß und danach wird sie zu Netlogon.bak umbenannt und wieder neu gestartet. mehr als 40MB werden auf der Festplatte daher nicht belegt.

Anmelde-DC untersuchen

Also habe ich meinen PDC-Emulator in Ruhe gelassen und habe mich zum DC2 verbunden. Aber auch hier habe nicht nicht viel gefunden. Natürlich gibt es hier im Eventlog die 4740-Einträge:

Log Name:      Security
Source:        Microsoft-Windows-Security-Auditing
Date:          23.01.2019 13:03:22
Event ID:      4740
Task Category: User Account Management
Level:         Information
Keywords:      Audit Success
User:          N/A
Computer:      DC2.UCLABOR.de
Description:
A user account was locked out.

Subject:
        Security ID:            SYSTEM
        Account Name:           DC2$
        Account Domain:         UCLABOR
        Logon ID:               0x3E7

Account That Was Locked Out:
        Security ID:            UCLABOR\user1
        Account Name:           user1

Additional Information:
        Caller Computer Name:	
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="Microsoft-Windows-Security-Auditing" Guid="{54849625-5478-4994-A5BA-3E3B0328C30D}" />
    <EventID>4740</EventID>
    <Version>0</Version>
    <Level>0</Level>
    <Task>13824</Task>
    <Opcode>0</Opcode>
    <Keywords>0x8020000000000000</Keywords>
    <TimeCreated SystemTime="2019-01-23T12:03:22.871287200Z" />
    <EventRecordID>2372356</EventRecordID>
    <Correlation />
    <Execution ProcessID="524" ThreadID="4544" />
    <Channel>Security</Channel>
    <Computer>DC2.UCLABOR.de</Computer>
    <Security />
  </System>
  <EventData>
    <Data Name="TargetUserName">user1</Data>
    <Data Name="TargetDomainName">
    </Data>
    <Data Name="TargetSid">S-1-5-21-11949449-30417519-71842111-2522</Data>
    <Data Name="SubjectUserSid">S-1-5-18</Data>
    <Data Name="SubjectUserName">DC2$</Data>
    <Data Name="SubjectDomainName">UCLABOR</Data>
    <Data Name="SubjectLogonId">0x3e7</Data>
  </EventData>
</Event>

Aber auch hier finde ich keine IP-Adresse oder einen Namen des Clients, auf dem der Anmeldeversuch stattgefunden hat. Auch hier habe ich dann mit dem NETLOGON-Debugging weiter gesucht und wurde wieder fündig.

01/23 13:13:19 [LOGON] [4544] UCLABOR: SamLogon: Transitive Network logon of UCLABOR\USER2 from (via CLIENT1) Entered
01/23 13:13:19 [LOGON] [4544] UCLABOR: SamLogon: Transitive Network logon of UCLABOR\USER2 from (via CLIENT1) Returns 0x0
01/23 13:13:21 [MAILSLOT] [1884] Received ping from CLIENT1(CLIENT1.uclabor.de) uclabor.de. (null) on UDP LDAP
01/23 13:13:21 [MISC] [1884] UCLABOR: Pack NextClosestSiteName into message 0
01/23 13:13:21 [MAILSLOT] [1884] UCLABOR: Ping response 'Sam Logon Response Ex' (null) to \\CLIENT1 Site: Paderborn on UDP LDAP
01/23 13:13:21 [LOGON] [3864] UCLABOR: SamLogon: Transitive Network logon of UCLABOR\user from  (via CLIENT1) Entered
01/23 13:13:21 [CRITICAL] [3864] NlPrintRpcDebug: Couldn't get EEInfo for I_NetLogonSamLogonEx: 1761 (may be legitimate for 0xc000006a)

Hier erscheint erstmals der Client "CLIENT1" als Quelle, für den der Domain Controller die Authentifizierung durchführt. Die ersten beiden Zeilen zeigen, wie eine erfolgreiche Anmeldung aussieht. Aber die Folgezeilen liefern den UDPPing um die Site zu ermitteln und dann eine versuchte Anmeldung, die mit einem Fehler beantwortet ist. Details zur Bedeutung des " Couldn't get EEInfo for I_NetLogonSamLogonEx" habe ich leider nicht ermitteln können. Die Meldung konnte ich aber bislang nur nur mit gesperrten Konten beobachten.

Analyse auf dem Client1

Erst die Analyse auf dem Client selbst hat dort dann gezeigt, welcher Client wirklich den Lockout erzeugt hat. Auch hier war es die 4740-Meldung, die dann nur komplett gewesen ist. Interessant war hier, dass es eine Client gab, die in meinem Netzwerk gar nicht bekannt war. Sehr schnell  habe ich dann aber ermittelt, dass es sich um ein "Docker Netzwerk" gehandelt hat und hier unter HyperV eine VM als Docker-Host diese IP-Adresse genutzt hat. Hier kann der Entwickler seine Anmeldedaten hinterlegen, mit denen der Docker Host sich dann zu anderen Dateifreigaben verbindet. Für mich war es aber schon etwas überraschend, dass hier die Kette so lang war:

  1. Eine HyperV VM mit Docker greift anscheinend auf die Festplatte des Hosts per SMB zu
  2. Der HyperV Host fragt den DC2, ob die Anmeldung OK ist.
  3. Der DC2 fragt oder informiert den DC

Die IP-Adresse oder der Name der ersten Station ist dabei zur an der zweiten Station zu sehen. In dem Fall was das aber kein überwachter Server sondern auch nur ein Client, dessen Eventlog natürlich nicht zuerst kontrolliert wird. Die weiteren Server sehen zwar noch den Anmeldeversuch aber im Eventlog steht weder der Client noch die vorhergehende Station. Dazu muss ich dann doch wieder das NETLOGON-Debugging einschalten.

Lockout tracking

Zumindest in meiner Demo-Umgebung ist es anscheinend nicht ausreichend den PDC-Emulator auf "Lockout"-Events zu überwachen und selbst die Kontroller aller DCs scheint nicht sicher den Verursacher aufzulisten. Ich werde nun sicher nicht jeden Client in das Enterprise Log Management aufnehmen aber suche schon noch nach einem Weg, dass die Details aus dem NETLOGON-Trace auch wieder den Weg in eine Eventlog-Message finden und so zumindest die Client ermittelbar ist. Es reicht aber doch nicht, den PDC-Emulator zu überwachen, da hier zwar alle Lockout-Anforderungen und Anfragen ankommen aber leider nicht der Name oder die IP-Adresse des Clients protokolliert wird.

In meinem Fall war es nun kein "Böser Angreifer", sondern der Anwender selbst, der sich durch hinterlegte veraltete Anmeldedaten in einer Applikation selbst immer wieder ausgesperrt hat. Wobei hier auch die Frage erlaubt sein darf, warum Docker es immer wieder versucht anstatt nach einer fehlerhaften Anmeldung den Anwender erneut zu fragen.

Weitere Links