Beispiel #1
0
        public ActionResult StartMonitoring(string RunId, string Directory)
        {
            if (RunId != null)
            {
                if (DatabaseManager.GetRun(RunId) != null)
                {
                    return(Json(ASA_ERROR.UNIQUE_ID));
                }

                var run = new AsaRun(RunId: RunId, Timestamp: DateTime.Now, Version: AsaHelpers.GetVersionString(), Platform: AsaHelpers.GetPlatform(), new List <RESULT_TYPE>()
                {
                    RESULT_TYPE.FILEMONITOR
                }, RUN_TYPE.MONITOR);
                DatabaseManager.InsertRun(run);

                MonitorCommandOptions opts = new MonitorCommandOptions
                {
                    RunId = RunId,
                    EnableFileSystemMonitor = true,
                    MonitoredDirectories    = Directory,
                    Verbose = Logger.Verbose,
                    Debug   = Logger.Debug,
                    Quiet   = Logger.Quiet
                };
                AttackSurfaceAnalyzerClient.ClearMonitors();
                return(Json((int)AttackSurfaceAnalyzerClient.RunGuiMonitorCommand(opts)));
            }
            return(Json(-1));
        }
        public void TestTrimToLatest()
        {
            DatabaseManager.Setup("asa.sqlite");
            var compareRun = new AsaRun("Run1", DateTime.Now, "Version", AsaHelpers.GetPlatform(), new List <RESULT_TYPE>()
            {
                RESULT_TYPE.CERTIFICATE
            }, RUN_TYPE.COMPARE);
            var run1 = new AsaRun("Run1", DateTime.Now, "Version", AsaHelpers.GetPlatform(), new List <RESULT_TYPE>()
            {
                RESULT_TYPE.CERTIFICATE
            }, RUN_TYPE.COLLECT);
            var run2 = new AsaRun("Run2", DateTime.Now, "Version", AsaHelpers.GetPlatform(), new List <RESULT_TYPE>()
            {
                RESULT_TYPE.CERTIFICATE
            }, RUN_TYPE.COLLECT);
            var run3 = new AsaRun("Run3", DateTime.Now, "Version", AsaHelpers.GetPlatform(), new List <RESULT_TYPE>()
            {
                RESULT_TYPE.CERTIFICATE
            }, RUN_TYPE.COLLECT);

            // TODO: Write results in and then trim them

            DatabaseManager.InsertRun(compareRun);
            DatabaseManager.InsertRun(run1);
            DatabaseManager.InsertRun(run2);
            DatabaseManager.InsertRun(run3);

            DatabaseManager.TrimToLatest();

            Assert.IsTrue(DatabaseManager.GetRuns(RUN_TYPE.COLLECT).Count == 1);
        }
        public static void InsertRun(AsaRun run)
        {
            if (run == null)
            {
                return;
            }
            if (MainConnection != null)
            {
                using var cmd = new SqliteCommand(SQL_INSERT_RUN, MainConnection.Connection, MainConnection.Transaction);
                cmd.Parameters.AddWithValue("@run_id", run.RunId);
                cmd.Parameters.AddWithValue("@type", run.Type);
                cmd.Parameters.AddWithValue("@serialized", JsonConvert.SerializeObject(run));

                try
                {
                    cmd.ExecuteNonQuery();
                }
                catch (SqliteException e)
                {
                    Log.Warning(e.StackTrace);
                    Log.Warning(e.Message);
                    AsaTelemetry.TrackTrace(Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Error, e);
                }
            }
            else
            {
                Log.Debug("Failed to InsertRun because MainConnection is null.");
            }
        }
        public void TestGetRun()
        {
            DatabaseManager.Setup("asa.sqlite");
            var run1 = new AsaRun("Run1", DateTime.Now, "Version", AsaHelpers.GetPlatform(), new List <RESULT_TYPE>()
            {
                RESULT_TYPE.CERTIFICATE
            }, RUN_TYPE.COLLECT);

            DatabaseManager.InsertRun(run1);

            var run2 = DatabaseManager.GetRun("Run1");

            Assert.IsTrue(run1.Version == run2?.Version);
        }
        public void TestGetLatestRunIds()
        {
            DatabaseManager.Setup("asa.sqlite");
            var run1 = new AsaRun("Run1", DateTime.Now, "Version", AsaHelpers.GetPlatform(), new List <RESULT_TYPE>()
            {
                RESULT_TYPE.CERTIFICATE
            }, RUN_TYPE.COLLECT);
            var run2 = new AsaRun("Run2", DateTime.Now, "Version", AsaHelpers.GetPlatform(), new List <RESULT_TYPE>()
            {
                RESULT_TYPE.CERTIFICATE
            }, RUN_TYPE.COLLECT);
            var run3 = new AsaRun("Run3", DateTime.Now, "Version", AsaHelpers.GetPlatform(), new List <RESULT_TYPE>()
            {
                RESULT_TYPE.CERTIFICATE
            }, RUN_TYPE.COLLECT);

            DatabaseManager.InsertRun(run1);
            DatabaseManager.InsertRun(run2);
            DatabaseManager.InsertRun(run3);

            var runids = DatabaseManager.GetLatestRunIds(10, RUN_TYPE.COLLECT);

            Assert.IsTrue(runids.Count == 3);
        }
Beispiel #6
0
 public abstract void InsertRun(AsaRun run);
Beispiel #7
0
        public static int RunCollectCommand(CollectCommandOptions opts)
        {
            if (opts == null)
            {
                return(-1);
            }
#if DEBUG
            Logger.Setup(true, opts.Verbose, opts.Quiet);
#else
            Logger.Setup(opts.Debug, opts.Verbose, opts.Quiet);
#endif
            var dbSettings = new DBSettings()
            {
                ShardingFactor = opts.Shards
            };
            SetupOrDie(opts.DatabaseFilename, dbSettings);
            AsaTelemetry.Setup();

            Dictionary <string, string> StartEvent = new Dictionary <string, string>();
            StartEvent.Add("Files", opts.EnableAllCollectors ? "True" : opts.EnableFileSystemCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Ports", opts.EnableNetworkPortCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Users", opts.EnableUserCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Certificates", opts.EnableCertificateCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Registry", opts.EnableRegistryCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Service", opts.EnableServiceCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Firewall", opts.EnableFirewallCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("ComObject", opts.EnableComObjectCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("EventLog", opts.EnableEventLogCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Admin", AsaHelpers.IsAdmin().ToString(CultureInfo.InvariantCulture));
            AsaTelemetry.TrackEvent("Run Command", StartEvent);

            AdminOrQuit();

            CheckFirstRun();

            int returnValue = (int)ASA_ERROR.NONE;
            opts.RunId = opts.RunId?.Trim() ?? DateTime.Now.ToString("o", CultureInfo.InvariantCulture);

            if (opts.MatchedCollectorId != null)
            {
                var matchedRun = DatabaseManager.GetRun(opts.MatchedCollectorId);
                if (matchedRun is AsaRun)
                {
                    foreach (var resultType in matchedRun.ResultTypes)
                    {
                        switch (resultType)
                        {
                        case RESULT_TYPE.FILE:
                            opts.EnableFileSystemCollector = true;
                            break;

                        case RESULT_TYPE.PORT:
                            opts.EnableNetworkPortCollector = true;
                            break;

                        case RESULT_TYPE.CERTIFICATE:
                            opts.EnableCertificateCollector = true;
                            break;

                        case RESULT_TYPE.COM:
                            opts.EnableComObjectCollector = true;
                            break;

                        case RESULT_TYPE.FIREWALL:
                            opts.EnableFirewallCollector = true;
                            break;

                        case RESULT_TYPE.LOG:
                            opts.EnableEventLogCollector = true;
                            break;

                        case RESULT_TYPE.SERVICE:
                            opts.EnableServiceCollector = true;
                            break;

                        case RESULT_TYPE.USER:
                            opts.EnableUserCollector = true;
                            break;
                        }
                    }
                }
            }

            var dict = new List <RESULT_TYPE>();

            if (opts.EnableFileSystemCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new FileSystemCollector(opts));
                dict.Add(RESULT_TYPE.FILE);
            }
            if (opts.EnableNetworkPortCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new OpenPortCollector());
                dict.Add(RESULT_TYPE.PORT);
            }
            if (opts.EnableServiceCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new ServiceCollector());
                dict.Add(RESULT_TYPE.SERVICE);
            }
            if (opts.EnableUserCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new UserAccountCollector());
                dict.Add(RESULT_TYPE.USER);
            }
            if (opts.EnableRegistryCollector || (opts.EnableAllCollectors && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)))
            {
                collectors.Add(new RegistryCollector(opts.Parallelization));
                dict.Add(RESULT_TYPE.REGISTRY);
            }
            if (opts.EnableCertificateCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new CertificateCollector());
                dict.Add(RESULT_TYPE.CERTIFICATE);
            }
            if (opts.EnableFirewallCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new FirewallCollector());
                dict.Add(RESULT_TYPE.FIREWALL);
            }
            if (opts.EnableComObjectCollector || (opts.EnableAllCollectors && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)))
            {
                collectors.Add(new ComObjectCollector());
                dict.Add(RESULT_TYPE.COM);
            }
            if (opts.EnableEventLogCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new EventLogCollector(opts.GatherVerboseLogs));
                dict.Add(RESULT_TYPE.LOG);
            }

            if (collectors.Count == 0)
            {
                Log.Warning(Strings.Get("Err_NoCollectors"));
                return((int)ASA_ERROR.NO_COLLECTORS);
            }

            if (opts.Overwrite)
            {
                DatabaseManager.DeleteRun(opts.RunId);
            }
            else
            {
                if (DatabaseManager.GetRun(opts.RunId) != null)
                {
                    Log.Error(Strings.Get("Err_RunIdAlreadyUsed"));
                    return((int)ASA_ERROR.UNIQUE_ID);
                }
            }
            Log.Information(Strings.Get("Begin"), opts.RunId);

            var run = new AsaRun(RunId: opts.RunId, Timestamp: DateTime.Now, Version: AsaHelpers.GetVersionString(), Platform: AsaHelpers.GetPlatform(), ResultTypes: dict, Type: RUN_TYPE.COLLECT);

            DatabaseManager.InsertRun(run);

            Log.Information(Strings.Get("StartingN"), collectors.Count.ToString(CultureInfo.InvariantCulture), Strings.Get("Collectors"));

            Console.CancelKeyPress += delegate
            {
                Log.Information("Cancelling collection. Rolling back transaction. Please wait to avoid corrupting database.");
                DatabaseManager.RollBack();
                Environment.Exit(-1);
            };

            Dictionary <string, string> EndEvent = new Dictionary <string, string>();
            foreach (BaseCollector c in collectors)
            {
                try
                {
                    DatabaseManager.BeginTransaction();

                    var StopWatch = Stopwatch.StartNew();

                    Task.Run(() => c.Execute());

                    Thread.Sleep(1);

                    while (c.RunStatus == RUN_STATUS.RUNNING)
                    {
                        if (c.Results.TryDequeue(out CollectObject? res))
                        {
                            DatabaseManager.Write(res, opts.RunId);
                        }
                        else
                        {
                            Thread.Sleep(1);
                        }
                    }

                    StopWatch.Stop();
                    TimeSpan t      = TimeSpan.FromMilliseconds(StopWatch.ElapsedMilliseconds);
                    string   answer = string.Format(CultureInfo.InvariantCulture, "{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms",
                                                    t.Hours,
                                                    t.Minutes,
                                                    t.Seconds,
                                                    t.Milliseconds);
                    Log.Debug(Strings.Get("Completed"), c.GetType().Name, answer);

                    c.Results.AsParallel().ForAll(x => DatabaseManager.Write(x, opts.RunId));

                    var prevFlush = DatabaseManager.Connections.Select(x => x.WriteQueue.Count).Sum();
                    var totFlush  = prevFlush;

                    var printInterval   = 10;
                    var currentInterval = 0;

                    StopWatch = Stopwatch.StartNew();

                    while (DatabaseManager.HasElements)
                    {
                        Thread.Sleep(1000);

                        if (currentInterval++ % printInterval == 0)
                        {
                            var actualDuration = (currentInterval < printInterval) ? currentInterval : printInterval;
                            var sample         = DatabaseManager.Connections.Select(x => x.WriteQueue.Count).Sum();
                            var curRate        = prevFlush - sample;
                            var totRate        = (double)(totFlush - sample) / StopWatch.ElapsedMilliseconds;
                            try
                            {
                                t      = (curRate > 0) ? TimeSpan.FromMilliseconds(sample / ((double)curRate / (actualDuration * 1000))) : TimeSpan.FromMilliseconds(99999999); //lgtm[cs/loss-of-precision]
                                answer = string.Format(CultureInfo.InvariantCulture, "{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms",
                                                       t.Hours,
                                                       t.Minutes,
                                                       t.Seconds,
                                                       t.Milliseconds);
                                Log.Debug("Flushing {0} results. ({1}/{4}s {2:0.00}/s overall {3} ETA)", sample, curRate, totRate * 1000, answer, actualDuration);
                            }
                            catch (Exception e) when(
                                e is OverflowException)
                            {
                                Log.Debug($"Overflowed: {curRate} {totRate} {sample} {t} {answer}");
                                Log.Debug("Flushing {0} results. ({1}/s {2:0.00}/s)", sample, curRate, totRate * 1000);
                            }
                            prevFlush = sample;
                        }
                    }

                    StopWatch.Stop();
                    t      = TimeSpan.FromMilliseconds(StopWatch.ElapsedMilliseconds);
                    answer = string.Format(CultureInfo.InvariantCulture, "{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms",
                                           t.Hours,
                                           t.Minutes,
                                           t.Seconds,
                                           t.Milliseconds);
                    Log.Debug("Completed flushing in {0}", answer);

                    DatabaseManager.Commit();
                }
                catch (Exception e)
                {
                    Log.Error(Strings.Get("Err_CollectingFrom"), c.GetType().Name, e.Message, e.StackTrace);
                    Dictionary <string, string> ExceptionEvent = new Dictionary <string, string>();
                    ExceptionEvent.Add("Exception Type", e.GetType().ToString());
                    ExceptionEvent.Add("Stack Trace", e.StackTrace ?? string.Empty);
                    ExceptionEvent.Add("Message", e.Message);
                    AsaTelemetry.TrackEvent("CollectorCrashRogueException", ExceptionEvent);
                    returnValue = 1;
                }
            }
            AsaTelemetry.TrackEvent("End Command", EndEvent);

            DatabaseManager.Commit();
            DatabaseManager.CloseDatabase();
            return(returnValue);
        }
Beispiel #8
0
        private static int RunMonitorCommand(MonitorCommandOptions opts)
        {
#if DEBUG
            Logger.Setup(true, opts.Verbose);
#else
            Logger.Setup(opts.Debug, opts.Verbose);
#endif
            AdminOrQuit();

            SetupOrDie(opts.DatabaseFilename);
            AsaTelemetry.Setup();

            Dictionary <string, string> StartEvent = new Dictionary <string, string>();
            StartEvent.Add("Files", opts.EnableFileSystemMonitor.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Admin", AsaHelpers.IsAdmin().ToString(CultureInfo.InvariantCulture));
            AsaTelemetry.TrackEvent("Begin monitoring", StartEvent);

            CheckFirstRun();

            if (opts.RunId is string)
            {
                opts.RunId = opts.RunId.Trim();
            }
            else
            {
                opts.RunId = DateTime.Now.ToString("o", CultureInfo.InvariantCulture);
            }

            if (opts.Overwrite)
            {
                DatabaseManager.DeleteRun(opts.RunId);
            }
            else
            {
                if (DatabaseManager.GetRun(opts.RunId) != null)
                {
                    Log.Error(Strings.Get("Err_RunIdAlreadyUsed"));
                    return((int)ASA_ERROR.UNIQUE_ID);
                }
            }
            var run = new AsaRun(RunId: opts.RunId, Timestamp: DateTime.Now, Version: AsaHelpers.GetVersionString(), Platform: AsaHelpers.GetPlatform(), new List <RESULT_TYPE>()
            {
                RESULT_TYPE.FILEMONITOR
            }, RUN_TYPE.MONITOR);

            DatabaseManager.InsertRun(run);

            int returnValue = 0;

            if (opts.EnableFileSystemMonitor)
            {
                List <String> directories = new List <string>();

                if (opts.MonitoredDirectories != null)
                {
                    var parts = opts.MonitoredDirectories.Split(',');
                    foreach (String part in parts)
                    {
                        directories.Add(part);
                    }
                }
                else
                {
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                    {
                        directories.Add("/");
                    }
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        directories.Add("C:\\");
                    }
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                    {
                        directories.Add("/");
                    }
                }

                List <NotifyFilters> filterOptions = new List <NotifyFilters>
                {
                    NotifyFilters.Attributes, NotifyFilters.CreationTime, NotifyFilters.DirectoryName, NotifyFilters.FileName, NotifyFilters.LastAccess, NotifyFilters.LastWrite, NotifyFilters.Security, NotifyFilters.Size
                };

                foreach (String dir in directories)
                {
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                    {
                        var newMon = new FileSystemMonitor(opts.RunId, dir, false);
                        monitors.Add(newMon);
                    }
                    else
                    {
                        foreach (NotifyFilters filter in filterOptions)
                        {
                            Log.Information("Adding Path {0} Filter Type {1}", dir, filter.ToString());
                            var newMon = new FileSystemMonitor(opts.RunId, dir, false, filter);
                            monitors.Add(newMon);
                        }
                    }
                }
            }

            //if (opts.EnableRegistryMonitor)
            //{
            //var monitor = new RegistryMonitor();
            //monitors.Add(monitor);
            //}

            if (monitors.Count == 0)
            {
                Log.Warning(Strings.Get("Err_NoMonitors"));
                returnValue = (int)ASA_ERROR.NO_COLLECTORS;
            }

            using var exitEvent = new ManualResetEvent(false);

            // If duration is set, we use the secondary timer.
            if (opts.Duration > 0)
            {
                Log.Information("{0} {1} {2}.", Strings.Get("MonitorStartedFor"), opts.Duration, Strings.Get("Minutes"));
                using var aTimer = new System.Timers.Timer
                      {
                          Interval  = opts.Duration * 60 * 1000, //lgtm [cs/loss-of-precision]
                          AutoReset = false,
                      };
                aTimer.Elapsed += (source, e) => { exitEvent.Set(); };

                // Start the timer
                aTimer.Enabled = true;
            }

            foreach (FileSystemMonitor c in monitors)
            {
                Log.Information(Strings.Get("Begin"), c.GetType().Name);

                try
                {
                    c.StartRun();
                }
                catch (Exception ex)
                {
                    Log.Error(Strings.Get("Err_CollectingFrom"), c.GetType().Name, ex.Message, ex.StackTrace);
                    returnValue = 1;
                }
            }

            // Set up the event to capture CTRL+C
            Console.CancelKeyPress += (sender, eventArgs) =>
            {
                eventArgs.Cancel = true;
                exitEvent.Set();
            };

            Console.Write(Strings.Get("MonitoringPressC"));

            // Write a spinner and wait until CTRL+C
            WriteSpinner(exitEvent);
            Log.Information("");

            foreach (var c in monitors)
            {
                Log.Information(Strings.Get("End"), c.GetType().Name);

                try
                {
                    c.StopRun();
                    if (c is FileSystemMonitor)
                    {
                        ((FileSystemMonitor)c).Dispose();
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(ex, " {0}: {1}", c.GetType().Name, ex.Message, Strings.Get("Err_Stopping"));
                }
            }

            DatabaseManager.Commit();

            return(returnValue);
        }
        public static int RunCollectCommand(CollectCommandOptions opts)
        {
            if (opts == null)
            {
                return(-1);
            }
#if DEBUG
            Logger.Setup(true, opts.Verbose, opts.Quiet);
#else
            Logger.Setup(opts.Debug, opts.Verbose, opts.Quiet);
#endif
            var dbSettings = new DBSettings()
            {
                ShardingFactor = opts.Shards
            };
            SetupOrDie(opts.DatabaseFilename, dbSettings);
            AsaTelemetry.Setup();

            Dictionary <string, string> StartEvent = new Dictionary <string, string>();
            StartEvent.Add("Files", opts.EnableAllCollectors ? "True" : opts.EnableFileSystemCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Ports", opts.EnableNetworkPortCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Users", opts.EnableUserCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Certificates", opts.EnableCertificateCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Registry", opts.EnableRegistryCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Service", opts.EnableServiceCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Firewall", opts.EnableFirewallCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("ComObject", opts.EnableComObjectCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("EventLog", opts.EnableEventLogCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Admin", AsaHelpers.IsAdmin().ToString(CultureInfo.InvariantCulture));
            AsaTelemetry.TrackEvent("Run Command", StartEvent);

            AdminOrQuit();

            CheckFirstRun();

            int returnValue = (int)ASA_ERROR.NONE;
            opts.RunId = opts.RunId?.Trim() ?? DateTime.Now.ToString("o", CultureInfo.InvariantCulture);

            if (opts.MatchedCollectorId != null)
            {
                var matchedRun = DatabaseManager.GetRun(opts.MatchedCollectorId);
                if (matchedRun is AsaRun)
                {
                    foreach (var resultType in matchedRun.ResultTypes)
                    {
                        switch (resultType)
                        {
                        case RESULT_TYPE.FILE:
                            opts.EnableFileSystemCollector = true;
                            break;

                        case RESULT_TYPE.PORT:
                            opts.EnableNetworkPortCollector = true;
                            break;

                        case RESULT_TYPE.CERTIFICATE:
                            opts.EnableCertificateCollector = true;
                            break;

                        case RESULT_TYPE.COM:
                            opts.EnableComObjectCollector = true;
                            break;

                        case RESULT_TYPE.FIREWALL:
                            opts.EnableFirewallCollector = true;
                            break;

                        case RESULT_TYPE.LOG:
                            opts.EnableEventLogCollector = true;
                            break;

                        case RESULT_TYPE.SERVICE:
                            opts.EnableServiceCollector = true;
                            break;

                        case RESULT_TYPE.USER:
                            opts.EnableUserCollector = true;
                            break;
                        }
                    }
                }
            }

            var dict = new List <RESULT_TYPE>();

            if (opts.EnableFileSystemCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new FileSystemCollector(opts));
                dict.Add(RESULT_TYPE.FILE);
            }
            if (opts.EnableNetworkPortCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new OpenPortCollector(opts.RunId));
                dict.Add(RESULT_TYPE.PORT);
            }
            if (opts.EnableServiceCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new ServiceCollector(opts.RunId));
                dict.Add(RESULT_TYPE.SERVICE);
            }
            if (opts.EnableUserCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new UserAccountCollector(opts.RunId));
                dict.Add(RESULT_TYPE.USER);
            }
            if (opts.EnableRegistryCollector || (opts.EnableAllCollectors && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)))
            {
                collectors.Add(new RegistryCollector(opts.RunId, opts.Parallelization));
                dict.Add(RESULT_TYPE.REGISTRY);
            }
            if (opts.EnableCertificateCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new CertificateCollector(opts.RunId));
                dict.Add(RESULT_TYPE.CERTIFICATE);
            }
            if (opts.EnableFirewallCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new FirewallCollector(opts.RunId));
                dict.Add(RESULT_TYPE.FIREWALL);
            }
            if (opts.EnableComObjectCollector || (opts.EnableAllCollectors && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)))
            {
                collectors.Add(new ComObjectCollector(opts.RunId));
                dict.Add(RESULT_TYPE.COM);
            }
            if (opts.EnableEventLogCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new EventLogCollector(opts.RunId, opts.GatherVerboseLogs));
                dict.Add(RESULT_TYPE.LOG);
            }

            if (collectors.Count == 0)
            {
                Log.Warning(Strings.Get("Err_NoCollectors"));
                return((int)ASA_ERROR.NO_COLLECTORS);
            }

            if (opts.Overwrite)
            {
                DatabaseManager.DeleteRun(opts.RunId);
            }
            else
            {
                if (DatabaseManager.GetRun(opts.RunId) != null)
                {
                    Log.Error(Strings.Get("Err_RunIdAlreadyUsed"));
                    return((int)ASA_ERROR.UNIQUE_ID);
                }
            }
            Log.Information(Strings.Get("Begin"), opts.RunId);

            var run = new AsaRun(RunId: opts.RunId, Timestamp: DateTime.Now, Version: AsaHelpers.GetVersionString(), Platform: AsaHelpers.GetPlatform(), ResultTypes: dict, Type: RUN_TYPE.COLLECT);

            DatabaseManager.InsertRun(run);

            Log.Information(Strings.Get("StartingN"), collectors.Count.ToString(CultureInfo.InvariantCulture), Strings.Get("Collectors"));

            Console.CancelKeyPress += delegate
            {
                Log.Information("Cancelling collection. Rolling back transaction. Please wait to avoid corrupting database.");
                DatabaseManager.RollBack();
                Environment.Exit(-1);
            };

            Dictionary <string, string> EndEvent = new Dictionary <string, string>();
            foreach (BaseCollector c in collectors)
            {
                try
                {
                    c.Execute();
                    EndEvent.Add(c.GetType().ToString(), c.NumCollected().ToString(CultureInfo.InvariantCulture));
                }
                catch (Exception e)
                {
                    Log.Error(Strings.Get("Err_CollectingFrom"), c.GetType().Name, e.Message, e.StackTrace);
                    Dictionary <string, string> ExceptionEvent = new Dictionary <string, string>();
                    ExceptionEvent.Add("Exception Type", e.GetType().ToString());
                    ExceptionEvent.Add("Stack Trace", e.StackTrace ?? string.Empty);
                    ExceptionEvent.Add("Message", e.Message);
                    AsaTelemetry.TrackEvent("CollectorCrashRogueException", ExceptionEvent);
                    returnValue = 1;
                }
            }
            AsaTelemetry.TrackEvent("End Command", EndEvent);

            DatabaseManager.Commit();
            DatabaseManager.CloseDatabase();
            return(returnValue);
        }