Watcher alerts for failed logons

I am currently using Winlogbeat to send security logs from multiple domain controllers. I want to set up a watcher alert that would trigger on x amount of failed logon attempts to the same user in a certain time range. Would anyone be able to help me with the query syntax for this certain case? Thanks.

Hey,

unfortunately I dont have a windows machine to check how a failed login attempt looks like, are willing to share such a document? At the end, everything boils down to write a query, that matches your requirement and then put a watch around it...

--Alex

This is what the event itself looks like.

Hey,

I was talking about what the event looked like in Elasticsearch, not on the windows side. Can you just execute a search against the index that stores your event and show a sample JSON of a failed login attempt?

--Alex

{
"_index": "winlogbeat-2017.07.12",
"_type": "wineventlog",
"_id": "AV03UyPKa8mW8Kx63QBo",
"_version": 1,
"_score": null,
"_source": {
"computer_name": "DCxxx",
"process_id": 496,
"keywords": [
"Audit Failure"
],
"log_name": "Security",
"level": "Information",
"record_number": "1288265xx",
"event_data": {
"Status": "0x18",
"PreAuthType": "2",
"ServiceName": "krbtgt/",
"TicketOptions": "0x4081001x",
"TargetSid": "S-1-xxx",
"IpAddress": "::ffff:xx.xx.x.xxx",
"IpPort": "xxxxx",
"TargetUserName": "xxx"
},
"message": "Kerberos pre-authentication failed.\n\nAccount Information:\n\tSecurity ID:\t\tS-1-xxx\n\tAccount Name:\t\xxx\n\nService Information:\n\tService Name:\t\tkrbtgt/xxx\n\nNetwork Information:\n\tClient Address:\t\t::ffff:xx.xx.x.xxx\n\tClient Port:\t\txxxxx\n\nAdditional Information:\n\tTicket Options:\t\t0x40810xx\n\tFailure Code:\t\t0x18\n\tPre-Authentication Type:\t2\n\nCertificate Information:\n\tCertificate Issuer Name:\t\t\n\tCertificate Serial Number: \t\n\tCertificate Thumbprint:\t\t\n\nCertificate information is only provided if a certificate was used for pre-authentication.\n\nPre-authentication types, ticket options and failure codes are defined in RFC 4120.\n\nIf the ticket was malformed or damaged during transit and could not be decrypted, then many fields in this event might not be present.",
"opcode": "Info",
"type": "wineventlog",
"tags": [
"beats_input_codec_plain_applied"
],
"thread_id": 1300,
"@timestamp": "2017-07-12T15:03:30.208Z",
"task": "Kerberos Authentication Service",
"event_id": 4771,
"provider_guid": "{54849625-5478-4994-A5BA-3E3B0328C30D}",
"@version": "1",
"beat": {
"hostname": "DCxxx",
"name": "DCxxx",
"version": "5.4.1"
},
"host": "DCxxx",
"source_name": "Microsoft-Windows-Security-Auditing"
},
"fields": {
"@timestamp": [
1499871810208
]
},
"highlight": {
"keywords": [
"@kibana-highlighted-field@Audit Failure@/kibana-highlighted-field@"
]
},
"sort": [
1499871810208
]
}

Hey,

so in this example, you would need to build a query that filters for ServiceName": "krbtgt/", and searches in the message field for kerberos failed. Then this query also requires a filter for the last n minutes. As you also want to get counts per user, you need to have a terms aggregation on the TargetUserName field. The query would be something like this (I left out some parts, consider it pseudocode)

"query" : {
  "bool" : {
    "filter" : [
      { "range" : { "@timestamp" : {  FROM NOW-5minutes TILL NOW } } },
      { "match" : { "message" : "kerberos failed" }}
    ]
  }
},
"aggs" : {
  "byUser" : {
     "terms" : { "field" : "TargetUserName" }   
} 
}

Once you have this query, you can start writing a watch. But make sure that the query works as expected.

For further alerting examples, check out the examples repo

--Alex

1 Like

Thank you. After the usernames are bucketed how would I create a condition that would only return a hit if a bucket has 3 or more docs in it?

1 Like

Hey,

there is a min_doc_count parameter for the terms agg to only return buckets with a certain count, then you could check if any buckets are returned as part of the condition.

--Alex

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.