Beispiel #1
0
        protected override void OnStop()
        {
            // Guardrail for timeout
            RequestAdditionalTime(5000);

            // Check if any collector tasks are registered
            if (SilkUtility.CollectorTaskList.Any())
            {
                // We pop terminated threads out of the list
                foreach (CollectorInstance CollectorTask in SilkUtility.CollectorTaskList)
                {
                    try
                    {
                        CollectorTask.EventSource.StopProcessing();
                        TraceEventSession.GetActiveSession(CollectorTask.EventParseSessionName).Dispose();
                        SilkUtility.CollectorTaskList.Remove(CollectorTask);
                        SilkUtility.WriteCollectorGuidMessageToServiceTextLog(CollectorTask.CollectorGUID, "Collector terminated", false);
                    } catch { }
                }
            }

            // Write status to log
            SilkUtility.WriteToServiceTextLog("[+] SilkService stopped at: " + DateTime.Now);
        }
Beispiel #2
0
        protected override void OnStart(string[] args)
        {
            SilkUtility.WriteToServiceTextLog("[+] SilkService started at: " + DateTime.Now);
            List <CollectorParameters> CollectorConfig = SilkParameters.ReadXmlConfig();

            if (!CollectorConfig.Any())
            {
                // We didn't find any ETWCollector elements so we stop the service
                // Logs in ServiceLog text file
                // Stop -> OnStop -> Change service state
                Stop();
            }
            else
            {
                Boolean IsSuccess = SilkParameters.ValidateCollectorParameters(CollectorConfig);
                if (!IsSuccess)
                {
                    // There was an error in parsing the collector parameters so we stop the service
                    // Logs in ServiceLog text file
                    // Stop -> OnStop -> Change service state
                    Stop();
                }
                else
                {
                    // Check if the config has 1+ Kernel collectors
                    // Check if multiple collectors are writing to the same file
                    int              KCCount    = 0;
                    Boolean          IsSamePath = false;
                    HashSet <String> CCPath     = new HashSet <String>();
                    for (int i = 0; i < CollectorConfig.Count; i++)
                    {
                        if (CollectorConfig[i].CollectorType == CollectorType.Kernel)
                        {
                            KCCount += 1;
                        }

                        if (CollectorConfig[i].OutputType == OutputType.file)
                        {
                            if (!CCPath.Add(CollectorConfig[i].Path))
                            {
                                IsSamePath = true;
                            }
                        }
                    }

                    if (KCCount > 1 | IsSamePath)
                    {
                        if (KCCount > 1)
                        {
                            SilkUtility.WriteToServiceTextLog("[!] SilkService can only support one Kernel collector..");
                        }
                        else
                        {
                            SilkUtility.WriteToServiceTextLog("[!] File based output paths must be unique..");
                        }

                        Stop();
                    }
                    else
                    {
                        // We spin up the collector threads
                        SilkUtility.WriteToServiceTextLog("[*] Starting collector threads: " + DateTime.Now);
                        foreach (CollectorParameters Collector in CollectorConfig)
                        {
                            // We create a thread for the collector
                            Thread CollectorThread = new Thread(() => {
                                try
                                {
                                    SilkUtility.WriteToServiceTextLog("    [+] GUID:     " + Collector.CollectorGUID);
                                    SilkUtility.WriteToServiceTextLog("    [>] Type:     " + Collector.CollectorType);
                                    if (Collector.CollectorType == CollectorType.User)
                                    {
                                        SilkUtility.WriteToServiceTextLog("    [>] Provider: " + Collector.ProviderName);
                                    }
                                    else
                                    {
                                        SilkUtility.WriteToServiceTextLog("    [>] Provider: " + Collector.KernelKeywords);
                                    }
                                    SilkUtility.WriteToServiceTextLog("    [>] Out Type: " + Collector.OutputType);
                                    ETWCollector.StartTrace(Collector);
                                }
                                catch (Exception ex) { SilkUtility.WriteToServiceTextLog("[!] " + ex.ToString()); }

                                // If any collectors terminate by internal error we stop the service
                                Stop();
                            });

                            // We have to mark threads as background to ensure they exit in a timely fashion
                            CollectorThread.IsBackground = false;
                            // Start the collector thread
                            CollectorThread.Start();

                            // We wait for the thread to signal and then reset the event
                            SilkUtility.SignalThreadStarted.WaitOne();
                            SilkUtility.SignalThreadStarted.Reset();
                        }
                    }
                }
            }
        }
Beispiel #3
0
        // Spin up collector threads
        public static Boolean ValidateCollectorParameters(List <CollectorParameters> Collectors)
        {
            // Loop collector configs
            for (int i = 0; i < Collectors.Count; i++)
            {
                // Assign list instance to variable
                CollectorParameters Collector = Collectors[i];

                // What type of collector are we creating?
                if (Collector.CollectorType == CollectorType.None)
                {
                    SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid CollectorType specified", true);
                    return(false);
                }
                else if (Collector.CollectorType == CollectorType.Kernel)
                {
                    if (Collector.KernelKeywords == KernelKeywords.None)
                    {
                        SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid KernelKeywords specified", true);
                        return(false);
                    }
                }
                else if (Collector.CollectorType == CollectorType.User)
                {
                    if (String.IsNullOrEmpty(Collector.ProviderName))
                    {
                        SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid ProviderName specified", true);
                        return(false);
                    }

                    // Check and convert UserKeywords to ulong
                    if (String.IsNullOrEmpty((String)Collector.UserKeywords))
                    {
                        SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid UserKeywords specified", true);
                        return(false);
                    }
                    else
                    {
                        try
                        {
                            if (((String)Collector.UserKeywords).StartsWith("0x"))
                            {
                                Collector.UserKeywords = Convert.ToUInt64((String)Collector.UserKeywords, 16);
                            }
                            else
                            {
                                Collector.UserKeywords = Convert.ToUInt64((String)Collector.UserKeywords);
                            }
                        }
                        catch
                        {
                            SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid UserKeywords mask specified", true);
                            return(false);
                        }
                    }
                }

                // Validate output parameters
                if (Collector.OutputType == OutputType.None)
                {
                    SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid OutputType specified", true);
                    return(false);
                }
                else
                {
                    if (Collector.OutputType == OutputType.file)
                    {
                        if (String.IsNullOrEmpty(Collector.Path))
                        {
                            SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid output path specified", true);
                            return(false);
                        }
                        else
                        {
                            try
                            {
                                FileAttributes CheckAttrib = File.GetAttributes(Collector.Path);
                                if (CheckAttrib.HasFlag(FileAttributes.Directory))
                                {
                                    SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Output path is a directory, not a file", true);
                                    return(false);
                                }
                            }
                            catch { }
                            if (!(Directory.Exists(System.IO.Path.GetDirectoryName(Collector.Path))))
                            {
                                SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Output path does not exist", true);
                                return(false);
                            }
                            else
                            {
                                if (!(SilkUtility.DirectoryHasPermission(System.IO.Path.GetDirectoryName(Collector.Path), System.Security.AccessControl.FileSystemRights.Write)))
                                {
                                    SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "No write access to output path", true);
                                    return(false);
                                }
                            }
                        }
                    }
                    else if (Collector.OutputType == OutputType.url)
                    {
                        if (String.IsNullOrEmpty(Collector.Path))
                        {
                            SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "No URL specified", true);
                            return(false);
                        }
                        else
                        {
                            Uri  uriResult;
                            bool UrlResult = Uri.TryCreate(Collector.Path, UriKind.Absolute, out uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
                            if (!UrlResult)
                            {
                                SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid URL specified", true);
                                return(false);
                            }
                        }
                    }
                    else if (Collector.OutputType == OutputType.eventlog)
                    {
                        Collector.Path = "SilkService-Log";
                    }
                }

                // Validate filter options
                // None, EventName, ProcessID, ProcessName, Opcode
                if (Collector.FilterOption != FilterOption.None)
                {
                    if (String.IsNullOrEmpty((String)Collector.FilterValue))
                    {
                        SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid FilterValue specified", true);
                        return(false);
                    }
                    if (Collector.FilterOption == FilterOption.ProcessID)
                    {
                        try
                        {
                            Collector.FilterValue = Convert.ToUInt32((String)Collector.FilterValue);
                        }
                        catch
                        {
                            SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid ProcessID specified", true);
                            return(false);
                        }
                    }
                    if (Collector.FilterOption == FilterOption.Opcode)
                    {
                        try
                        {
                            Collector.FilterValue = byte.Parse((String)Collector.FilterValue);
                            if ((byte)Collector.FilterValue > 9)
                            {
                                SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Opcode outside valid range (0-9)", true);
                                return(false);
                            }
                        }
                        catch
                        {
                            SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid Opcode specified", true);
                            return(false);
                        }
                    }
                    else
                    {
                        Collector.FilterValue = (String)Collector.FilterValue;
                    }
                }

                // Validate Yara folder path
                if (Collector.YaraScan != String.Empty)
                {
                    try
                    {
                        FileAttributes CheckAttrib = File.GetAttributes(Collector.YaraScan);
                        if (!(CheckAttrib.HasFlag(FileAttributes.Directory)))
                        {
                            SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "YaraScan path is not a directory", true);
                            return(false);
                        }
                        else
                        {
                            List <string> YaraRuleCollection = Directory.GetFiles(Collector.YaraScan, "*.yar", SearchOption.AllDirectories).ToList();
                            if (YaraRuleCollection.Count == 0)
                            {
                                SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "YaraScan directory does not conatin any *.yar files", true);
                                return(false);
                            }
                            else
                            {
                                // We already initialize yara for performace,
                                // new rules can not be added at runtime.
                                Collector.YaraInstance = new YSInstance();
                                Collector.YaraContext  = new YSContext();
                                Collector.YaraCompiler = Collector.YaraInstance.CompileFromFiles(YaraRuleCollection, null);
                                Collector.YaraRules    = Collector.YaraCompiler.GetRules();
                                YSReport YaraReport = Collector.YaraCompiler.GetErrors();

                                if (!(YaraReport.IsEmpty()))
                                {
                                    SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "The following yara errors were detected", true);

                                    Dictionary <string, List <string> > Errors = YaraReport.Dump();
                                    foreach (KeyValuePair <string, List <string> > Error in Errors)
                                    {
                                        SilkUtility.WriteToServiceTextLog("==> " + Error.Key);
                                        foreach (String ErrorMsg in Error.Value)
                                        {
                                            SilkUtility.WriteToServiceTextLog("    + " + ErrorMsg);
                                        }
                                    }
                                    return(false);
                                }
                            }
                        }
                    }
                    catch
                    {
                        SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid YaraScan folder path", true);
                        return(false);
                    }

                    if (Collector.YaraOptions == YaraOptions.None)
                    {
                        SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Invalid YaraOptions specified", true);
                        return(false);
                    }
                }

                // Overwrite list entry
                Collectors[i] = Collector;

                // We passed all collector parameter checks
                SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Parameter validation success", false);
            }

            // Validation complete
            return(true);
        }
Beispiel #4
0
        public static void StartTrace(CollectorParameters Collector)
        {
            Boolean WriteEventLogEntry(String Message, EventLogEntryType Type, EventIds EventId, String Path)
            {
                //--[Event ID's]
                // 0 == Collector start
                // 1 == Collector terminated -> by user
                // 2 == Collector terminated -> by error
                // 3 == Event recorded
                //--

                try
                {
                    // Event log properties
                    String Source = "ETW Collector";

                    // If the source doesn't exist we have to create it first
                    if (!EventLog.SourceExists(Source))
                    {
                        EventLog.CreateEventSource(Source, Path);
                    }

                    // Write event
                    using (EventLog Log = new EventLog(Path))
                    {
                        Log.Source           = Source;
                        Log.MaximumKilobytes = 99968;                                   // Max ~100mb size -> needs 64kb increments
                        Log.ModifyOverflowPolicy(OverflowAction.OverwriteAsNeeded, 10); // Always overwrite oldest
                        Log.WriteEntry(Message, Type, (int)EventId);
                    }
                    return(true);
                }
                catch
                {
                    return(false);
                }
            }

            int ProcessJSONEventData(String JSONData, OutputType OutputType, String Path, String YaraScan, YaraOptions YaraOptions, YSInstance YaraInstance, YSRules YaraRules)
            {
                // Yara matches
                List <String> YaraRuleMatches = new List <String>();

                // Yara options
                if (YaraScan != String.Empty)
                {
                    byte[]           JSONByteArray = Encoding.ASCII.GetBytes(JSONData);
                    List <YSMatches> Matches       = YaraInstance.ScanMemory(JSONByteArray, YaraRules, null, 0);
                    YaraRuleMatches.Clear();
                    if (Matches.Count != 0)
                    {
                        foreach (YSMatches Match in Matches)
                        {
                            YaraRuleMatches.Add(Match.Rule.Identifier);
                        }

                        // Dynamically update the JSON object -> List<String> YaraRuleMatches
                        JObject obj = JObject.Parse(JSONData);
                        ((JArray)obj["YaraMatch"]).Add(YaraRuleMatches);
                        JSONData = obj.ToString(Newtonsoft.Json.Formatting.None);
                    }
                }

                if (YaraOptions == YaraOptions.All || YaraOptions == YaraOptions.None || (YaraScan != String.Empty && YaraRuleMatches.Count > 0))
                {
                    //--[Return Codes]
                    // 0 == OK
                    // 1 == File write failed
                    // 2 == URL POST request failed
                    // 3 == Eventlog write failed
                    //--

                    // Process JSON
                    if (OutputType == OutputType.file)
                    {
                        try
                        {
                            if (!File.Exists(Path))
                            {
                                File.WriteAllText(Path, (JSONData + Environment.NewLine));
                            }
                            else
                            {
                                File.AppendAllText(Path, (JSONData + Environment.NewLine));
                            }

                            return(0);
                        }
                        catch
                        {
                            return(1);
                        }
                    }
                    else if (OutputType == OutputType.url)
                    {
                        try
                        {
                            string         responseFromServer = string.Empty;
                            HttpWebRequest webRequest         = (HttpWebRequest)WebRequest.Create(Path);
                            webRequest.Timeout     = 10000; // 10 second timeout
                            webRequest.Method      = "POST";
                            webRequest.ContentType = "application/json";
                            webRequest.Accept      = "application/json";
                            using (var streamWriter = new StreamWriter(webRequest.GetRequestStream()))
                            {
                                streamWriter.Write(JSONData);
                                streamWriter.Flush();
                                streamWriter.Close();
                            }
                            var httpResponse = (HttpWebResponse)webRequest.GetResponse();
                            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                            {
                                var result = streamReader.ReadToEnd();
                            }

                            return(0);
                        }
                        catch
                        {
                            return(2);
                        }
                    }
                    else
                    {
                        Boolean WriteEvent = WriteEventLogEntry(JSONData, EventLogEntryType.Information, EventIds.Event, Path);

                        if (WriteEvent)
                        {
                            return(0);
                        }
                        else
                        {
                            return(3);
                        }
                    }
                }
                else
                {
                    return(0);
                }
            }

            // Local variables for StartTrace
            String  EventParseSessionName;
            Boolean ProcessEventData;

            // Is elevated? While running as a service this should always be true but
            // this is kept for edge-case user-fail.
            if (TraceEventSession.IsElevated() != true)
            {
                SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "The collector must be run elevated", true);
                return;
            }

            // Print status
            SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Starting trace collector", false);

            // We tag event sessions with a unique name
            // While running these are observable with => logman -ets
            if (Collector.CollectorType == CollectorType.Kernel)
            {
                EventParseSessionName = KernelTraceEventParser.KernelSessionName;
            }
            else
            {
                String RandId = Guid.NewGuid().ToString();
                EventParseSessionName = ("SilkServiceUserCollector_" + RandId);
            }

            // Create trace session
            using (var TraceSession = new TraceEventSession(EventParseSessionName))
            {
                // The collector cannot survive process termination (safeguard)
                TraceSession.StopOnDispose = true;

                // Create event source
                using (var EventSource = new ETWTraceEventSource(EventParseSessionName, TraceEventSourceType.Session))
                {
                    // A DynamicTraceEventParser can understand how to read the embedded manifests that occur in the dataStream
                    var EventParser = new DynamicTraceEventParser(EventSource);

                    // Loop events as they arrive
                    EventParser.All += delegate(TraceEvent data)
                    {
                        // It's a bit ugly but ... ¯\_(ツ)_/¯
                        if (Collector.FilterOption != FilterOption.None)
                        {
                            if (Collector.FilterOption == FilterOption.Opcode && (byte)data.Opcode != (byte)Collector.FilterValue)
                            {
                                ProcessEventData = false;
                            }
                            else if (Collector.FilterOption == FilterOption.ProcessID && data.ProcessID != (UInt32)Collector.FilterValue)
                            {
                                ProcessEventData = false;
                            }
                            else if (Collector.FilterOption == FilterOption.ProcessName && data.ProcessName != (String)Collector.FilterValue)
                            {
                                ProcessEventData = false;
                            }
                            else if (Collector.FilterOption == FilterOption.EventName && data.EventName != (String)Collector.FilterValue)
                            {
                                ProcessEventData = false;
                            }
                            else
                            {
                                ProcessEventData = true;
                            }
                        }
                        else
                        {
                            ProcessEventData = true;
                        }

                        // Only process/serialize events if they match our filter
                        if (ProcessEventData)
                        {
                            var eRecord = new EventRecordStruct
                            {
                                ProviderGuid    = data.ProviderGuid,
                                YaraMatch       = new List <String>(),
                                ProviderName    = data.ProviderName,
                                EventName       = data.EventName,
                                Opcode          = data.Opcode,
                                OpcodeName      = data.OpcodeName,
                                TimeStamp       = data.TimeStamp,
                                ThreadID        = data.ThreadID,
                                ProcessID       = data.ProcessID,
                                ProcessName     = data.ProcessName,
                                PointerSize     = data.PointerSize,
                                EventDataLength = data.EventDataLength
                            };

                            // Populate Proc name if undefined
                            if (String.IsNullOrEmpty(eRecord.ProcessName))
                            {
                                try
                                {
                                    eRecord.ProcessName = Process.GetProcessById(eRecord.ProcessID).ProcessName;
                                }
                                catch
                                {
                                    eRecord.ProcessName = "N/A";
                                }
                            }
                            var EventProperties = new Hashtable();

                            // Try to parse event XML
                            try
                            {
                                StringReader  XmlStringContent   = new StringReader(data.ToString());
                                XmlTextReader EventElementReader = new XmlTextReader(XmlStringContent);
                                while (EventElementReader.Read())
                                {
                                    for (int AttribIndex = 0; AttribIndex < EventElementReader.AttributeCount; AttribIndex++)
                                    {
                                        EventElementReader.MoveToAttribute(AttribIndex);
                                        EventProperties.Add(EventElementReader.Name, EventElementReader.Value);
                                    }
                                }
                            }
                            catch
                            {
                                // For debugging (?), never seen this fail
                                EventProperties.Add("XmlEventParsing", "false");
                            }
                            eRecord.XmlEventData = EventProperties;

                            // Serialize to JSON
                            String JSONEventData = Newtonsoft.Json.JsonConvert.SerializeObject(eRecord);
                            int    ProcessResult = ProcessJSONEventData(JSONEventData, Collector.OutputType, Collector.Path, Collector.YaraScan, Collector.YaraOptions, Collector.YaraInstance, Collector.YaraRules);

                            // Verify that we processed the result successfully
                            if (ProcessResult != 0)
                            {
                                if (ProcessResult == 1)
                                {
                                    SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "The collector failed to write to file", true);
                                }
                                else if (ProcessResult == 2)
                                {
                                    SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "The collector failed to POST the result", true);
                                }
                                else
                                {
                                    SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "The collector failed write to the eventlog", true);
                                }

                                // Write status to eventlog if dictated by the output type
                                if (Collector.OutputType == OutputType.eventlog)
                                {
                                    WriteEventLogEntry($"{{\"Collector\":\"Stop\",\"Error\":true,\"ErrorCode\":{ProcessResult}}}", EventLogEntryType.Error, EventIds.StopError, Collector.Path);
                                }

                                // This collector encountered an error, terminate the service
                                TerminateCollector();
                            }
                        }
                    };

                    // Specify the providers details
                    if (Collector.CollectorType == CollectorType.Kernel)
                    {
                        TraceSession.EnableKernelProvider((KernelTraceEventParser.Keywords)Collector.KernelKeywords);
                    }
                    else
                    {
                        // Note that the collector doesn't know if you specified a wrong provider name,
                        // the only tell is that you won't get any events ;)
                        TraceSession.EnableProvider(Collector.ProviderName, (TraceEventLevel)Collector.UserTraceEventLevel, (ulong)Collector.UserKeywords);
                    }

                    // Write status to eventlog if dictated by the output type
                    if (Collector.OutputType == OutputType.eventlog)
                    {
                        String ConvertKeywords;
                        if (Collector.CollectorType == CollectorType.Kernel)
                        {
                            ConvertKeywords = Enum.GetName(typeof(KernelTraceEventParser.Keywords), Collector.KernelKeywords);
                        }
                        else
                        {
                            ConvertKeywords = "0x" + String.Format("{0:X}", (ulong)Collector.UserKeywords);
                        }
                        String Message = $"{{\"Collector\":\"Start\",\"Data\":{{\"Type\":\"{Collector.CollectorType}\",\"Provider\":\"{Collector.ProviderName}\",\"Keywords\":\"{ConvertKeywords}\",\"FilterOption\":\"{Collector.FilterOption}\",\"FilterValue\":\"{Collector.FilterValue}\",\"YaraPath\":\"{Collector.YaraScan}\",\"YaraOption\":\"{Collector.YaraOptions}\"}}}}";
                        WriteEventLogEntry(Message, EventLogEntryType.SuccessAudit, EventIds.Start, Collector.Path);
                    }

                    // Populate the trace bookkeeper
                    var CollectorInstance = new CollectorInstance
                    {
                        CollectorGUID         = Collector.CollectorGUID,
                        EventSource           = EventSource,
                        EventParseSessionName = EventParseSessionName,
                    };
                    SilkUtility.CollectorTaskList.Add(CollectorInstance);

                    // Signal the ManualResetEvent
                    SilkUtility.SignalThreadStarted.Set();

                    // Continuously process all new events in the data source
                    EventSource.Process();

                    void TerminateCollector()
                    {
                        EventSource.StopProcessing();
                        TraceSession?.Stop();
                        SilkUtility.WriteCollectorGuidMessageToServiceTextLog(Collector.CollectorGUID, "Collector terminated", false);
                        return;
                    }
                }
            }
        }
Beispiel #5
0
        // Parse SilkService XML config
        public static List <CollectorParameters> ReadXmlConfig()
        {
            // Load config
            String   ConfigPath    = AppDomain.CurrentDomain.BaseDirectory + "\\SilkServiceConfig.xml";
            XElement XmlConfigFile = null;

            try
            {
                XmlConfigFile = XElement.Load(ConfigPath);
            } catch
            {
                SilkUtility.WriteToServiceTextLog("[!] SilkServiceConfig.xml configuration file invalid or not found");
                return(SilkUtility.SilkServiceParameterSets);
            }

            // Define XML elements
            XName CI   = XName.Get("ETWCollector");
            XName CG   = XName.Get("Guid");
            XName CT   = XName.Get("CollectorType");
            XName KK   = XName.Get("KernelKeywords");
            XName OT   = XName.Get("OutputType");
            XName P    = XName.Get("Path");
            XName PN   = XName.Get("ProviderName");
            XName UTEL = XName.Get("UserTraceEventLevel");
            XName UK   = XName.Get("UserKeywords");
            XName FO   = XName.Get("FilterOption");
            XName FV   = XName.Get("FilterValue");
            XName YS   = XName.Get("YaraScan");
            XName YO   = XName.Get("YaraOptions");

            // Initialize result struct
            var CollectorParamInstance = new CollectorParameters();

            // Loop ETWCollector elements
            try
            {
                foreach (XElement Collector in XmlConfigFile.Elements(CI))
                {
                    XElement ParamContainer;

                    // Loop all possible params
                    try // (1) --> CollectorGUID, ID of the the collector instance for internal tracking
                    {
                        ParamContainer = Collector.Element(CG);
                        Guid EnumContainer;
                        if (Guid.TryParse(ParamContainer.Value, out EnumContainer))
                        {
                            CollectorParamInstance.CollectorGUID = EnumContainer;
                        }
                        else
                        {
                            CollectorParamInstance.CollectorGUID = Guid.Empty;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.CollectorGUID = Guid.Empty;
                    }
                    try // (2) --> CollectorType
                    {
                        ParamContainer = Collector.Element(CT);
                        CollectorType EnumContainer;
                        if (Enum.TryParse(ParamContainer.Value, true, out EnumContainer))
                        {
                            CollectorParamInstance.CollectorType = EnumContainer;
                        }
                        else
                        {
                            CollectorParamInstance.CollectorType = CollectorType.None;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.CollectorType = CollectorType.None;
                    }
                    try // (3) --> KernelKeywords
                    {
                        ParamContainer = Collector.Element(KK);
                        KernelKeywords EnumContainer;
                        if (Enum.TryParse(ParamContainer.Value, true, out EnumContainer))
                        {
                            CollectorParamInstance.KernelKeywords = EnumContainer;
                        }
                        else
                        {
                            CollectorParamInstance.KernelKeywords = KernelKeywords.None;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.KernelKeywords = KernelKeywords.None;
                    }
                    try // (4) --> OutputType
                    {
                        ParamContainer = Collector.Element(OT);
                        OutputType EnumContainer;
                        if (Enum.TryParse(ParamContainer.Value, true, out EnumContainer))
                        {
                            CollectorParamInstance.OutputType = EnumContainer;
                        }
                        else
                        {
                            CollectorParamInstance.OutputType = OutputType.None;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.OutputType = OutputType.None;
                    }
                    try // (5) --> Path
                    {
                        ParamContainer = Collector.Element(P);
                        if (!String.IsNullOrEmpty(ParamContainer.Value))
                        {
                            CollectorParamInstance.Path = ParamContainer.Value;
                        }
                        else
                        {
                            CollectorParamInstance.Path = String.Empty;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.Path = String.Empty;
                    }
                    try // (6) --> ProviderName
                    {
                        ParamContainer = Collector.Element(PN);
                        if (!String.IsNullOrEmpty(ParamContainer.Value))
                        {
                            CollectorParamInstance.ProviderName = ParamContainer.Value;
                        }
                        else
                        {
                            CollectorParamInstance.ProviderName = String.Empty;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.ProviderName = String.Empty;
                    }
                    try // (7) --> UserTraceEventLevel
                    {
                        ParamContainer = Collector.Element(UTEL);
                        UserTraceEventLevel EnumContainer;
                        if (Enum.TryParse(ParamContainer.Value, true, out EnumContainer))
                        {
                            CollectorParamInstance.UserTraceEventLevel = EnumContainer;
                        }
                        else
                        {
                            CollectorParamInstance.UserTraceEventLevel = UserTraceEventLevel.Informational;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.UserTraceEventLevel = UserTraceEventLevel.Informational;
                    }
                    try // (8) --> UserKeywords
                    {
                        ParamContainer = Collector.Element(UK);
                        if (!String.IsNullOrEmpty(ParamContainer.Value))
                        {
                            CollectorParamInstance.UserKeywords = ParamContainer.Value;
                        }
                        else
                        {
                            CollectorParamInstance.UserKeywords = "0xffffffffffffffff";
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.UserKeywords = "0xffffffffffffffff";
                    }
                    try // (9) --> FilterOption
                    {
                        ParamContainer = Collector.Element(FO);
                        FilterOption EnumContainer;
                        if (Enum.TryParse(ParamContainer.Value, true, out EnumContainer))
                        {
                            CollectorParamInstance.FilterOption = EnumContainer;
                        }
                        else
                        {
                            CollectorParamInstance.FilterOption = FilterOption.None;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.FilterOption = FilterOption.None;
                    }
                    try // (10) --> FilterValue
                    {
                        ParamContainer = Collector.Element(FV);
                        if (!String.IsNullOrEmpty(ParamContainer.Value))
                        {
                            CollectorParamInstance.FilterValue = ParamContainer.Value;
                        }
                        else
                        {
                            CollectorParamInstance.FilterValue = String.Empty;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.FilterValue = String.Empty;
                    }
                    try // (11) --> YaraScan
                    {
                        ParamContainer = Collector.Element(YS);
                        if (!String.IsNullOrEmpty(ParamContainer.Value))
                        {
                            CollectorParamInstance.YaraScan = ParamContainer.Value;
                        }
                        else
                        {
                            CollectorParamInstance.YaraScan = String.Empty;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.YaraScan = String.Empty;
                    }
                    try // (12) --> YaraOptions
                    {
                        ParamContainer = Collector.Element(YO);
                        YaraOptions EnumContainer;
                        if (Enum.TryParse(ParamContainer.Value, true, out EnumContainer))
                        {
                            CollectorParamInstance.YaraOptions = EnumContainer;
                        }
                        else
                        {
                            CollectorParamInstance.YaraOptions = YaraOptions.None;
                        }
                    }
                    catch
                    {
                        CollectorParamInstance.YaraOptions = YaraOptions.None;
                    }

                    // Add result to ouput object
                    SilkUtility.SilkServiceParameterSets.Add(CollectorParamInstance);
                }
            }
            catch
            {
                SilkUtility.WriteToServiceTextLog("[!] Parsing error encountered while processing SilkService XML configuration file");
            }

            if (SilkUtility.SilkServiceParameterSets.Count == 0)
            {
                SilkUtility.WriteToServiceTextLog("[!] SilkService XML configuration file did not contain any ETWCollector elements");
            }

            return(SilkUtility.SilkServiceParameterSets);
        }