I am doing a student project to detect attempted logins into windows with wrong passwords (live-time) and warn the user. I detect when the computer is locked, then start listening for event 4648 written to event log.
4648 : A logon attempt with explicit credentials was attempted
My goal is to correctly detect event 4648 when the screen is locked.
I have a DateTime.Compare
that compares the timestamp when screen is locked and timestamp of 4648 event written. I make sure the handler only triggers if event is written after
screen is locked.
What baffles me is how the handler for event 4648
still triggers on correct first-try login attempts.
I have used these posts as reference
Detect windows logon attempts programmatically using C#
c# event handler is called multiple times when event is raised once
Programmatically Determine a Duration of a Locked Workstation?
I have tried unsubscribing from previous event handlers before subscribing again as the post i linked, however to no avail. I can't seem to find the reason why the event handler for 4648 keeps triggering ambiguously.
public static void LoginLogoutDetector()
{
Microsoft.Win32.SystemEvents.SessionSwitch += new Microsoft.Win32.SessionSwitchEventHandler(SystemEvents_SessionSwitch);
}
//if user locks screen
void SystemEvents_SessionSwitch(object sender, Microsoft.Win32.SessionSwitchEventArgs e)
{
//screen locked detection
if (e.Reason == SessionSwitchReason.SessionLock)
{
EventLog logListener = new EventLog("Security");
datetime = (DateTime.Now.ToString("dd:MM:yyyy hh:mm:ss tt")).ToString();//get the time of screenlock
logListener.EntryWritten -= logListener_EntryWritten;//unregister prev subscribers
logListener.EntryWritten += logListener_EntryWritten;//register
logListener.EnableRaisingEvents = true;
}
//screen unlock detection
else if (e.Reason == SessionSwitchReason.SessionUnlock)
{
Console.WriteLine("Screen unlocked!");
}
}//sessionswitch
This is the code for the handler for events written to event log
void logListener_EntryWritten(object sender, EntryWrittenEventArgs e)
{
//var eventLog = new EventLog("Security", System.Environment.MachineName);
//eventLog.Clear();
var events = new long[] { 4648 };
//only tell me if there is a 4648 event
if (events.Contains(e.Entry.InstanceId))
{
Console.WriteLine("4648 detected. triggered IF block");
string eventlogtime = e.Entry.TimeGenerated.ToString();// get timestamp of event log 4648 generated
//get the timestamp the log was generated (after d2!)
DateTime d1 = DateTime.Parse(eventlogtime);
Console.WriteLine("D1 (Event Log Timestamp) " + d1);
bruteforcelogtime = (d1).ToString();
//get the timestamp of computer locked (before d1!)
DateTime d2 = DateTime.ParseExact(datetime, "dd:MM:yyyy hh:mm:ss tt", CultureInfo.InvariantCulture);
Console.WriteLine("D2 (Computer Locked) :" + d2);
//d1 = event written
//d2 = computer locked
//event log should always be written after pc lock. d1>d2
int result = DateTime.Compare(d1, d2);
Console.WriteLine("Comparing d1,d2 = " + result);
if (result >= 0)//d1 later than d2
{
Console.WriteLine("Login with wrong password was attempted at " + e.Entry.TimeWritten);
Console.Write("\n");
MessageBox.Show("bad login detected");
}
}
else
{
Console.WriteLine("there were no brute force attempts ( no 4648) ");
}
}//LoginLogoutDetector
I expect the event handler logListener_EntryWritten
to only trigger when there are wrong login attempts. However it triggers even if there is a correct login attempt!
Outputs: even when I login with correct credentials on first try
Screen unlocked!
4648 detected. triggered IF block
D1 (Event Log Timestamp) 2/8/2019 2:44:03 PM
D2 (Computer Locked) :2/8/2019 2:43:59 PM
Comparing d1,d2 = 1
Login with wrong password was attempted at 2/8/2019 2:44:03 PM
there were no brute force attempts ( no 4648)
there were no brute force attempts ( no 4648)
there were no brute force attempts ( no 4648)
there were no brute force attempts ( no 4648)
there were no brute force attempts ( no 4648)