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] Загрузка завершена"); }
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)); }
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); } }
// 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); }