Beispiel #1
0
        // This stuff happens when you click the "Update config on selected computers button"
        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            if (SelectedComputerList.SelectedIndex < 0)
            {
                System.Windows.MessageBox.Show("Please Select a Computer");
                return;
            }
            // If the selected listbox item is the tag of the config, rather than the configuration itself, pop up an error and let the user try again
            string selectedItem = Configs.Items[Configs.SelectedIndex].ToString();
            bool   containsTag  = selectedItem.Contains("Tag");

            if (containsTag == true)
            {
                System.Windows.MessageBox.Show("Error, Select config value, not the tag");
                return;
            }
            // UpdateConfigs
            Regex ConfigToDeployRegEx = new Regex(@"([^\\]*)$");
            Match MatchedSysmonConfig = ConfigToDeployRegEx.Match(selectedItem);

            System.Collections.IList
            // This grabs the selected computer variable
                ComputerSelected = SelectedComputerList.SelectedItems;

            // If there is no computer selected to update the configuration on, pop up an error and let the user try again
            if (SelectedComputerList.SelectedIndex < 0)
            {
                System.Windows.MessageBox.Show("Please Select a Computer");
                return;
            }

            // Run command on whatever computers we selected - probably need a better way to do this at some point, with multiple threads etc - this is a pretty funky loop as we are doing some validation here as well
            foreach (object SelectedComputer in ComputerSelected)
            {
                ManagementClass      processClass = new ManagementClass($@"\\{SelectedComputer}\root\cimv2:Win32_Process");
                ManagementBaseObject inParams     = processClass.GetMethodParameters("Create");

                //Selected Sysmon Config Variable Name = FinalSysmonMatchedConfig
                var FinalSysmonMatchedConfig = MatchedSysmonConfig.ToString();

                //Commands ran on the remote host to update the configuration file
                inParams["CommandLine"]      = "C:\\SysmonFiles\\Sysmon.exe -c " + FinalSysmonMatchedConfig;
                inParams["CurrentDirectory"] = @"C:\SysmonFiles";
                ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);



                Log.Information("Updated " + SelectedComputer + " with " + FinalSysmonMatchedConfig);

                // XPath Query for Event ID 16s only, this is the "Sysmon config state changed" event - later we specify the log channel and extract the SHA256 value of the configuration file hash as it exists on the remote host
                string logQuery = "*[System[(EventID = 16)]]";

                //Establish a remote event log session on the computer in this for loop
                EventLogSession session = new EventLogSession(SelectedComputer.ToString());
                EventLogQuery   query   = new EventLogQuery("Microsoft-Windows-Sysmon/Operational", PathType.LogName, logQuery);
                query.Session = session;
                try
                {
                    EventLogReader logReader = new EventLogReader(query);
                    // Loop through the events that were returned in the above query
                    for (EventRecord eventdetail = logReader.ReadEvent(); eventdetail != null; eventdetail = logReader.ReadEvent())
                    {
                        // EventData variable contains the detail of each event in XML format, I tried to use LINQ to extract the XML elements instead of regex but found regex to be simpler, please don't hate me for the upcoming dirty regexes
                        string EventData = eventdetail.ToXml();
                        // RegEx used to extract just the SHA256 hash from Event ID 16
                        Regex SHA256 = new Regex(@"[A-Fa-f0-9]{64}");
                        // Put the matched regex (the SHA256) hash into a variable called SHA256Value
                        Match SHA256Value = SHA256.Match(EventData);
                        // Another awful regex to extract the time stamp from Event ID 16 - the SHA256 value of the updated config as well as the time stamp get logged, this way you can validate that the right configuration file got pushed to the right computer
                        Regex LoggedEventTime        = new Regex(@"\d\d\d\d\-\d\d\-\d\d.\d\d\:\d\d\:\d\d\.\d\d\d");
                        Match MatchedLoggedEventTime = LoggedEventTime.Match(EventData);
                        // Log showing that we found an Event ID 16 on the selected remote host, and we log the time and SHA256 value of the configuration file pushed
                        Log.Information("Found Config Update Event on " + SelectedComputer + " Logged at " + MatchedLoggedEventTime + "." + " Updated with config file with the SHA256 Hash of: " + SHA256Value.ToString());
                    }
                }
                catch (Exception eventlogexception)
                {
                    Log.Debug(eventlogexception.Message + ": You may have hit the update configs button on a host with Sysmon not installed");
                }
            }
        }
Beispiel #2
0
        // This takes the selected items from the "ComputerList" ListBox, loops through them and puts them into another ListBox named "SelectedComputerList" - we want to perform whatever actions we need on this list

        public void SelectComputers_Click(object sender, RoutedEventArgs e)
        {
            // If we click on select computers with no actual computers selected pop up a message box since the GUI is a bit confusing
            if (ComputerList.SelectedIndex < 0)
            {
                System.Windows.MessageBox.Show("Please Select a Computer from the Live Computers in Domain List");
                return;
            }
            // Need better logic for handling duplicates here
            SelectedComputerList.Items.Clear();

            // Put the computers the user selected in the GUI into a variable
            var SelectedComputers = ComputerList.SelectedItems;

            // Set parallel options
            int computercount = ((IList)SelectedComputers).Count;
            var options       = new ParallelOptions {
                MaxDegreeOfParallelism = 100
            };

            // Need to put the list of computers into a blocking collection for parallel for each
            BlockingCollection <string> SelectedComputersCollection = new BlockingCollection <string>();

            // Loop through the list of selected computers and add them to the new blocking list
            foreach (object SelectedComputer in SelectedComputers)
            {
                SelectedComputersCollection.Add((string)SelectedComputer);
            }

            // Looping through the computers that are in the domain or populated via a text file - this logic performs a ping check on the computers and adds them to the middle computers you want to action listbox, these are the computers that will have various commands issued to them

            //REF: http://hk.uwenku.com/question/p-dyussklc-gg.html (sketchy site)


            // Setting the value for ping timeout, 5000ms
            int pingtimeout = 5000;
            // Setting the current variable to 0, this is used for the progress bar
            int current = 0;

            // Setting the max value of the progress bar equtal to the amount of computers
            myprogressDialog.Maximum = computercount;
            // Initailizing the percentcomplete variable, used for the progress bar
            int percentcomplete = 0;

            // Start the task for the foreach loop, this loops through a list of computers and adds only the live ones
            Task looper = new Task(() =>
            {
                Parallel.ForEach(SelectedComputersCollection, options, SelectedComputer =>
                                 // foreach (object SelectedComputer in SelectedComputers) -- this is the old for loop, leaving here just in case
                {
                    // Need to use the Dispatcher method to update GUI
                    Dispatcher.Invoke(async() =>
                    {
                        StatusLabel.Content = "Working...";

                        // This stuff updates the progress bar, needs a bit of work
                        current++;
                        percentcomplete        = (current / computercount) * 100;
                        myprogressDialog.Value = percentcomplete;
                        // End of progress bar update

                        // Within the loop, try, catch - try the pings and log successes, if it fails log the error message

                        Ping pingSender = new Ping();
                        //PingReply ComputerPingReply = pingSender.Send(SelectedComputer.ToString(), pingtimeout); -- this is the old single threaded ping, leaving here just in case
                        try
                        {
                            PingReply ComputerPingReply = await pingSender.SendPingAsync(SelectedComputer.ToString(), pingtimeout);
                            if (ComputerPingReply.Status == IPStatus.Success)
                            {
                                myprogressDialog.Value = current;
                                SelectedComputerList.Items.Add(SelectedComputer);
                                Log.Information(SelectedComputer + " Passed Ping Check");
                            }
                            if (ComputerPingReply.Status == IPStatus.DestinationHostUnreachable)
                            {
                                myprogressDialog.Value = current;
                                Log.Information(SelectedComputer + " Was Unreachable");
                            }
                        }
                        catch (Exception pingexception)
                        {
                            Log.Debug(SelectedComputer + " : " + pingexception.InnerException.Message);
                        }
                    });
                });
            });  // closing brackets for the Task

            // Start our looper task
            looper.Start();
            // When the task is done, update the status label and dispose of the task
            looper.GetAwaiter().OnCompleted(() =>
            {
                StatusLabel.Content = "Done!";
                looper.Dispose();
            });
        }