Пример #1
0
        public static void Init()
        {
            Connector.Logger.WriteLine("[YaraIntegration.Init] Start");

            Instance = new YSInstance();

            Dictionary <string, object> externals = new Dictionary <string, object>()
            {
                { "filename", string.Empty },
                { "filepath", string.Empty },
                { "extension", string.Empty }
            };

            Connector.Logger.WriteLine("[YaraIntegration.Init] Загрука YARA правил");

            List <string> ruleFilenames = Directory.GetFiles(MODULE__SCAN.Configuration.YaraRulesDir, "*.yar", MODULE__SCAN.Configuration.YaraRulesSearchOption).ToList();

            Connector.Logger.WriteLine($"[YaraIntegration.Init] Загружено {ruleFilenames.Count} файлов ");

            Context  = new YSContext();
            Compiler = Instance.CompileFromFiles(ruleFilenames, externals);

            Rules    = Compiler.GetRules();
            Errors   = Compiler.GetErrors();
            Warnings = Compiler.GetWarnings();

            var ErrDump = Errors.Dump();
            var WrnDump = Warnings.Dump();

            foreach (var key in ErrDump)
            {
                Connector.Logger.WriteLine($"[YaraIntegration.Init] Error!");
            }

            foreach (var key in WrnDump)
            {
                Connector.Logger.WriteLine($"[YaraIntegration.Init] Warning!");
            }

            Connector.Logger.WriteLine($"[YaraIntegration.Init] Загрузка завершена");
        }
Пример #2
0
        public static YSScanner CompileRules(List <string> yaraRuleFiles, Action <string> loggingFunction)
        {
            YSRules result = null;

            using (YSCompiler compiler = _yaraInstance.CompileFromFiles(yaraRuleFiles, null))
            {
                string yaraWarnings = string.Empty;
                string yaraErrors   = string.Empty;

                YSReport warnings = compiler.GetWarnings();
                if (!warnings.IsEmpty())
                {
                    yaraWarnings = string.Join(Environment.NewLine,
                                               warnings.Dump().Select(kvp => $"{kvp.Key}:" + Environment.NewLine + string.Join(Environment.NewLine + "\t", kvp.Value)));
                }

                if (!string.IsNullOrWhiteSpace(yaraWarnings))
                {
                    loggingFunction.Invoke("YARA reported warnings.");
                    loggingFunction.Invoke(yaraWarnings);
                    loggingFunction.Invoke("");
                }

                YSReport errors = compiler.GetErrors();
                if (!errors.IsEmpty())
                {
                    yaraErrors = string.Join(Environment.NewLine,
                                             errors.Dump().Select(kvp => $"{kvp.Key}:" + Environment.NewLine + string.Join(Environment.NewLine + "\t", kvp.Value)));
                    yaraErrors += Environment.NewLine;
                }

                if (!string.IsNullOrWhiteSpace(yaraErrors))
                {
                    throw new Exception("YARA reported errors compiling rules:" + Environment.NewLine + yaraErrors);
                }

                result = compiler.GetRules();
            }

            return(new YSScanner(result, null));
        }
Пример #3
0
        private void OnExecute()
        {
            // Print custom help
            if (Help)
            {
                SilkUtility.PrintHelp();
                return;
            }

            // Print trivia
            if (Trivia)
            {
                SilkUtility.PrintTrivia();
                return;
            }

            // What type of collector are we creating?
            if (CollectorType == CollectorType.None)
            {
                SilkUtility.ReturnStatusMessage("[!] Select valid collector type (-t|--type)", ConsoleColor.Red);
                return;
            }
            else if (CollectorType == CollectorType.Kernel)
            {
                if (KernelKeywords == KernelKeywords.None)
                {
                    SilkUtility.ReturnStatusMessage("[!] Select valid Kernel keyword (-kk|--kernelkeyword)", ConsoleColor.Red);
                    return;
                }
            }
            else if (CollectorType == CollectorType.User)
            {
                if (String.IsNullOrEmpty(ProviderName))
                {
                    SilkUtility.ReturnStatusMessage("[!] Specify valid provider name (-pn|--providername)", ConsoleColor.Red);
                    return;
                }

                // Check and convert UserKeywords to ulong
                if (String.IsNullOrEmpty(UserKeywords))
                {
                    SilkUtility.ReturnStatusMessage("[!] Specify valid keywords mask (-uk|--userkeyword)", ConsoleColor.Red);
                    return;
                }
                else
                {
                    try
                    {
                        if (UserKeywords.StartsWith("0x"))
                        {
                            SilkUtility.UlongUserKeywords = Convert.ToUInt64(UserKeywords, 16);
                        }
                        else
                        {
                            SilkUtility.UlongUserKeywords = Convert.ToUInt64(UserKeywords);
                        }
                    }
                    catch
                    {
                        SilkUtility.ReturnStatusMessage("[!] Specify valid keywords mask (-uk|--userkeyword)", ConsoleColor.Red);
                        return;
                    }
                }
            }

            // Validate output parameters
            if (OutputType == OutputType.None)
            {
                SilkUtility.ReturnStatusMessage("[!] Select valid output type (-ot|--outputtype)", ConsoleColor.Red);
                return;
            }
            else
            {
                if (OutputType == OutputType.file)
                {
                    if (String.IsNullOrEmpty(Path))
                    {
                        SilkUtility.ReturnStatusMessage("[!] Specify valid output file (-p|--path)", ConsoleColor.Red);
                        return;
                    }
                    else
                    {
                        try
                        {
                            FileAttributes CheckAttrib = File.GetAttributes(Path);
                            if (CheckAttrib.HasFlag(FileAttributes.Directory))
                            {
                                SilkUtility.ReturnStatusMessage("[!] Specify an output filepath not a directory (-p|--path)", ConsoleColor.Red);
                                return;
                            }
                        }
                        catch { }
                        if (!(Directory.Exists(System.IO.Path.GetDirectoryName(Path))))
                        {
                            SilkUtility.ReturnStatusMessage("[!] Invalid path specified (-p|--path)", ConsoleColor.Red);
                            return;
                        }
                        else
                        {
                            if (!(SilkUtility.DirectoryHasPermission(System.IO.Path.GetDirectoryName(Path), System.Security.AccessControl.FileSystemRights.Write)))
                            {
                                SilkUtility.ReturnStatusMessage("[!] No write access to output path (-p|--path)", ConsoleColor.Red);
                                return;
                            }
                        }
                    }
                }
                else
                {
                    if (String.IsNullOrEmpty(Path))
                    {
                        SilkUtility.ReturnStatusMessage("[!] Specify valid URL (-p|--path)", ConsoleColor.Red);
                        return;
                    }
                    else
                    {
                        Uri  uriResult;
                        bool UrlResult = Uri.TryCreate(Path, UriKind.Absolute, out uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
                        if (!UrlResult)
                        {
                            SilkUtility.ReturnStatusMessage("[!] Invalid URL specified (-p|--path)", ConsoleColor.Red);
                            return;
                        }
                    }
                }
            }

            // Validate filter options
            // None, EventName, ProcessID, ProcessName, Opcode
            if (FilterOption != FilterOption.None)
            {
                if (String.IsNullOrEmpty(FilterValue))
                {
                    SilkUtility.ReturnStatusMessage("[!] Specify a valid filter value (-fv|--filtervalue) in conjunction with -f", ConsoleColor.Red);
                    return;
                }
                if (FilterOption == FilterOption.ProcessID)
                {
                    try
                    {
                        SilkUtility.FilterValueObject = Convert.ToUInt32(FilterValue);
                    }
                    catch
                    {
                        SilkUtility.ReturnStatusMessage("[!] Specify a valid ProcessID", ConsoleColor.Red);
                        return;
                    }
                }
                else if (FilterOption == FilterOption.Opcode)
                {
                    try
                    {
                        SilkUtility.FilterValueObject = byte.Parse(FilterValue);
                        if ((byte)SilkUtility.FilterValueObject > 9)
                        {
                            SilkUtility.ReturnStatusMessage("[!] Opcode outside valid range (0-9)", ConsoleColor.Red);
                            return;
                        }
                    }
                    catch
                    {
                        SilkUtility.ReturnStatusMessage("[!] Specify a valid Opcode", ConsoleColor.Red);
                        return;
                    }
                }
                else
                {
                    SilkUtility.FilterValueObject = FilterValue;
                }
            }

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

                            if (!(YaraReport.IsEmpty()))
                            {
                                SilkUtility.ReturnStatusMessage("[!] The following yara errors were detected (-y|--yara)", ConsoleColor.Red);

                                Dictionary <string, List <string> > Errors = YaraReport.Dump();
                                foreach (KeyValuePair <string, List <string> > Error in Errors)
                                {
                                    SilkUtility.ReturnStatusMessage("==> " + Error.Key, ConsoleColor.Yellow);
                                    foreach (String ErrorMsg in Error.Value)
                                    {
                                        SilkUtility.ReturnStatusMessage("    + " + ErrorMsg, ConsoleColor.Yellow);
                                    }
                                }
                                return;
                            }
                        }
                    }
                }
                catch
                {
                    SilkUtility.ReturnStatusMessage("[!] Specify a valid yara rule folder path (-y|--yara)", ConsoleColor.Red);
                    return;
                }

                if (YaraOptions == YaraOptions.None)
                {
                    SilkUtility.ReturnStatusMessage("[!] Specify a valid yara option (-yo|--yaraoptions)", ConsoleColor.Red);
                    return;
                }
            }

            // We passed all collector parameter checks
            SilkUtility.ReturnStatusMessage("[+] Collector parameter validation success..", ConsoleColor.Green);

            // Launch the collector
            if (CollectorType == CollectorType.Kernel)
            {
                ETWCollector.StartTrace(CollectorType, (ulong)KernelKeywords, OutputType, Path, FilterOption, SilkUtility.FilterValueObject, YaraScan, YaraOptions);
            }
            else
            {
                ETWCollector.StartTrace(CollectorType, SilkUtility.UlongUserKeywords, OutputType, Path, FilterOption, SilkUtility.FilterValueObject, YaraScan, YaraOptions, ProviderName, UserTraceEventLevel);
            }
        }
Пример #4
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);
        }