Windows Logon Session Time Monitoring

Before you post: Your responses to these questions will help the community help you. Please complete this template if you’re asking a support question.
Don’t forget to select tags to help index your topic!

1. Describe your incident:
Hello I am a new user to graylog and I’d like to ask for help with a configuration. I am using winlogbeat to collect windows logon/logoff messages from computers. Every logon session has it’s specific LogonID. I need to create an event when a user doesn’t logoff after 12 hours.

What I was able to do:
Create a pipeline with a rules which adds new field in message, for Logon - Sessionidlogon and for Logoff - sessionid and then i routed these session messages to a new stream so that it would be easier to work with.
Here is the pipeline:
Stage 1 first rule:
rule “Create field SessionID”
when
has_field(“winlogbeat_winlog_task”) AND
to_string($message.winlogbeat_winlog_task) == “Logoff”
then set_field(“Sessionid”, $message.winlogbeat_winlog_event_data_TargetLogonId);
end

Stage 1 second rule:
rule “Create field SessionIDLogon”
when
has_field(“winlogbeat_winlog_task”) AND
to_string($message.winlogbeat_winlog_task) == “Logon”
then set_field(“Sessionidlogon”, $message.winlogbeat_winlog_event_data_TargetLogonId);
end

Stage 2 rule:
rule “Session stream rule”
when
has_field(“winlogbeat_winlog_task”)
then route_to_stream(“Session_stream”);
remove_from_stream(“Default Stream”);
debug($message.winlogbeat_winlog_task);
end

Till here everything works correctly, I have created a pipeline for the Session stream where I want to compare the messages and sort ended and opened sessions, so as the next step I created a rule which should sort ended session to another stream again, but I think this rule is not correct, I think it compares just fields in one message which is being processed.

The rule:
rule “Route ended session login message”
when
has_field(“winlogbeat_winlog_task”) AND
to_string($message.winlogbeat_winlog_task) == “Logon” AND
to_string($message.Sessionidlogon) == to_string($message.Sessionid)
then route_to_stream(“Ended sessions”);
end

I’ll be really grateful for any help. I haven’t figured out how to check the time of the session yet, but at first I need to know how to compare logon and logoff messages so I can sort opened and ended sessions

2. Describe your environment:

  • OS Information: Ubuntu 20.04.6 LTS

  • Package Version: Graylog 5.0.7+7758557

  • Service logs, configurations, and environment variables:
    rule “Create field SessionIDLogon”
    when
    has_field(“winlogbeat_winlog_task”) AND
    to_string($message.winlogbeat_winlog_task) == “Logon”
    then set_field(“Sessionidlogon”, $message.winlogbeat_winlog_event_data_TargetLogonId);
    end

Stage 2 rule:
rule “Session stream rule”
when
has_field(“winlogbeat_winlog_task”)
then route_to_stream(“Session_stream”);
remove_from_stream(“Default Stream”);
debug($message.winlogbeat_winlog_task);
end

rule “Route ended session login message”
when
has_field(“winlogbeat_winlog_task”) AND
to_string($message.winlogbeat_winlog_task) == “Logon” AND
to_string($message.Sessionidlogon) == to_string($message.Sessionid)
then route_to_stream(“Ended sessions”);
end

3. What steps have you already taken to try and solve the problem?
I was thinking about using filter and agreggation or event correlation, but I don’t think it’s usable in this situation, because I need to check if the session already ended or not.

4. How can the community help?
It would be great if someone could point me in the right direction on how to solve this.
Thank you very much.

I think you are trying to compare to values from a message in the past, you cannot do that natively in pipeline rules, you can only see data from the current message.

Two options, if your ingestion is under 2GB a day you can use the free enterprise license and use correlation events to alert based off this exact situation.

The other option is to use the community plugin (which is pretty old, and could stop working if there is an upgrade) slookup that lets you run a search from a pipeline. GitHub - billmurrin/graylog-plugin-slookup-function: Stream Lookup function for GrayLog2 Pipeline Processor
However, this means you will be running a lot of searches, so make sure your infrastructure can handle it.

Thank you very much for a fast response, I’ll check it out.

So I tried to use the slookup plugin, it seems to work but I have problems with values in fields that should slookup return.
I’ll try to explain the current situation:
------------------------------------------------------Stage1
When a logon message arrives in default stream I create field Sessionid:

rule “Create field SessionIDLogon”
when
has_field(“winlogbeat_winlog_task”) AND
to_string($message.winlogbeat_winlog_task) == “Logon”
then set_field(“Sessionid”, $message.winlogbeat_winlog_event_data_TargetLogonId);
end

When a logoff message arrives in default stream I also create field Sessionid:

rule “Create field SessionID”
when
has_field(“winlogbeat_winlog_task”) AND
to_string($message.winlogbeat_winlog_task) == “Logoff”
then set_field(“Sessionid”, $message.winlogbeat_winlog_event_data_TargetLogonId);
end
------------------------------------------------------Stage2
If it’s a Logon message route it to stream Active_Logins:

rule “Session stream rule”
when
has_field(“winlogbeat_winlog_task”) AND
to_string($message.winlogbeat_winlog_task) == “Logon”
then route_to_stream(“Active_Logins”);
remove_from_stream(“Default Stream”);
end

If it’s a Logoff message look in the stream Active_Logins and search for the same Sessionid defined in variable session, if it finds a match it should return fields with values as defined in the rule:

rule “Session check”
when
has_field(“winlogbeat_winlog_task”) AND
to_string($message.winlogbeat_winlog_task) == “Logoff”
then
let session = to_string($message.Sessionid);
//StreamID, Source Field, Destination Field, Return Field(s), Relative Time, Ascending SortOrder
let system_info = slookup(“6572c3d7c76687742ccfee90”, “Sessionid”, session, [“Sessionid”, “timestamp”], “100”, “asc”);
set_field(“Sessionidlogon”, to_string(system_info[0]));
set_field(“Session_logon_time”, to_string(system_info[1]));
set_field(“Session_ended”, to_string($message.timestamp));
end

The problem is that when a Logoff message comes it seems to lookup the login message with the same Sessionid, but the values it returns says “No match found”
So I’m not sure if it’s working correctly maybe I made a mistake somewhere.

Here’s how the fields in Logoff message looks after proccessing:

Session_ended
2023-12-14 08:34:05.218
Session_logon_time
No match found
Sessionid
0x5933747
Sessionidlogon
No match found
beats_type
winlogbeat
message
An account was logged off.

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