Monitoring Windows Logons with Winlogbeat

Windows event logs can provide invaluable insight into your Windows based infrastructure. The Windows operating system has many event log channels, each dedicated to a specific category of events. In this blog post we are going to look at how to visualize logon and logon failure events from the Security event log.

Winlogbeat is our lightweight shipper for Windows event logs. It installs and runs as a Windows service and ships event log data to Elasticsearch or Logstash. We will install Winlogbeat 5.0 on all machines in our example domain. Winlogbeat 5.0 has a new feature that enables it to ship the raw data that was used in logging the event. Having these raw event data fields makes filtering and aggregating much easier than in earlier versions of Winlogbeat.

Winlogbeat - Account Usage Dashboard


Below is the configuration file being used with Winlogbeat to ship data directly to Elasticsearch. For more information on how to install Winlogbeat please see the Getting Started Guide.

  - name: Security
    ignore_older: 168h

  hosts: ["elasticsearch.elastic.local:9200"] "winlogbeat"
  template.path: "winlogbeat.template.json"
  template.overwrite: false

On domain controllers I am adding an additional line to the configuration file as shown below. This will tag all events from the domain controllers with dc. The tag will we be used for filtering.

tags: ['dc']

Monitoring for Successful Logons

Successful Windows Logons

The reason for monitoring successful logons is to look for compromised user credentials. The number of successful logons can be a major indicator that compromised credentials are being used for system crawling or other malicious activity.

An event with event ID 4624 is logged by Windows for every successful logon regardless of the logon type (local, network, remote desktop, etc.).

If we simply created a data table visualization in Kibana showing all events with event ID 4624 we would be overwhelmed with noise and it would not be easy to spot abnormal user logon patterns. So there are several filtering steps we are going to apply to remove the noise. Each of the filters is described below.

| Filter | Description |-------------------------------------------------|------------------------------------------------- | event_id:4624 | This selects all logon events across the domain. | !event_data.LogonType:0 | This filters logon type 0 which is used for system accounts. | !event_data.LogonType:5 | This filters logon type 5 which is used for service accounts. | !event_data.TargetUserName:"ANONYMOUS LOGON" | This filters anonymous logons ( which are typically benign. Anonymous users have extremely limited privileges. | !event_data.TargetDomainName:"Window Manager" | This filters logons from the Desktop Window Manager that is part of Windows 8 and Windows 2012. | !event_data.TargetUserName:*$ | This filters logons from managed service accounts. The trailing dollar sign is reserved for managed service accounts. | !tags:"dc" | This filters logon events from our domain controllers. When a user logs onto a domain workstation and their credentials are not cached locally, a logon event is generated on both the workstation and domain controller. This filter prevents us from double counting the number of successful user logons.

The data table visualization shown above was created using this list of filters. The data table uses aggregations to count the total number of logons per user, the number of unique computers the user logged on to, and the number of unique source IPs that were used in those logons (if the user was remote).

The table can be used to spot accounts that are potentially compromised. If an account has been used to logon to an abnormally high number of computers within your organization, it would warrant further investigation to see if the account is being used to crawl the network.

Monitoring Logon Failures

Failed Logon Attempts

Monitoring failed logons can be useful for a number of purposes. From a security perspective, the obvious use cases are to detect unauthorized access attempts and brute-force credential attacks. From an infrastructure management perspective, failed logon attempts can be used to detect problems. For example, if a service account starts generating failures then it may indicate a configuration issue.

Windows uses event ID 4625 when logging failed logon attempts. To visualize the failed logons we are going to use an area chart and simply filter for event_id:4625. To show the different types of logons being used we split the area based on the event_data.LogonType field. An example is is shown above.

If anomalies are spotted in the chart, the user can select a more specific time period or logon type and use the Discover tab to view more details.

Visualizing the Origin of Remote Logons (requires Logstash)

Source Locations of all Remote Desktop Logons and Logon Attempts

If you allow Remote Desktop connections from the Internet it can be useful to plot the origins of those connections of a map. Both successful and failed logons report the IP address of the client in the event_data.IpAddress field. By using a GeoIP filter to enrich the event with the location associated with the source IP address, we can visualize the events on a map in Kibana.

This type of visualization can be used to quickly spot anomalies. For example, if you have no employees in South America and suddenly you have successful logons originating from that continent, then it's time to further investigate the incident.


This setup is a bit more advanced because it requires using either Logstash or an Ingest Node pipeline to enrich the event with the location associated with the IP address. Below are the configurations I used to enrich the events using Logstash.

This is the Winlogbeat configuration file. The output was changed from Elasticsearch to Logstash.

  - name: Security
    ignore_older: 168h

  hosts: ["logstash.elastic.local:9200"]

This is the Logstash configuration. It accepts data from the Winlogbeat instances on port 5044. It enriches the events with location information using the the geoip filter. And finally it outputs the events to Elasticsearch.

input {
  beats {
    port => 5044

filter {
  geoip {
    source => "[event_data][IpAddress]"

output {
  elasticsearch {
    hosts => "logstash.elastic.local:9200"
    manage_template => false
    index => "%{[@metadata][beat]}-%{+YYYY.MM.dd}"
    document_type => "%{[@metadata][type]}"

And because we are indexing a new field in our events we need to enhance the Elasticserach index template used for the Winlogbeat data. Install this template to Elasticsearch before indexing events containing the geoip fields.

PUT _template/winlogbeat_1
  "order": 1,
  "template": "winlogbeat-*",
  "mappings": {
    "_default_": {
      "properties": {
        "geoip"  : {
          "dynamic": true,
          "properties" : {
            "ip": { "type": "ip" },
            "location" : { "type" : "geo_point" },
            "latitude" : { "type" : "float" },
            "longitude" : { "type" : "float" }


Logon (4624) and logon failure (4625) events are just two of the many events generated by Windows that can monitored, visualized, and alerted on by using the Elastic stack. There are many great resources available that explain the value that can be obtained by monitoring certain Windows event IDs. Check out Events to Monitor from Microsoft or Spotting the Adversary with Windows Event Log Monitoring from the U.S. National Security Agency.

The visualizations created here can be downloaded as JSON and imported directly into a Kibana. To import into Kibana click on Settings -> Objects -> Import, and then select the JSON file you downloaded.