Example #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);
        }
Example #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();
                        }
                    }
                }
            }
        }
Example #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);
        }
Example #4
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);
        }