I have some C# code that seems to be working well to monitor Windows event 4624, and plan to use it in a Windows service to provide notification when a user successfully logs into a system. However the code will potentially be used on non-English computers, and I assume my code would not achieve the desired result on them. I have done some searching and it doesn't appear to me that there's an easy way monitor this event on multiple languages. Here is on example, and here is another one I found.
Maybe the easiest solution would be to have different versions of the program for different language systems or have logic built in that would detect the language and act accordingly, but both those options seem clumsy to me.
Is there some standardized way to collect this information that I'm missing?
public static async Task subscribe4624()
{
await Task.Run(() =>
{
EventLogWatcher watcher4624 = null;
try
{
EventLogQuery subscriptionQuery4624 = new EventLogQuery(
"Security", PathType.LogName, "*[System/EventID=4624]");
watcher4624 = new EventLogWatcher(subscriptionQuery4624);
// Make the watcher listen to the EventRecordWritten
// events. When this event happens, the callback method
// (EventLogEventRead) is called.
watcher4624.EventRecordWritten =
new EventHandler<EventRecordWrittenEventArgs>(
EventLogEventRead4624);
// Activate the subscription
watcher4624.Enabled = true;
for (; ; )
{
// Wait for events to occur.
System.Threading.Thread.Sleep(1000);
}
}
catch (EventLogReadingException e)
{
log.Info("Error reading the log: {0}" e.Message);
}
finally
{
// Stop listening to events
watcher4624.Enabled = false;
if (watcher4624 != null)
{
watcher4624.Dispose();
}
}
});
}
// Callback method that gets executed when an event is
// reported to the subscription.
public static void EventLogEventRead4624(object obj,
EventRecordWrittenEventArgs arg)
{
// Make sure there was no error reading the event.
if (arg.EventRecord != null)
{
//////
// This section creates a list of XPath reference strings to select
// the properties that we want to display
// In this example, we will extract the User, TimeCreated, EventID and EventRecordID
//////
// Array of strings containing XPath references
String[] xPathRefs = new String[5];
xPathRefs[0] = "Event/System/TimeCreated/@SystemTime";
xPathRefs[1] = "Event/System/Computer";
xPathRefs[2] = "Event/EventData/Data[@Name=\"TargetUserName\"]";
xPathRefs[3] = "Event/EventData/Data[@Name=\"TargetDomain\"]";
xPathRefs[4] = "Event/EventData/Data[@Name=\"LogonType\"]";
// Place those strings in an IEnumberable object
IEnumerable<String> xPathEnum = xPathRefs;
// Create the property selection context using the XPath reference
EventLogPropertySelector logPropertyContext = null;
try
{
logPropertyContext = new EventLogPropertySelector(xPathEnum);
}
catch (Exception ex)
{
log.Info(ex.Message);
}
IList<object> logEventProps = ((EventLogRecord)arg.EventRecord).GetPropertyValues(logPropertyContext);
if (logEventProps[4].ToString() == "2")
{
log.Info("Time: " logEventProps[0]);
log.Info("Computer: " logEventProps[1]);
log.Info("TargetUserName: " logEventProps[2]);
log.Info("TargetDomainName: " logEventProps[3]);
log.Info("LogonType: " logEventProps[4]);
log.Info("---------------------------------------");
//log.Info("Description: " arg.EventRecord.FormatDescription());
Console.WriteLine("Time: " logEventProps[0]);
Console.WriteLine("Computer: " logEventProps[1]);
Console.WriteLine("TargetUserName: " logEventProps[2]);
Console.WriteLine("TargetDomainName: " logEventProps[3]);
Console.WriteLine("LogonType: " logEventProps[4]);
Console.WriteLine("---------------------------------------");
//Console.WriteLine("Description: " arg.EventRecord.FormatDescription());
}
}
else
{
log.Info("The event instance was null.");
}
}
CodePudding user response:
Here's an XML for message 4621 from my computer (the operating system language is german):
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Security-Auditing" Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}" />
<EventID>4624</EventID>
<Version>2</Version>
<Level>0</Level>
<Task>12544</Task>
<Opcode>0</Opcode>
<Keywords>0x8020000000000000</Keywords>
<TimeCreated SystemTime="2022-02-14T12:10:32.8804196Z" />
<EventRecordID>706697</EventRecordID>
<Correlation ActivityID="{9d82cb76-0e04-0002-21cc-829d040ed801}" />
<Execution ProcessID="1180" ThreadID="58872" />
<Channel>Security</Channel>
<Computer>DESKTOP-Win10</Computer>
<Security />
</System>
<EventData>
<Data Name="SubjectUserSid">S-1-5-18</Data>
<Data Name="SubjectUserName">DESKTOP-WIN10$</Data>
<Data Name="SubjectDomainName">WORKGROUP</Data>
<Data Name="SubjectLogonId">0x3e7</Data>
<Data Name="TargetUserSid">S-1-5-18</Data>
<Data Name="TargetUserName">SYSTEM</Data>
<Data Name="TargetDomainName">NT-AUTORITÄT</Data>
<Data Name="TargetLogonId">0x3e7</Data>
<Data Name="LogonType">5</Data>
<Data Name="LogonProcessName">Advapi</Data>
<Data Name="AuthenticationPackageName">Negotiate</Data>
<Data Name="WorkstationName">-</Data>
<Data Name="LogonGuid">{00000000-0000-0000-0000-000000000000}</Data>
<Data Name="TransmittedServices">-</Data>
<Data Name="LmPackageName">-</Data>
<Data Name="KeyLength">0</Data>
<Data Name="ProcessId">0x480</Data>
<Data Name="ProcessName">C:\Windows\System32\services.exe</Data>
<Data Name="IpAddress">-</Data>
<Data Name="IpPort">-</Data>
<Data Name="ImpersonationLevel">%33</Data>
<Data Name="RestrictedAdminMode">-</Data>
<Data Name="TargetOutboundUserName">-</Data>
<Data Name="TargetOutboundDomainName">-</Data>
<Data Name="VirtualAccount">%43</Data>
<Data Name="TargetLinkedLogonId">0x0</Data>
<Data Name="ElevatedToken">%42</Data>
</EventData>
</Event>
So the entity names are still english, some of the values are not, though.