Windows.Events.FailedLogBeforeSuccess

Sometimes attackers will brute force an local user’s account’s password. If the account password is strong, brute force attacks are not effective and might not represent a high value event in themselves.

However, if the brute force attempt succeeds, then it is a very high value event (since brute forcing a password is typically a suspicious activity).

On the endpoint this looks like a bunch of failed logon attempts in quick succession followed by a successful login.

NOTE: In order for this artifact to work we need Windows to be logging failed account login. This is not on by default and should be enabled via group policy.

https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/basic-audit-logon-events

You can set the policy in group policy management console (gpmc): Computer Configuration\Windows Settings\Security Settings\Local Policies\Audit Policy.


name: Windows.Events.FailedLogBeforeSuccess
description: |
  Sometimes attackers will brute force an local user's account's
  password. If the account password is strong, brute force attacks are
  not effective and might not represent a high value event in
  themselves.

  However, if the brute force attempt succeeds, then it is a very high
  value event (since brute forcing a password is typically a
  suspicious activity).

  On the endpoint this looks like a bunch of failed logon attempts in
  quick succession followed by a successful login.

  NOTE: In order for this artifact to work we need Windows to be
  logging failed account login. This is not on by default and should
  be enabled via group policy.

  https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/basic-audit-logon-events

  You can set the policy in group policy management console (gpmc):
  Computer Configuration\Windows Settings\Security Settings\Local Policies\Audit Policy.
type: CLIENT_EVENT

parameters:
  - name: securityLogFile
    default: >-
      C:/Windows/System32/Winevt/Logs/Security.evtx

  - name: failureCount
    description: Alert if there are this many failures before the successful logon.
    default: 3

  - name: failedLogonTimeWindow
    default: 3600

sources:
  - precondition:
      SELECT OS FROM info() where OS = 'windows'
    query: |
      LET failed_logon = SELECT EventData as FailedEventData,
           System as FailedSystem
      FROM watch_evtx(filename=securityLogFile)
      WHERE System.EventID.Value = 4625


      LET last_5_events = SELECT FailedEventData, FailedSystem
        FROM fifo(query=failed_logon,
                      max_rows=500,
                      max_age=atoi(string=failedLogonTimeWindow))

      // Force the fifo to materialize.
      LET foo <= SELECT * FROM last_5_events

      LET success_logon = SELECT EventData as SuccessEventData,
           System as SuccessSystem
        FROM watch_evtx(filename=securityLogFile)
        WHERE System.EventID.Value = 4624

      SELECT * FROM foreach(
          row=success_logon,
          query={
           SELECT SuccessSystem.TimeCreated.SystemTime AS LogonTime,
                  SuccessSystem, SuccessEventData,
                  enumerate(items=FailedEventData) as FailedEventData,
                  FailedSystem, count(items=SuccessSystem) as Count
           FROM last_5_events
           WHERE FailedEventData.SubjectUserName = SuccessEventData.SubjectUserName
           GROUP BY LogonTime
          })  WHERE Count > atoi(string=failureCount)