2

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 IEnumerable 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.");
            }
        }
5
  • 1
    I just checked, on my german windows, the XML description of that event looks exactly like you would expect, everything is english or language-independent. Of course, you need to make sure that you parse the fields (e.g. the time) correctly with CultureInfo.InvariantCulture Commented Feb 14, 2022 at 12:20
  • 1
    Your assumption is wrong, the XML schema remains the same across languages, so the property selectors will work regardless :) Commented Feb 14, 2022 at 12:38
  • Thanks to those that commented here. If somebody could post the XML for a 5478 event on a non-English system as an answer to this question it might clarify to others that are wondering about this in the future. Commented Feb 14, 2022 at 13:21
  • @user3140383 Why 5478? You were talking about 4624. Commented Feb 14, 2022 at 15:09
  • @PMF, I meant 4624. I'm actually monitoring both, but for the purpose of this discussion I should've said 4624. Commented Feb 14, 2022 at 15:27

1 Answer 1

2

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">%%1833</Data> 
    <Data Name="RestrictedAdminMode">-</Data> 
    <Data Name="TargetOutboundUserName">-</Data> 
    <Data Name="TargetOutboundDomainName">-</Data> 
    <Data Name="VirtualAccount">%%1843</Data> 
    <Data Name="TargetLinkedLogonId">0x0</Data> 
    <Data Name="ElevatedToken">%%1842</Data> 
  </EventData>
</Event>

So the entity names are still english, some of the values are not, though.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @PMF! Appreciate it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.