示例#1
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }
示例#2
0
        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);
                }
            }
        }
示例#3
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);
                }
            }
        }
示例#4
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();
                }
            }
        }
示例#5
0
        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);
            }
        }
示例#8
0
        /// <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);
        }
示例#9
0
        /*~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());
            }
        }
示例#10
0
        /// <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;
            }
        }
示例#12
0
        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);
                }
            }
        }
示例#13
0
        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();
                    }
                }
            }
        }
示例#14
0
        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"]);
                }
            }
        }
示例#15
0
        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);
        }
示例#16
0
 public void before_each()
 {
     ctx      = new YaraContext();
     compiler = new Compiler();
 }
 static FileProperties()
 {
     _yaraContext = new YaraContext();
     _yaraCompiledRulesDictionary = new Dictionary <string, Rules>();
 }
示例#18
0
        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);
            }
        }