Exemple #1
0
        private Dictionary <int, PruneProcessInstance> ParseWhitelist()
        {
            Dictionary <int, PruneProcessInstance> newInstances = new Dictionary <int, PruneProcessInstance>();

            FileConfiguration whitelistFile = new FileConfiguration(ConfigPath, WhitelistPath);
            GpoConfiguration  whitelistGPO  = new  GpoConfiguration();

            //Module Only Syntax = 0
            //Process and Module Syntax = 1
            //Process Only Syntax = 2
            int whitelistSyntax = whitelistGPO.WhitelistSupportEnabled();

            String[] lines;

            if (whitelistSyntax != -1)
            {
                lines = whitelistGPO.ReadWhitelist();

                if (lines == null || lines.Length < 1)
                {
                    lines = whitelistFile.ReadWhitelist();
                }
            }
            else
            {
                lines = whitelistFile.ReadWhitelist();
            }

            try
            {
                //A dictionary so we know which of the currently monitored processes are in the whitelist
                Dictionary <string, bool> programFoundInWhitelist = new Dictionary <string, bool>();

                //initialize all members of the list to false
                foreach (string value in _processIdToWhitelistEntry.Values)
                {
                    if (!programFoundInWhitelist.ContainsKey(value))
                    {
                        programFoundInWhitelist.Add(value, false);
                    }
                }

                Process[] runningProcesses = Process.GetProcesses(".");

                //look at each line of the whitelist
                foreach (string line in lines)
                {
                    if (!string.IsNullOrWhiteSpace(line))
                    {
                        //remove starting and ending whitespace
                        string processName = line.Trim();

                        //the idle and system "processes" should not be monitored, so if they are included they get skipped
                        if (processName.Equals("0") || processName.Equals("4") ||
                            processName.Equals("idle", StringComparison.OrdinalIgnoreCase) ||
                            processName.Equals("system", StringComparison.OrdinalIgnoreCase))
                        {
                            PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteDISALLOWED_PROCESS_EVENT();
                            continue;
                        }

                        //if the line isn't a comment
                        if (processName.ToCharArray()[0] != '#')
                        {
                            if ((processName.Contains("module=") || processName.Contains("Module=")) && whitelistSyntax != 2)
                            {
                                //Split 'module=' off, then trim white space
                                string moduleName     = processName.Split('.')[0].Trim(); //module=test.dll -> module=test
                                string moduleFileTemp = processName.Split('=')[1].Trim(); //module=test.dll -> test.dll
                                string moduleFile     = null;
                                string moduleProcess  = null;

                                if (moduleFileTemp.Contains(","))
                                {
                                    string[] moduleTempSplit = moduleFileTemp.Split(','); //module=test.dll,svchost -> test.dll,svchost
                                    moduleFile    = moduleTempSplit[0].Trim();            //module=test.dll,svchost -> test.dll
                                    moduleProcess = moduleTempSplit[1].Trim();            //module=test.dll,svchost -> svchost
                                }
                                else
                                {
                                    moduleFile = moduleFileTemp;
                                }

                                if (_processIdToWhitelistEntry.ContainsValue(moduleName))
                                {
                                    programFoundInWhitelist[moduleName] = true;
                                    //TODO: Continue here? If it is already in the list, we can skip this
                                }

                                foreach (Process proc in runningProcesses)
                                {
                                    //ensure we don't already monitor this process and that this process is not the system or idle process
                                    if (proc.Id != 4 && proc.Id != 0 && !_processIdToWhitelistEntry.ContainsKey(proc.Id))
                                    {
                                        if (moduleProcess == null || moduleProcess == proc.ProcessName)
                                        {
                                            try
                                            {
                                                //collect the modules from for the process
                                                List <Prune.Module> moduleList =
                                                    Prune.NativeMethods.CollectModules(proc);

                                                foreach (Prune.Module module in moduleList)
                                                {
                                                    //Check if this module is the one we are looking for
                                                    if (module.ModuleName.Equals(moduleFile, StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        //It is, so add a new instances and log that it was created
                                                        newInstances.Add(proc.Id, new PruneProcessInstance(true,
                                                                                                           proc.Id, moduleName, _writeCacheInterval, _logInterval, DirectoryPath));
                                                        _processIdToWhitelistEntry.Add(proc.Id, moduleName);
                                                        PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteCREATING_INSTANCE_EVENT(moduleName + "_" + proc.Id);

                                                        //We don't need to look at the rest of the modules
                                                        break;
                                                    }
                                                }
                                            } catch (Exception) {
                                                //If we fail to get any modules for some reason, we need to keep going
                                                //We also don't need to report the error, because this will happen any time we try for a protected processes,
                                                //  which may be often
                                                continue;
                                            }
                                        }
                                        else
                                        {
                                        }
                                    }
                                }
                            }
                            else if (whitelistSyntax != 0)
                            {
                                if (_processIdToWhitelistEntry.ContainsValue(processName))
                                {
                                    programFoundInWhitelist[processName] = true;
                                }

                                string tempProcName;
                                bool   nameIsId = false;

                                //If the name is all digits, it is treated as an ID
                                if (processName.All(char.IsDigit))
                                {
                                    nameIsId = true;

                                    //Get the process name from the ID to ensure there is a process tied to this ID currently active
                                    tempProcName = Prune.GetProcessNameFromProcessId(int.Parse(processName));

                                    if (tempProcName == null)
                                    {
                                        //Could not find a name for the given process ID.
                                        //  Assume the process is not active and skip it.
                                        continue;
                                    }
                                }
                                else //Otherwise it is treated as a process name
                                {
                                    tempProcName = processName;
                                }

                                //Get all system process objects that have the specified name
                                Process[] processes = Prune.GetProcessesFromProcessName(tempProcName);

                                if (processes == null || processes.Length == 0)
                                {
                                    //Could not find any processes that have the provided name.
                                    //  Assume the process is not started and skip it.
                                    continue;
                                }

                                if (nameIsId)
                                {
                                    int procId = int.Parse(processName);
                                    processName = Prune.GetProcessNameFromProcessId(procId);

                                    if (!_processIdToWhitelistEntry.ContainsKey(procId))
                                    {
                                        //Because an ID was provided, use the ID for the new instance
                                        newInstances.Add(procId, new PruneProcessInstance(true, procId, processName,
                                                                                          _writeCacheInterval, _logInterval, DirectoryPath));
                                        _processIdToWhitelistEntry.Add(procId, processName);
                                        PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteCREATING_INSTANCE_EVENT(processName + "_" + procId);
                                    }
                                }
                                else
                                {
                                    //We were given a process name, so we create a Prune instance for each process instances
                                    foreach (Process proc in processes)
                                    {
                                        int procId = proc.Id;

                                        if (!_processIdToWhitelistEntry.ContainsKey(procId))
                                        {
                                            newInstances.Add(procId,
                                                             new PruneProcessInstance(true, procId, processName,
                                                                                      _writeCacheInterval, _logInterval, DirectoryPath));
                                            _processIdToWhitelistEntry.Add(procId, processName);
                                            PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteCREATING_INSTANCE_EVENT(processName + "_" + procId);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                //Loop through to see which Prune instances are tied to processes no longer in the whitelist
                foreach (string key in programFoundInWhitelist.Keys)
                {
                    if (!programFoundInWhitelist[key])
                    {
                        //Make a copy of the list to iterate over so that we can remove elements from the original list
                        Dictionary <int, string> tempList = new Dictionary <int, string>(_processIdToWhitelistEntry);

                        lock (_PruneInstances)
                        {
                            //loop through the copied list of all elements that we have Prune instances for that are no longer in the whitelist
                            foreach (KeyValuePair <int, string> entry in tempList)
                            {
                                if (entry.Value == key)
                                {
                                    //call the finish monitoring method to wrap everything up
                                    _PruneInstances[entry.Key].FinishMonitoring();

                                    //Remove the process from the list of processes monitored by ETW
                                    Prune.RemoveEtwCounter(entry.Key);

                                    //remove it form the active Prune instances
                                    _PruneInstances.Remove(entry.Key);

                                    //remove it from the active whitelist entries
                                    _processIdToWhitelistEntry.Remove(entry.Key);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Prune.HandleError(true, 1, "Error while parsing the whitelist\n" + e.Message);
            }

            return(newInstances);
        }
Exemple #2
0
        //Read the config settings and parse the values it contains
        private void ReadConfigSettings()
        {
            FileConfiguration configFile = new FileConfiguration(ConfigPath, WhitelistPath);
            GpoConfiguration  configGPO  = new  GpoConfiguration();

            //Retrieve the configuration objects
            ServiceConfiguration fileConfig = configFile.ReadConfiguration();
            ServiceConfiguration gpoConfig  = configGPO.ReadConfiguration();

            _logInterval            = fileConfig.CalculateStatisticsInterval;
            _writeCacheInterval     = fileConfig.WriteCacheToFileInterval;
            _monitorInterval        = fileConfig.DataRecordingInterval;
            _whitelistCheckInterval = fileConfig.WhitelistCheckInterval;
            _configCheckInterval    = fileConfig.ConfigCheckInterval;

            //Check if Gropu Policy is configured
            if (gpoConfig != null)
            {
                //GP setting overrides local config file setting
                //CalculateStatisticsInterval
                if (gpoConfig.CalculateStatisticsInterval != 0)
                {
                    _logInterval = gpoConfig.CalculateStatisticsInterval;
                }

                //WriteCacheToFileInterval
                if (gpoConfig.WriteCacheToFileInterval != 0)
                {
                    _writeCacheInterval = gpoConfig.WriteCacheToFileInterval;
                }

                //DataRecordingInterval
                if (gpoConfig.DataRecordingInterval != 0)
                {
                    _monitorInterval = gpoConfig.DataRecordingInterval;
                }

                //WhitelistCheckInterval
                if (gpoConfig.WhitelistCheckInterval != 0)
                {
                    _whitelistCheckInterval = gpoConfig.WhitelistCheckInterval;
                }

                //ConfigCheckInterval
                if (gpoConfig.ConfigCheckInterval != 0)
                {
                    _configCheckInterval = gpoConfig.ConfigCheckInterval;
                }
            }

            //Bounds checking on input to ensure everything is a valid input
            //	If something does equal 0, then we set it to the default time
            if (_logInterval == 0)
            {
                _logInterval = 86400;
            }

            if (_writeCacheInterval == 0)
            {
                _writeCacheInterval = 3600;
            }

            if (_monitorInterval == 0)
            {
                _monitorInterval = 1;
            }

            try
            {
                _monitorTimer.Interval   = _monitorInterval * 1000;
                _whitelistTimer.Interval = _whitelistCheckInterval * 1000;
                _configTimer.Interval    = _configCheckInterval * 1000;
                _logTimer.Interval       = 86400 * 1000;
            }
            catch (Exception e)
            {
                Prune.HandleError(true, 1, "Error setting timer interval times from the configuration file input\n" + e.Message);
            }
        }