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 ActionResult StartMonitoring(string RunId, string Directory, string Extension) { if (RunId != null) { using (var cmd = new SqliteCommand(INSERT_RUN, DatabaseManager.Connection, DatabaseManager.Transaction)) { cmd.Parameters.AddWithValue("@run_id", RunId.Trim()); cmd.Parameters.AddWithValue("@file_system", true); cmd.Parameters.AddWithValue("@ports", false); cmd.Parameters.AddWithValue("@users", false); cmd.Parameters.AddWithValue("@services", false); cmd.Parameters.AddWithValue("@registry", false); cmd.Parameters.AddWithValue("@certificates", false); cmd.Parameters.AddWithValue("@firewall", false); cmd.Parameters.AddWithValue("@comobjects", false); cmd.Parameters.AddWithValue("@type", "monitor"); cmd.Parameters.AddWithValue("@timestamp", DateTime.Now.ToString("o", CultureInfo.InvariantCulture)); cmd.Parameters.AddWithValue("@version", AsaHelpers.GetVersionString()); cmd.Parameters.AddWithValue("@platform", AsaHelpers.GetPlatformString()); try { cmd.ExecuteNonQuery(); DatabaseManager.Commit(); } catch (SqliteException e) { Log.Warning(e.StackTrace); Log.Warning(e.Message); return(Json((int)GUI_ERROR.UNIQUE_ID)); } } MonitorCommandOptions opts = new MonitorCommandOptions { RunId = RunId, EnableFileSystemMonitor = true, MonitoredDirectories = Directory, FilterLocation = "filters.json" }; AttackSurfaceAnalyzerClient.ClearMonitors(); return(Json((int)AttackSurfaceAnalyzerClient.RunGuiMonitorCommand(opts))); } return(Json(-1)); }
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); }
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); }