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,
                          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);
        }
        private static int RunConfigCommand(ConfigCommandOptions opts)
        {
            SetupOrDie(opts.DatabaseFilename);
            CheckFirstRun();
            AsaTelemetry.Setup();

            if (opts.ResetDatabase)
            {
                var filename = DatabaseManager.SqliteFilename;
                DatabaseManager.Destroy();
                Log.Information(Strings.Get("DeletedDatabaseAt"), filename);
            }
            else
            {
                if (opts.ListRuns)
                {
                    if (DatabaseManager.FirstRun)
                    {
                        Log.Warning(Strings.Get("FirstRunListRunsError"), opts.DatabaseFilename);
                    }
                    else
                    {
                        Log.Information(Strings.Get("DumpingDataFromDatabase"), opts.DatabaseFilename);
                        List <string> CollectRuns = DatabaseManager.GetRuns(RUN_TYPE.COLLECT);
                        if (CollectRuns.Count > 0)
                        {
                            Log.Information(Strings.Get("Begin"), Strings.Get("EnumeratingCollectRunIds"));
                            foreach (string runId in CollectRuns)
                            {
                                var run = DatabaseManager.GetRun(runId);

                                if (run is AsaRun)
                                {
                                    Log.Information("RunId:{2} Timestamp:{0} AsaVersion:{1} ",
                                                    run.Timestamp,
                                                    run.Version,
                                                    run.RunId);

                                    var resultTypesAndCounts = DatabaseManager.GetResultTypesAndCounts(run.RunId);

                                    foreach (var kvPair in resultTypesAndCounts)
                                    {
                                        Log.Information("{0} : {1}", kvPair.Key, kvPair.Value);
                                    }
                                }
                            }
                        }
                        else
                        {
                            Log.Information(Strings.Get("NoCollectRuns"));
                        }

                        List <string> MonitorRuns = DatabaseManager.GetRuns(RUN_TYPE.MONITOR);
                        if (MonitorRuns.Count > 0)
                        {
                            Log.Information(Strings.Get("Begin"), Strings.Get("EnumeratingMonitorRunIds"));

                            foreach (string monitorRun in MonitorRuns)
                            {
                                var run = DatabaseManager.GetRun(monitorRun);

                                if (run != null)
                                {
                                    string output = $"{run.RunId} {run.Timestamp} {run.Version} {run.Type}";
                                    Log.Information(output);
                                    Log.Information(string.Join(',', run.ResultTypes.Where(x => run.ResultTypes.Contains(x))));
                                }
                            }
                        }
                        else
                        {
                            Log.Information(Strings.Get("NoMonitorRuns"));
                        }
                    }
                }

                if (opts.TelemetryOptOut != null)
                {
                    AsaTelemetry.SetEnabled(!bool.Parse(opts.TelemetryOptOut));
                    Log.Information(Strings.Get("TelemetryOptOut"), (bool.Parse(opts.TelemetryOptOut)) ? "Opted out" : "Opted in");
                }
                if (opts.DeleteRunId != null)
                {
                    DatabaseManager.DeleteRun(opts.DeleteRunId);
                }
                if (opts.TrimToLatest)
                {
                    DatabaseManager.TrimToLatest();
                }
            }
            return(0);
        }
        private static int RunExportCollectCommand(ExportCollectCommandOptions opts)
        {
#if DEBUG
            Logger.Setup(true, opts.Verbose, opts.Quiet);
#else
            Logger.Setup(opts.Debug, opts.Verbose, opts.Quiet);
#endif

            if (opts.OutputPath != null && !Directory.Exists(opts.OutputPath))
            {
                Log.Fatal(Strings.Get("Err_OutputPathNotExist"), opts.OutputPath);
                return(0);
            }

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

            if (opts.FirstRunId is null || opts.SecondRunId is null)
            {
                Log.Information("Provided null run Ids using latest two runs.");
                List <string> runIds = DatabaseManager.GetLatestRunIds(2, RUN_TYPE.COLLECT);

                if (runIds.Count < 2)
                {
                    Log.Fatal(Strings.Get("Err_CouldntDetermineTwoRun"));
                    System.Environment.Exit(-1);
                }
                else
                {
                    opts.SecondRunId = runIds.First();
                    opts.FirstRunId  = runIds.ElementAt(1);
                }
            }

            if (opts.FirstRunId is null || opts.SecondRunId is null)
            {
                return((int)ASA_ERROR.INVALID_ID);
            }
            Log.Information(Strings.Get("Comparing"), opts.FirstRunId, opts.SecondRunId);

            Dictionary <string, string> StartEvent = new Dictionary <string, string>();
            StartEvent.Add("OutputPathSet", (opts.OutputPath != null).ToString(CultureInfo.InvariantCulture));

            AsaTelemetry.TrackEvent("{0} Export Compare", StartEvent);

            CompareCommandOptions options = new CompareCommandOptions(opts.FirstRunId, opts.SecondRunId)
            {
                DatabaseFilename = opts.DatabaseFilename,
                AnalysesFile     = opts.AnalysesFile,
                Analyze          = opts.Analyze,
                SaveToDatabase   = opts.SaveToDatabase
            };

            Dictionary <string, object> results = CompareRuns(options);

            JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings()
            {
                Formatting           = Formatting.Indented,
                NullValueHandling    = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Ignore,
                Converters           = new List <JsonConverter>()
                {
                    new StringEnumConverter()
                },
                ContractResolver = new AsaExportContractResolver()
            });
            var outputPath = opts.OutputPath;
            if (outputPath is null)
            {
                outputPath = Directory.GetCurrentDirectory();
            }
            if (opts.ExplodedOutput)
            {
                results.Add("metadata", AsaHelpers.GenerateMetadata());

                string path = Path.Combine(outputPath, AsaHelpers.MakeValidFileName(opts.FirstRunId + "_vs_" + opts.SecondRunId));
                Directory.CreateDirectory(path);
                foreach (var key in results.Keys)
                {
                    string filePath = Path.Combine(path, AsaHelpers.MakeValidFileName(key));
                    using (StreamWriter sw = new StreamWriter(filePath)) //lgtm[cs/path-injection]
                    {
                        using (JsonWriter writer = new JsonTextWriter(sw))
                        {
                            serializer.Serialize(writer, results[key]);
                        }
                    }
                }
                Log.Information(Strings.Get("OutputWrittenTo"), (new DirectoryInfo(path)).FullName);
            }
            else
            {
                string path   = Path.Combine(outputPath, AsaHelpers.MakeValidFileName(opts.FirstRunId + "_vs_" + opts.SecondRunId + "_summary.json.txt"));
                var    output = new Dictionary <string, Object>();
                output["results"]  = results;
                output["metadata"] = AsaHelpers.GenerateMetadata();
                using (StreamWriter sw = new StreamWriter(path)) //lgtm[cs/path-injection]
                {
                    using (JsonWriter writer = new JsonTextWriter(sw))
                    {
                        serializer.Serialize(writer, output);
                    }
                }
                Log.Information(Strings.Get("OutputWrittenTo"), (new FileInfo(path)).FullName);
            }
            return(0);
        }
Esempio n. 4
0
        public void Compare(string firstRunId, string secondRunId)
        {
            if (firstRunId == null)
            {
                throw new ArgumentNullException(nameof(firstRunId));
            }
            if (secondRunId == null)
            {
                throw new ArgumentNullException(nameof(secondRunId));
            }

            List <RawCollectResult>  addObjects    = DatabaseManager.GetMissingFromFirst(firstRunId, secondRunId);
            List <RawCollectResult>  removeObjects = DatabaseManager.GetMissingFromFirst(secondRunId, firstRunId);
            List <RawModifiedResult> modifyObjects = DatabaseManager.GetModified(firstRunId, secondRunId);

            Parallel.ForEach(addObjects,
                             (added =>
            {
                var obj = new CompareResult()
                {
                    Compare = added.DeserializedObject,
                    BaseRunId = firstRunId,
                    CompareRunId = secondRunId,
                    CompareRowKey = added.RowKey,
                    ChangeType = CHANGE_TYPE.CREATED,
                    ResultType = added.ResultType,
                    Identity = added.Identity
                };
                Log.Debug($"Adding {obj.Identity}");
                Results[$"{added.ResultType.ToString()}_{CHANGE_TYPE.CREATED.ToString()}"].Enqueue(obj);
            }));

            Parallel.ForEach(removeObjects,
                             (removed =>
            {
                var obj = new CompareResult()
                {
                    Base = removed.DeserializedObject,
                    BaseRunId = firstRunId,
                    CompareRunId = secondRunId,
                    BaseRowKey = removed.RowKey,
                    ChangeType = CHANGE_TYPE.DELETED,
                    ResultType = removed.ResultType,
                    Identity = removed.Identity
                };

                Results[$"{removed.ResultType.ToString()}_{CHANGE_TYPE.DELETED.ToString()}"].Enqueue(obj);
            }));

            Parallel.ForEach(modifyObjects,
                             (modified =>
            {
                var compareLogic = new CompareLogic();
                compareLogic.Config.IgnoreCollectionOrder = true;
                var first = modified.First.DeserializedObject;
                var second = modified.Second.DeserializedObject;
                var obj = new CompareResult()
                {
                    Base = first,
                    Compare = second,
                    BaseRunId = firstRunId,
                    CompareRunId = secondRunId,
                    BaseRowKey = modified.First.RowKey,
                    CompareRowKey = modified.Second.RowKey,
                    ChangeType = CHANGE_TYPE.MODIFIED,
                    ResultType = modified.First.ResultType,
                    Identity = modified.First.Identity
                };

                var properties = first.GetType().GetProperties();

                foreach (var prop in properties)
                {
                    try
                    {
                        var propName = prop.Name;
                        List <Diff> diffs;
                        object added = null;
                        object removed = null;
                        object changed = new object();

                        object firstProp = prop.GetValue(first);
                        object secondProp = prop.GetValue(second);
                        if (firstProp == null && secondProp == null)
                        {
                            continue;
                        }
                        else if (firstProp == null && secondProp != null)
                        {
                            added = prop.GetValue(second);
                            diffs = GetDiffs(prop, added, null);
                        }
                        else if (secondProp == null && firstProp != null)
                        {
                            removed = prop.GetValue(first);
                            diffs = GetDiffs(prop, null, removed);
                        }
                        else if (firstProp != null && secondProp != null && compareLogic.Compare(firstProp, secondProp).AreEqual)
                        {
                            continue;
                        }
                        else
                        {
                            var firstVal = prop.GetValue(first);
                            var secondVal = prop.GetValue(second);

                            if (firstVal is List <string> )
                            {
                                added = ((List <string>)prop.GetValue(second)).Except((List <string>)prop.GetValue(first));
                                removed = ((List <string>)prop.GetValue(first)).Except((List <string>)prop.GetValue(second));
                                if (!((IEnumerable <string>)added).Any())
                                {
                                    added = null;
                                }
                                if (!((IEnumerable <string>)removed).Any())
                                {
                                    removed = null;
                                }
                            }
                            else if (firstVal is List <KeyValuePair <string, string> > )
                            {
                                added = ((List <KeyValuePair <string, string> >)prop.GetValue(second)).Except((List <KeyValuePair <string, string> >)prop.GetValue(first));
                                removed = ((List <KeyValuePair <string, string> >)prop.GetValue(first)).Except((List <KeyValuePair <string, string> >)prop.GetValue(second));
                                if (!((IEnumerable <KeyValuePair <string, string> >)added).Any())
                                {
                                    added = null;
                                }
                                if (!((IEnumerable <KeyValuePair <string, string> >)removed).Any())
                                {
                                    removed = null;
                                }
                            }
                            else if (firstVal is Dictionary <string, string> )
                            {
                                added = ((Dictionary <string, string>)secondVal)
                                        .Except((Dictionary <string, string>)firstVal)
                                        .ToDictionary(x => x.Key, x => x.Value);

                                removed = ((Dictionary <string, string>)firstVal)
                                          .Except((Dictionary <string, string>)secondVal)
                                          .ToDictionary(x => x.Key, x => x.Value);
                                if (!((IEnumerable <KeyValuePair <string, string> >)added).Any())
                                {
                                    added = null;
                                }
                                if (!((IEnumerable <KeyValuePair <string, string> >)removed).Any())
                                {
                                    removed = null;
                                }
                            }
                            else if (firstVal is string || firstVal is int || firstVal is bool)
                            {
                                obj.Diffs.Add(new Diff()
                                {
                                    Field = prop.Name, Before = firstVal, After = secondVal
                                });
                            }
                            else
                            {
                                obj.Diffs.Add(new Diff()
                                {
                                    Field = prop.Name, Before = firstVal, After = secondVal
                                });
                            }

                            diffs = GetDiffs(prop, added, removed);
                        }
                        foreach (var diff in diffs)
                        {
                            obj.Diffs.Add(diff);
                        }
                    }
                    catch (InvalidCastException e)
                    {
                        Log.Debug(e, $"Failed to cast {JsonSerializer.Serialize(prop)}");
                    }
                    catch (Exception e)
                    {
                        Log.Debug(e, "Generic exception. Tell a programmer.");
                        Dictionary <string, string> ExceptionEvent = new Dictionary <string, string>();
                        ExceptionEvent.Add("Exception Type", e.GetType().ToString());
                        AsaTelemetry.TrackEvent("CompareException", ExceptionEvent);
                    }
                }

                Results[$"{modified.First.ResultType.ToString()}_{CHANGE_TYPE.MODIFIED.ToString()}"].Enqueue(obj);
            }));

            foreach (var empty in Results.Where(x => x.Value.Count == 0))
            {
                Results.Remove(empty.Key, out _);
            }
        }
 public static void ClassSetup(TestContext _)
 {
     Logger.Setup(false, true);
     Strings.Setup();
     AsaTelemetry.Setup(test: true);
 }
Esempio n. 6
0
 public void Setup()
 {
     Logger.Setup(false, true);
     Strings.Setup();
     AsaTelemetry.Setup(test: true);
 }
        public ActionResult ChangeTelemetryState(bool DisableTelemetry)
        {
            AsaTelemetry.SetOptOut(DisableTelemetry);

            return(Json(true));
        }
Esempio n. 8
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
            DatabaseManager.Setup(opts.DatabaseFilename);
            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();
            DatabaseManager.VerifySchemaVersion();

            int returnValue = (int)GUI_ERROR.NONE;
            opts.RunId = opts.RunId.Trim();

            if (opts.RunId.Equals("Timestamp", StringComparison.InvariantCulture))
            {
                opts.RunId = DateTime.Now.ToString("o", CultureInfo.InvariantCulture);
            }

            if (opts.MatchedCollectorId != null)
            {
                var resultTypes = DatabaseManager.GetResultTypes(opts.MatchedCollectorId);
                foreach (var resultType in resultTypes)
                {
                    switch (resultType.Key)
                    {
                    case RESULT_TYPE.FILE:
                        opts.EnableFileSystemCollector = resultType.Value;
                        break;

                    case RESULT_TYPE.PORT:
                        opts.EnableNetworkPortCollector = resultType.Value;
                        break;

                    case RESULT_TYPE.CERTIFICATE:
                        opts.EnableCertificateCollector = resultType.Value;
                        break;

                    case RESULT_TYPE.COM:
                        opts.EnableComObjectCollector = resultType.Value;
                        break;

                    case RESULT_TYPE.FIREWALL:
                        opts.EnableFirewallCollector = resultType.Value;
                        break;

                    case RESULT_TYPE.LOG:
                        opts.EnableEventLogCollector = resultType.Value;
                        break;

                    case RESULT_TYPE.SERVICE:
                        opts.EnableServiceCollector = resultType.Value;
                        break;

                    case RESULT_TYPE.USER:
                        opts.EnableUserCollector = resultType.Value;
                        break;
                    }
                }
            }

            var dict = new Dictionary <RESULT_TYPE, bool>();

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

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

            if (!opts.NoFilters)
            {
                if (opts.FilterLocation.Equals("Use embedded filters.", StringComparison.InvariantCulture))
                {
                    Filter.LoadEmbeddedFilters();
                }
                else
                {
                    Filter.LoadFilters(opts.FilterLocation);
                }
            }

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

            DatabaseManager.InsertRun(opts.RunId, dict);

            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.Transaction.Rollback();
                Environment.Exit(0);
            };

            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);
                    ExceptionEvent.Add("Message", e.Message);
                    AsaTelemetry.TrackEvent("CollectorCrashRogueException", ExceptionEvent);
                    returnValue = 1;
                }
            }
            AsaTelemetry.TrackEvent("End Command", EndEvent);

            DatabaseManager.Commit();
            return(returnValue);
        }
Esempio n. 9
0
        private static int RunConfigCommand(ConfigCommandOptions opts)
        {
            DatabaseManager.Setup(opts.DatabaseFilename);
            CheckFirstRun();
            AsaTelemetry.Setup();

            if (opts.ResetDatabase)
            {
                DatabaseManager.CloseDatabase();
                try
                {
                    File.Delete(opts.DatabaseFilename);
                }
                catch (IOException e)
                {
                    Log.Fatal(e, Strings.Get("FailedToDeleteDatabase"), opts.DatabaseFilename, e.GetType().ToString(), e.Message);
                    Environment.Exit(-1);
                }
                Log.Information(Strings.Get("DeletedDatabaseAt"), opts.DatabaseFilename);
            }
            else
            {
                DatabaseManager.VerifySchemaVersion();

                if (opts.ListRuns)
                {
                    if (DatabaseManager.FirstRun)
                    {
                        Log.Warning(Strings.Get("FirstRunListRunsError"), opts.DatabaseFilename);
                    }
                    else
                    {
                        Log.Information(Strings.Get("DumpingDataFromDatabase"), opts.DatabaseFilename);
                        List <string> CollectRuns = DatabaseManager.GetRuns("collect");
                        if (CollectRuns.Count > 0)
                        {
                            Log.Information(Strings.Get("Begin"), Strings.Get("EnumeratingCollectRunIds"));
                            foreach (string runId in CollectRuns)
                            {
                                var run = DatabaseManager.GetRun(runId);
                                Log.Information("RunId:{2} Timestamp:{0} AsaVersion:{1} ",
                                                run.Timestamp,
                                                run.Version,
                                                run.RunId);

                                var resultTypesAndCounts = DatabaseManager.GetResultTypesAndCounts(run.RunId);

                                foreach (var kvPair in resultTypesAndCounts)
                                {
                                    Log.Information("{0} : {1}", kvPair.Key, kvPair.Value);
                                }
                            }
                        }
                        else
                        {
                            Log.Information(Strings.Get("NoCollectRuns"));
                        }

                        List <string> MonitorRuns = DatabaseManager.GetRuns("monitor");
                        if (MonitorRuns.Count > 0)
                        {
                            Log.Information(Strings.Get("Begin"), Strings.Get("EnumeratingMonitorRunIds"));

                            foreach (string monitorRun in MonitorRuns)
                            {
                                var run = DatabaseManager.GetRun(monitorRun);

                                if (run != null)
                                {
                                    string output = $"{run.RunId} {run.Timestamp} {run.Version} {run.Type}";
                                    Log.Information(output);
                                    Log.Information(string.Join(',', run.ResultTypes.Keys.Where(x => run.ResultTypes[x])));
                                }
                            }
                        }
                        else
                        {
                            Log.Information(Strings.Get("NoMonitorRuns"));
                        }
                    }
                }

                if (opts.TelemetryOptOut != null)
                {
                    AsaTelemetry.SetOptOut(bool.Parse(opts.TelemetryOptOut));
                    Log.Information(Strings.Get("TelemetryOptOut"), (bool.Parse(opts.TelemetryOptOut)) ? "Opted out" : "Opted in");
                }
                if (opts.DeleteRunId != null)
                {
                    DatabaseManager.DeleteRun(opts.DeleteRunId);
                }
                if (opts.TrimToLatest)
                {
                    DatabaseManager.TrimToLatest();
                }
            }

            return(0);
        }
        public ActionResult ChangeTelemetryState(bool EnableTelemetry)
        {
            AsaTelemetry.SetEnabled(EnableTelemetry);

            return(Json(true));
        }
Esempio n. 11
0
        public static Dictionary <string, object> CompareRuns(CompareCommandOptions opts)
        {
            if (opts is null)
            {
                throw new ArgumentNullException(nameof(opts));
            }

            if (opts.SaveToDatabase)
            {
                DatabaseManager.InsertCompareRun(opts.FirstRunId, opts.SecondRunId, RUN_STATUS.RUNNING);
            }

            var results = new Dictionary <string, object>();

            comparators = new List <BaseCompare>();

            Dictionary <string, string> EndEvent = new Dictionary <string, string>();
            BaseCompare c     = new BaseCompare();
            var         watch = System.Diagnostics.Stopwatch.StartNew();

            if (!c.TryCompare(opts.FirstRunId, opts.SecondRunId))
            {
                Log.Warning(Strings.Get("Err_Comparing") + " : {0}", c.GetType().Name);
            }

            c.Results.ToList().ForEach(x => results.Add(x.Key, x.Value));

            watch.Stop();
            TimeSpan t      = TimeSpan.FromMilliseconds(watch.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.Information(Strings.Get("Completed"), "Comparing", answer);

            if (opts.Analyze)
            {
                watch = System.Diagnostics.Stopwatch.StartNew();
                Analyzer analyzer;

                analyzer = new Analyzer(DatabaseManager.RunIdToPlatform(opts.FirstRunId), opts.AnalysesFile);

                if (results.Count > 0)
                {
                    foreach (var key in results.Keys)
                    {
                        try
                        {
                            Parallel.ForEach(results[key] as ConcurrentQueue <CompareResult>, (result) =>
                            {
                                result.Analysis = analyzer.Analyze(result);
                            });
                        }
                        catch (ArgumentNullException)
                        {
                        }
                    }
                }

                watch.Stop();
                t      = TimeSpan.FromMilliseconds(watch.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.Information(Strings.Get("Completed"), "Analysis", answer);
            }

            watch = System.Diagnostics.Stopwatch.StartNew();


            if (opts.SaveToDatabase)
            {
                foreach (var key in results.Keys)
                {
                    try
                    {
                        foreach (var result in (results[key] as ConcurrentQueue <CompareResult>))
                        {
                            DatabaseManager.InsertAnalyzed(result);
                        }
                    }
                    catch (NullReferenceException)
                    {
                        Log.Debug(key);
                    }
                }
            }


            watch.Stop();
            t      = TimeSpan.FromMilliseconds(watch.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.Information(Strings.Get("Completed"), "Flushing", answer);

            if (opts.SaveToDatabase)
            {
                DatabaseManager.UpdateCompareRun(opts.FirstRunId, opts.SecondRunId, RUN_STATUS.COMPLETED);
            }

            DatabaseManager.Commit();
            AsaTelemetry.TrackEvent("End Command", EndEvent);
            return(results);
        }
Esempio n. 12
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(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);
        }
Esempio n. 13
0
        public void Compare(string firstRunId, string secondRunId)
        {
            if (firstRunId == null)
            {
                throw new ArgumentNullException(nameof(firstRunId));
            }
            if (secondRunId == null)
            {
                throw new ArgumentNullException(nameof(secondRunId));
            }

            ConcurrentBag <WriteObject> differentObjects             = DatabaseManager.GetAllMissing(firstRunId, secondRunId);
            ConcurrentBag <(WriteObject, WriteObject)> modifyObjects = DatabaseManager.GetModified(firstRunId, secondRunId);

            differentObjects.AsParallel().ForAll(different =>
            {
                if (different.RunId.Equals(firstRunId))
                {
                    var obj = new CompareResult()
                    {
                        Base         = different.ColObj,
                        BaseRunId    = firstRunId,
                        CompareRunId = secondRunId,
                        BaseRowKey   = different.RowKey,
                    };

                    Results[$"{different.ColObj?.ResultType}_{CHANGE_TYPE.DELETED}"].Enqueue(obj);
                }
                else if (different.RunId.Equals(secondRunId))
                {
                    var obj = new CompareResult()
                    {
                        Compare       = different.ColObj,
                        BaseRunId     = firstRunId,
                        CompareRunId  = secondRunId,
                        CompareRowKey = different.RowKey,
                    };
                    Results[$"{different.ColObj?.ResultType}_{CHANGE_TYPE.CREATED}"].Enqueue(obj);
                }
            });

            modifyObjects.AsParallel().ForAll(modified =>
            {
                var compareLogic = new CompareLogic();
                compareLogic.Config.IgnoreCollectionOrder = true;
                var first  = modified.Item1.ColObj;
                var second = modified.Item2.ColObj;
                var obj    = new CompareResult()
                {
                    Base          = first,
                    Compare       = second,
                    BaseRunId     = firstRunId,
                    CompareRunId  = secondRunId,
                    BaseRowKey    = modified.Item1.RowKey,
                    CompareRowKey = modified.Item2.RowKey,
                };

                var properties = first?.GetType().GetProperties();

                if (properties is PropertyInfo[])
                {
                    foreach (var prop in properties)
                    {
                        try
                        {
                            List <Diff> diffs;
                            object?added   = null;
                            object?removed = null;

                            object?firstProp  = prop.GetValue(first);
                            object?secondProp = prop.GetValue(second);
                            if (firstProp == null && secondProp == null)
                            {
                                continue;
                            }
                            else if (firstProp == null && secondProp != null)
                            {
                                added = prop.GetValue(second);
                                diffs = GetDiffs(prop, added, null);
                            }
                            else if (secondProp == null && firstProp != null)
                            {
                                removed = prop.GetValue(first);
                                diffs   = GetDiffs(prop, null, removed);
                            }
                            else if (firstProp != null && secondProp != null && compareLogic.Compare(firstProp, secondProp).AreEqual)
                            {
                                continue;
                            }
                            else
                            {
                                var firstVal  = prop.GetValue(first);
                                var secondVal = prop.GetValue(second);

                                if (firstVal is List <string> && secondVal is List <string> )
                                {
                                    added   = ((List <string>)secondVal).Except((List <string>)firstVal);
                                    removed = ((List <string>)firstVal).Except((List <string>?)prop.GetValue(second));
                                    if (!((IEnumerable <string>)added).Any())
                                    {
                                        added = null;
                                    }
                                    if (!((IEnumerable <string>)removed).Any())
                                    {
                                        removed = null;
                                    }
                                }
                                else if (firstVal is List <KeyValuePair <string, string> > && secondVal is List <KeyValuePair <string, string> > )
                                {
                                    added   = ((List <KeyValuePair <string, string> >)secondVal).Except((List <KeyValuePair <string, string> >)firstVal);
                                    removed = ((List <KeyValuePair <string, string> >)firstVal).Except((List <KeyValuePair <string, string> >)secondVal);
                                    if (!((IEnumerable <KeyValuePair <string, string> >)added).Any())
                                    {
                                        added = null;
                                    }
                                    if (!((IEnumerable <KeyValuePair <string, string> >)removed).Any())
                                    {
                                        removed = null;
                                    }
                                }
                                else if (firstVal is Dictionary <string, string> && secondVal is Dictionary <string, string> )
                                {
                                    added = ((Dictionary <string, string>)secondVal)
                                            .Except((Dictionary <string, string>)firstVal)
                                            .ToDictionary(x => x.Key, x => x.Value);

                                    removed = ((Dictionary <string, string>)firstVal)
                                              .Except((Dictionary <string, string>)secondVal)
                                              .ToDictionary(x => x.Key, x => x.Value);
                                    if (!((IEnumerable <KeyValuePair <string, string> >)added).Any())
                                    {
                                        added = null;
                                    }
                                    if (!((IEnumerable <KeyValuePair <string, string> >)removed).Any())
                                    {
                                        removed = null;
                                    }
                                }
                                else if ((firstVal is string || firstVal is int || firstVal is bool) && (secondVal is string || secondVal is int || secondVal is bool))
                                {
                                    obj.Diffs.Add(new Diff(prop.Name, firstVal, secondVal));
                                }
                                else
                                {
                                    obj.Diffs.Add(new Diff(prop.Name, firstVal, secondVal));
                                }

                                diffs = GetDiffs(prop, added, removed);
                            }
                            foreach (var diff in diffs)
                            {
                                obj.Diffs.Add(diff);
                            }
                        }
                        catch (InvalidCastException e)
                        {
                            Log.Debug(e, $"Failed to cast {JsonConvert.SerializeObject(prop)}");
                        }
                        catch (Exception e)
                        {
                            Log.Debug(e, "Generic exception. Tell a programmer.");
                            Dictionary <string, string> ExceptionEvent = new Dictionary <string, string>();
                            ExceptionEvent.Add("Exception Type", e.GetType().ToString());
                            AsaTelemetry.TrackEvent("CompareException", ExceptionEvent);
                        }
                    }
                }

                Results[$"{modified.Item1.ColObj?.ResultType.ToString()}_{CHANGE_TYPE.MODIFIED}"].Enqueue(obj);
            });

            foreach (var empty in Results.Where(x => x.Value.Count == 0))
            {
                Results.Remove(empty.Key, out _);
            }
        }
Esempio n. 14
0
        public static ConcurrentDictionary <(RESULT_TYPE, CHANGE_TYPE), List <CompareResult> > CompareRuns(CompareCommandOptions opts)
        {
            if (opts is null)
            {
                throw new ArgumentNullException(nameof(opts));
            }

            if (opts.SaveToDatabase)
            {
                DatabaseManager.InsertCompareRun(opts.FirstRunId, opts.SecondRunId, RUN_STATUS.RUNNING);
            }

            comparators = new List <BaseCompare>();

            Dictionary <string, string> EndEvent = new Dictionary <string, string>();
            BaseCompare c     = new BaseCompare();
            var         watch = System.Diagnostics.Stopwatch.StartNew();

            if (!c.TryCompare(opts.FirstRunId, opts.SecondRunId))
            {
                Log.Warning(Strings.Get("Err_Comparing") + " : {0}", c.GetType().Name);
            }

            watch.Stop();
            TimeSpan t      = TimeSpan.FromMilliseconds(watch.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.Information(Strings.Get("Completed"), "Comparing", answer);

            if (opts.Analyze)
            {
                watch = Stopwatch.StartNew();
                Analyzer analyzer = new Analyzer(DatabaseManager.RunIdToPlatform(opts.SecondRunId), opts.AnalysesFile);

                var violations = analyzer.VerifyRules();
                Analyzer.PrintViolations(violations);
                if (violations.Any())
                {
                    Log.Error("Encountered {0} issues with rules in {1}. Skipping analysis.", violations.Count, opts.AnalysesFile ?? "Embedded");
                }
                else
                {
                    if (c.Results.Count > 0)
                    {
                        foreach (var key in c.Results.Keys)
                        {
                            if (c.Results[key] is List <CompareResult> queue)
                            {
                                queue.AsParallel().ForAll(res =>
                                {
                                    res.Rules    = analyzer.Analyze(res);
                                    res.Analysis = res.Rules.Count > 0 ? res.Rules.Max(x => x.Flag) : analyzer.DefaultLevels[res.ResultType];
                                });
                            }
                        }
                    }
                }

                watch.Stop();
                t      = TimeSpan.FromMilliseconds(watch.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.Information(Strings.Get("Completed"), "Analysis", answer);
            }

            watch = Stopwatch.StartNew();

            if (opts.SaveToDatabase)
            {
                foreach (var key in c.Results.Keys)
                {
                    if (c.Results.TryGetValue(key, out List <CompareResult>?obj))
                    {
                        if (obj is List <CompareResult> Queue)
                        {
                            foreach (var result in Queue)
                            {
                                DatabaseManager.InsertAnalyzed(result);
                            }
                        }
                    }
                }
            }

            watch.Stop();
            t      = TimeSpan.FromMilliseconds(watch.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.Information(Strings.Get("Completed"), "Flushing", answer);

            if (opts.SaveToDatabase)
            {
                DatabaseManager.UpdateCompareRun(opts.FirstRunId, opts.SecondRunId, RUN_STATUS.COMPLETED);
            }

            DatabaseManager.Commit();
            AsaTelemetry.TrackEvent("End Command", EndEvent);
            return(c.Results);
        }
Esempio n. 15
0
        private static int RunMonitorCommand(MonitorCommandOptions opts)
        {
#if DEBUG
            Logger.Setup(true, opts.Verbose);
#else
            Logger.Setup(opts.Debug, opts.Verbose);
#endif
            AdminOrQuit();

            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)
            {
                monitors.Add(new FileSystemMonitor(opts, x => DatabaseManager.WriteFileMonitor(x, opts.RunId)));
            }

            //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"));
                }
            }

            FlushResults();

            DatabaseManager.Commit();

            return(returnValue);
        }
Esempio n. 16
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("Tpm", opts.EnableEventLogCollector.ToString(CultureInfo.InvariantCulture));
            StartEvent.Add("Keys", opts.EnableKeyCollector.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;

                        case RESULT_TYPE.KEY:
                            opts.EnableKeyCollector = true;
                            break;

                        case RESULT_TYPE.TPM:
                            opts.EnableTpmCollector = 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 (opts.EnableTpmCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new TpmCollector());
                dict.Add(RESULT_TYPE.TPM);
            }
            if (opts.EnableKeyCollector || opts.EnableAllCollectors)
            {
                collectors.Add(new CryptographicKeyCollector());
                dict.Add(RESULT_TYPE.KEY);
            }

            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);
        }