static void Main(string[] args) { // Get list of yara rules string[] ruleFiles = Directory.GetFiles(@"e:\yara-db\rules\", "*.yara", SearchOption.AllDirectories) .ToArray(); // Get list of samples to check string[] samples = new[] { @"e:\malware-samples\", // directory @"e:\speficic-samples\sample1.exe" // file }; // Initialize yara context using (YaraContext ctx = new YaraContext()) { // Compile list of yara rules CompiledRules rules = null; using (var compiler = new Compiler()) { foreach (var yara in ruleFiles) { compiler.AddRuleFile(yara); } rules = compiler.Compile(); Console.WriteLine($"* Compiled"); } if (rules != null) { // Initialize the scanner var scanner = new Scanner(); // Go through all samples foreach (var sample in samples) { // If item is file, scan the file if (File.Exists(sample)) { ScanFile(scanner, sample, rules); } // If item is directory, scan the directory else { if (Directory.Exists(sample)) { DirectoryInfo dirInfo = new DirectoryInfo(sample); foreach (FileInfo fi in dirInfo.EnumerateFiles("*", SearchOption.AllDirectories)) { ScanFile(scanner, fi.FullName, rules); } } } } } } }
public void CheckStringNotMatchTest() { // Initialize yara context using (YaraContext ctx = new YaraContext()) { // Compile yara rules CompiledRules rules = null; using (var compiler = new Compiler()) { compiler.AddRuleString("rule foo: bar {strings: $a = \"nml\" condition: $a}"); rules = compiler.Compile(); } if (rules != null) { // Initialize the scanner var scanner = new Scanner(); List <ScanResult> scanResult = scanner.ScanString("abcdefgjiklmnoprstuvwxyz", rules); Assert.True(scanResult.Count == 0); } } }
public void CheckMemoryNotMatchTest() { // Initialize yara context using (YaraContext ctx = new YaraContext()) { // Compile yara rules CompiledRules rules = null; using (var compiler = new Compiler()) { compiler.AddRuleString("rule foo: bar {strings: $a = \"nml\" condition: $a}"); rules = compiler.Compile(); } if (rules != null) { // Initialize the scanner var scanner = new Scanner(); Encoding encoding = Encoding.ASCII; byte[] buffer = encoding.GetBytes("abcdefgjiklmnoprstuvwxyz"); List <ScanResult> scanResult = scanner.ScanMemory(ref buffer, rules); Assert.True(scanResult.Count == 0); } } }
public void CheckExternalVariableRuleTest() { // Initialize yara context using (YaraContext ctx = new YaraContext()) { using (var compiler = new Compiler()) { //must declare this or the compiler will complain it doesn't exist when a rule references it compiler.DeclareExternalStringVariable("filename"); //declare rule with an external variable available compiler.AddRuleString("rule foo: bar {strings: $a = \"lmn\" condition: $a and filename matches /\\.txt$/is}"); CompiledRules compiledRules = compiler.Compile(); Assert.True(compiledRules.RuleCount == 1); Encoding encoding = Encoding.ASCII; byte[] buffer = encoding.GetBytes("abcdefgjiklmnoprstuvwxyz"); // Initialize a customscanner we can add variables to var scanner = new CustomScanner(compiledRules); ExternalVariables externalVariables = new ExternalVariables(); externalVariables.StringVariables.Add("filename", "Alphabet.txt"); List <ScanResult> compiledScanResults = scanner.ScanMemory(ref buffer, externalVariables); Assert.True(compiledScanResults.Count == 1); Assert.Equal("foo", compiledScanResults[0].MatchingRule.Identifier); //release before falling out of the yara context scanner.Release(); } } }
static void Main(string[] args) { using (var ctx = new YaraContext()) { Console.WriteLine("# Welcome to Yara Interactive Console..."); while (true) { Console.Write("> "); string command = Console.ReadLine(); if (string.IsNullOrWhiteSpace(command)) { continue; } bool isManagedCmd = CmdHandler.ExecuteCmd(command); if (!isManagedCmd) { Console.WriteLine(":Err: Unknown command..."); } } } }
public static Dictionary <string, ulong> YaraScanFile(string fileName) { Dictionary <string, ulong> beaconScanMatches = new Dictionary <string, ulong>(); using (var ctx = new YaraContext()) { Rules rules = null; try { using (Compiler compiler = new Compiler()) { // Retrieve YARA rules from YaraRules static class and compile them for scanning foreach (string rule in YaraRules.meterpreterRules) { compiler.AddRuleString(rule); } compiler.AddRuleString(YaraRules.cobaltStrikeRule); rules = compiler.GetRules(); } // Scanner and ScanResults do not need to be disposed. var scanner = new Scanner(); var results = scanner.ScanFile(fileName, rules); foreach (ScanResult result in results) { if (result.MatchingRule.Identifier.Contains("CobaltStrike")) { // Get Version 3 match - find the first occurrence of the config string if (result.Matches.ContainsKey(v3)) { beaconScanMatches.Add(v3, result.Matches[v3][0].Offset); } // Get Version 4 match if (result.Matches.ContainsKey(v4)) { beaconScanMatches.Add(v4, result.Matches[v4][0].Offset); } } } } finally { // Rules and Compiler objects must be disposed. if (rules != null) { rules.Dispose(); } } return(beaconScanMatches); } }
/// <summary> /// Perform YARA scan on process memory to detect meterpreter or Cobalt Strike payloads. /// </summary> /// <param name="processBytes">Byte array of target process to be scanned</param> public static Dictionary <string, ulong> YaraScanBytes(byte[] processBytes) { Dictionary <string, ulong> beaconScanMatches = new Dictionary <string, ulong>(); using (var ctx = new YaraContext()) { Rules rules = null; try { using (Compiler compiler = new Compiler()) { // Retrieve YARA rules from YaraRules static class and compile them for scanning foreach (string rule in YaraRules.meterpreterRules) { compiler.AddRuleString(rule); } compiler.AddRuleString(YaraRules.cobaltStrikeRule); rules = compiler.GetRules(); } // Perform scan on process memory byte[] Scanner scanner = new Scanner(); var results = scanner.ScanMemory(processBytes, rules); // Check for rule matches in process bytes foreach (ScanResult result in results) { if (result.MatchingRule.Identifier.Contains("CobaltStrike")) { // Get Version 3 match - find the first occurrence of the config string if (result.Matches.ContainsKey(v3)) { beaconScanMatches.Add(v3, result.Matches[v3][0].Offset); } // Get Version 4 match if (result.Matches.ContainsKey(v4)) { beaconScanMatches.Add(v4, result.Matches[v4][0].Offset); } } } } finally { if (rules != null) { rules.Dispose(); } } return(beaconScanMatches); } }
/// <summary> /// Create a Yara scanner /// </summary> /// <param name="rulesDir">Directory of YARA rules</param> public YARAScanner(string rulesDir) { ctx = new YaraContext(); ctx.GetType(); //prevent a 'this is never read' warning. It needs to be created and stay in memory but we dont reference it if (!CheckLibraryExists()) { throw new DllNotFoundException("libyara.dll not available"); } RefreshRules(rulesDir); }
/*~DetectWithYara() * { * if(_compiledRules != null) * _compiledRules.Dispose(); * }*/ #endregion #region Methods /// <summary> /// Loads yara rules and run tests /// </summary> private void LoadYaraRules() { //Load rules from files this._yaraRules = Directory.GetFiles(this._pathToRules, "*.yara", SearchOption.AllDirectories).ToArray(); this._results.Clear(); try { using (var ctx = new YaraContext()) { Rules rules = null; // Rules and Compiler objects must be disposed. using (var compiler = new Compiler()) { //string path = Path.Combine(this._pathToRules, "packer.yara"); foreach (var path in _yaraRules) { //Console.WriteLine(path); compiler.AddRuleFile(path); } rules = compiler.GetRules(); } // Scanner and ScanResults do not need to be disposed. var scanner = new Scanner(); var results = scanner.ScanFile(this._filename, rules); foreach (var a in results) { //Console.WriteLine(a.MatchingRule.Identifier); this._results.Add(a.MatchingRule.Identifier.ToString()); } // Rules and Compiler objects must be disposed. if (rules != null) { rules.Dispose(); } } } catch (Exception e) { Debug.WriteLine(e.ToString()); } }
/// <summary> /// Perform YARA scan on process memory to detect meterpreter or Cobalt Strike payloads. /// </summary> /// <param name="processBytes">Byte array of target process to be scanned</param> public static List <BeaconMatch> YaraScanBytes(byte[] processBytes) { List <BeaconMatch> beaconScanMatches = new List <BeaconMatch>(); using (var ctx = new YaraContext()) { Rules rules = null; try { using (Compiler compiler = new Compiler()) { // Retrieve YARA rules from YaraRules static class and compile them for scanning /* * foreach (string rule in YaraRules.meterpreterRules) * { * compiler.AddRuleString(rule); * } */ compiler.AddRuleString(YaraRules.cobaltStrikeRule); rules = compiler.GetRules(); } // Perform scan on process memory byte[] Scanner scanner = new Scanner(); var results = scanner.ScanMemory(processBytes, rules); beaconScanMatches = ParseScanResults(results); } finally { if (rules != null) { rules.Dispose(); } } return(beaconScanMatches); } }
public static void CleanUp() { if (_yaraCompiledRulesDictionary.Any()) { List <Rules> rules = _yaraCompiledRulesDictionary.Values.ToList(); foreach (Rules r in rules) { r.Dispose(); } _yaraCompiledRulesDictionary.Clear(); _yaraCompiledRulesDictionary = null; } if (_yaraContext != null) { _yaraContext.Dispose(); _yaraContext = null; } }
public void CheckSaveLoadRuleTest() { // Initialize yara context using (YaraContext ctx = new YaraContext()) { using (var compiler = new Compiler()) { compiler.AddRuleString("rule foo: bar {strings: $a = \"lmn\" condition: $a}"); CompiledRules compiledRules = compiler.Compile(); Assert.True(compiledRules.RuleCount == 1); Encoding encoding = Encoding.ASCII; byte[] buffer = encoding.GetBytes("abcdefgjiklmnoprstuvwxyz"); // Initialize the scanner var scanner = new Scanner(); List <ScanResult> compiledScanResults = scanner.ScanMemory(ref buffer, compiledRules); Assert.True(compiledScanResults.Count == 1); Assert.Equal("foo", compiledScanResults[0].MatchingRule.Identifier); //save the rule to disk string tempfile = System.IO.Path.GetTempFileName(); bool saved = compiledRules.Save(tempfile); Assert.True(saved); //load the saved rule to a new ruleset CompiledRules loadedRules = new CompiledRules(tempfile); List <ScanResult> loadedScanResults = scanner.ScanMemory(ref buffer, loadedRules); Assert.True(loadedScanResults.Count == 1); Assert.Equal("foo", loadedScanResults[0].MatchingRule.Identifier); System.IO.File.Delete(tempfile); } } }
static void Main(string[] args) { // Use the QuickScan class when you don't need to reuse rules // or other yara objects. QuickScan handles all of the resource // management including the YaraContext. // var results = QuickScan.File(".\\SampleFile.txt", ".\\HelloWorldRules.yara"); // When you need to reuse yara objects (e.g. when scanning multiple files) it's // more efficient to use the pattern below. Note that all yara operations must // take place within the scope of a YaraContext. using (var ctx = new YaraContext()) { Rules rules = null; try { // Rules and Compiler objects must be disposed. using (var compiler = new Compiler()) { compiler.AddRuleFile(".\\HelloWorldRules.yara"); rules = compiler.GetRules(); } // Scanner and ScanResults do not need to be disposed. var scanner = new Scanner(); var results = scanner.ScanFile(".\\SampleFile.txt", rules); } finally { // Rules and Compiler objects must be disposed. if (rules != null) { rules.Dispose(); } } } }
public void CheckIterateRulesTest() { string ruleText = @"rule foo: bar { meta: bool_meta = true int_meta = 10 string_meta = ""what a long, drawn-out thing this is!"" strings: $a = ""nml"" condition: $a }"; // Initialize yara context using (YaraContext ctx = new YaraContext()) { // Compile yara rules CompiledRules rules = null; using (var compiler = new Compiler()) { compiler.AddRuleString(ruleText); rules = compiler.Compile(); } if (rules != null) { var rule = rules.Rules.ToList()[0]; Assert.NotEmpty(rules.Rules); Assert.Equal("foo", rule.Identifier); Assert.Equal("bar", rule.Tags[0]); Assert.Equal(true, rule.Metas["bool_meta"]); Assert.Equal((long)10, rule.Metas["int_meta"]); Assert.Equal("what a long, drawn-out thing this is!", rule.Metas["string_meta"]); } } }
public List <ScanResult> YaraScan(string RulesFile, bool IncludeData = false, bool KernelSpace = false) { var rv = new List <ScanResult>(); using (var ctx = new YaraContext()) { Rules rules = null; try { // Rules and Compiler objects must be disposed. using (var compiler = new Compiler()) { compiler.AddRuleFile(RulesFile); rules = compiler.GetRules(); } PageTable.AddProcess(this, MemAccess); //var cnt = PT.FillPageQueue(false, KernelSpace); var curr = 0; YaraTotalScanned = 0; // single threaded worked best so far //Parallel.For(0, cnt, (i, loopState) => x foreach (var range in PT.FillPageQueue(false, KernelSpace, true, false)) //for (int i = 0; i < cnt; i++) { curr++; if (Vtero.VerboseLevel > 1) { //var curr = cnt - PT.PageQueue.Count; //var done = Convert.ToDouble(curr) / Convert.ToDouble(cnt) * 100.0; Console.CursorLeft = 0; Console.Write($"{curr} scanned"); } if (range.PTE.Valid) { // skip data as requested if (!IncludeData && range.PTE.NoExecute) { continue; } // Scanner and ScanResults do not need to be disposed. var scanner = new libyaraNET.Scanner(); unsafe { long[] block = null; bool GotData = false; if (range.PTE.LargePage) { block = new long[0x40000]; } else { block = new long[0x200]; } MemAccess.GetPageForPhysAddr(range.PTE, ref block, ref GotData); if (GotData) { fixed(void *lp = block) { var res = scanner.ScanMemory((byte *)lp, block.Length, rules, ScanFlags.None); rv.AddRange(res); YaraTotalScanned += block.Length; } } } } } } finally { // Rules and Compiler objects must be disposed. if (rules != null) { rules.Dispose(); } } } YaraOutput = rv; return(YaraOutput); }
public void before_each() { ctx = new YaraContext(); compiler = new Compiler(); }
static FileProperties() { _yaraContext = new YaraContext(); _yaraCompiledRulesDictionary = new Dictionary <string, Rules>(); }
public static List <BeaconMatch> YaraScanFile(string fileName, bool verbose) { List <BeaconMatch> beaconScanMatches = new List <BeaconMatch>(); using (var ctx = new YaraContext()) { Rules rules = null; try { using (Compiler compiler = new Compiler()) { // Retrieve YARA rules from YaraRules static class and compile them for scanning foreach (string rule in YaraRules.meterpreterRules) { compiler.AddRuleString(rule); } compiler.AddRuleString(YaraRules.cobaltStrikeRule); rules = compiler.GetRules(); } // Scanner and ScanResults do not need to be disposed. var scanner = new Scanner(); List <ScanResult> results = new List <ScanResult>(); // If file size > 2GB, stream the file and use ScanMemory() on file chunks rather than reading the whole file via if (new FileInfo(fileName).Length < Int32.MaxValue) { results.AddRange(scanner.ScanFile(fileName, rules)); } else { using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { // Parse the file in 200MB chunks int chunkSize = 1024 * 1024 * 200; byte[] chunk = new byte[chunkSize]; int bytesRead = 0; long bytesToRead = fileStream.Length; while (bytesToRead != 0) { int n = fileStream.Read(chunk, 0, chunkSize); if (n == 0) { break; } // Yara scan the file chunk and add any results to the list var scanResults = scanner.ScanMemory(chunk, rules); // Because the file is being scanned in chunks, match offsets are based on the start of the chunk. Need to add // previous bytes read to the current match offsets if (scanResults.Count > 0) { foreach (ScanResult result in scanResults) { if (result.MatchingRule.Identifier.Contains("CobaltStrike")) { foreach (string key in result.Matches.Keys) { result.Matches[key][0].Offset += (ulong)bytesRead; } results.Add(result); } } } bytesRead += n; bytesToRead -= n; // Shitty progress update if (verbose && bytesRead > 0 && bytesRead <= fileStream.Length) { Console.Write($"\r\tScanned {bytesRead} bytes of {fileStream.Length} byte file..."); } } } if (verbose) { Console.WriteLine($"\r\tFinished scanning file: {fileName}\t\t\t"); } } beaconScanMatches = ParseScanResults(results); } finally { // Rules and Compiler objects must be disposed. if (rules != null) { rules.Dispose(); } } return(beaconScanMatches); } }