public void TestFileCollector() { var testFolder = AsaHelpers.GetTempFolder(); Directory.CreateDirectory(testFolder); var opts = new CollectCommandOptions() { EnableFileSystemCollector = true, GatherHashes = true, SelectedDirectories = testFolder, DownloadCloud = false, }; using (var file = File.Open(Path.Combine(testFolder, "AsaLibTesterMZ"), FileMode.OpenOrCreate)) { file.Write(FileSystemUtils.WindowsMagicNumber, 0, 2); file.Write(FileSystemUtils.WindowsMagicNumber, 0, 2); file.Close(); } using (var file = File.Open(Path.Combine(testFolder, "AsaLibTesterJavaClass"), FileMode.OpenOrCreate)) { file.Write(FileSystemUtils.JavaMagicNumber, 0, 4); file.Close(); } var fsc = new FileSystemCollector(opts); fsc.Execute(); Assert.IsTrue(fsc.Results.Any(x => x is FileSystemObject FSO && FSO.Path.EndsWith("AsaLibTesterJavaClass") && FSO.IsExecutable == true)); Assert.IsTrue(fsc.Results.Any(x => x is FileSystemObject FSO && FSO.Path.EndsWith("AsaLibTesterMZ") && FSO.IsExecutable == true)); }
public EventLogCollector(CollectCommandOptions opts) { if (opts != null) { this.opts = opts; } }
public void TestFileCollector() { Setup(); var FirstRunId = "TestFileCollector-1"; var SecondRunId = "TestFileCollector-2"; var testFolder = AsaHelpers.GetTempFolder(); Directory.CreateDirectory(testFolder); var opts = new CollectCommandOptions() { RunId = FirstRunId, EnableFileSystemCollector = true, GatherHashes = true, SelectedDirectories = testFolder, DownloadCloud = false, CertificatesFromFiles = false }; var fsc = new FileSystemCollector(opts); fsc.Execute(); using (var file = File.Open(Path.Combine(testFolder, "AsaLibTesterMZ"), FileMode.OpenOrCreate)) { file.Write(FileSystemUtils.WindowsMagicNumber, 0, 2); file.Write(FileSystemUtils.WindowsMagicNumber, 0, 2); file.Close(); } using (var file = File.Open(Path.Combine(testFolder, "AsaLibTesterJavaClass"), FileMode.OpenOrCreate)) { file.Write(FileSystemUtils.JavaMagicNumber, 0, 4); file.Close(); } opts.RunId = SecondRunId; fsc = new FileSystemCollector(opts); fsc.Execute(); BaseCompare bc = new BaseCompare(); if (!bc.TryCompare(FirstRunId, SecondRunId)) { Assert.Fail(); } var results = bc.Results; Assert.IsTrue(results.ContainsKey("FILE_CREATED")); Assert.IsTrue(results["FILE_CREATED"].Where(x => x.Identity.Contains("AsaLibTesterMZ") && ((FileSystemObject)x.Compare).IsExecutable == true).Any()); Assert.IsTrue(results["FILE_CREATED"].Where(x => x.Identity.Contains("AsaLibTesterJavaClass") && ((FileSystemObject)x.Compare).IsExecutable == true).Any()); TearDown(); }
public void TestFileCompare() { var FirstRunId = "TestFileCollector-1"; var SecondRunId = "TestFileCollector-2"; var testFolder = AsaHelpers.GetTempFolder(); Directory.CreateDirectory(testFolder); var opts = new CollectCommandOptions() { RunId = FirstRunId, EnableFileSystemCollector = true, GatherHashes = true, SelectedDirectories = testFolder, DownloadCloud = false, }; var fsc = new FileSystemCollector(opts); fsc.Execute(); using (var file = File.Open(Path.Combine(testFolder, "AsaLibTesterMZ"), FileMode.OpenOrCreate)) { file.Write(FileSystemUtils.WindowsMagicNumber, 0, 2); file.Write(FileSystemUtils.WindowsMagicNumber, 0, 2); file.Close(); } using (var file = File.Open(Path.Combine(testFolder, "AsaLibTesterJavaClass"), FileMode.OpenOrCreate)) { file.Write(FileSystemUtils.JavaMagicNumber, 0, 4); file.Close(); } opts.RunId = SecondRunId; var fsc2 = new FileSystemCollector(opts); fsc2.Execute(); Assert.IsTrue(fsc2.Results.Any(x => x is FileSystemObject FSO && FSO.Path.EndsWith("AsaLibTesterMZ") && FSO.IsExecutable == true)); Assert.IsTrue(fsc2.Results.Any(x => x is FileSystemObject FSO && FSO.Path.EndsWith("AsaLibTesterJavaClass") && FSO.IsExecutable == true)); BaseCompare bc = new BaseCompare(); bc.Compare(fsc.Results, fsc2.Results, FirstRunId, SecondRunId); var results = bc.Results; Assert.IsTrue(results.ContainsKey((RESULT_TYPE.FILE, CHANGE_TYPE.CREATED))); Log.Debug(JsonConvert.SerializeObject(results)); Assert.IsTrue(results[(RESULT_TYPE.FILE, CHANGE_TYPE.CREATED)].Any(x => x.Compare is FileSystemObject FSO && FSO.Identity.Contains("AsaLibTesterMZ") && FSO.IsExecutable == true));
public ActionResult StartCollection(string Id, bool File, bool Port, bool Service, bool User, bool Registry, bool Certificates, bool Com, bool Firewall, bool Log) { CollectCommandOptions opts = new CollectCommandOptions(); opts.RunId = Id.Trim(); opts.EnableFileSystemCollector = File; opts.EnableNetworkPortCollector = Port; opts.EnableServiceCollector = Service; opts.EnableRegistryCollector = Registry; opts.EnableUserCollector = User; opts.EnableCertificateCollector = Certificates; opts.EnableComObjectCollector = Com; opts.EnableFirewallCollector = Firewall; opts.EnableEventLogCollector = Log; opts.DatabaseFilename = DatabaseManager.SqliteFilename; opts.FilterLocation = "Use embedded filters."; foreach (BaseCollector c in AttackSurfaceAnalyzerClient.GetCollectors()) { // The GUI *should* prevent us from getting here. But this is extra protection. // We won't start new collections while existing ones are ongoing. if (c.IsRunning() == RUN_STATUS.RUNNING) { return(Json(GUI_ERROR.ALREADY_RUNNING)); } } AttackSurfaceAnalyzerClient.ClearCollectors(); string Select_Runs = "select run_id from runs where run_id=@run_id"; using (var cmd = new SqliteCommand(Select_Runs, DatabaseManager.Connection, DatabaseManager.Transaction)) { cmd.Parameters.AddWithValue("@run_id", Id); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { return(Json(GUI_ERROR.UNIQUE_ID)); } } } Task.Factory.StartNew <int>(() => AttackSurfaceAnalyzerClient.RunCollectCommand(opts)); return(Json(GUI_ERROR.NONE)); }
public FileSystemCollector(CollectCommandOptions opts) { this.opts = opts; if (opts is null) { throw new ArgumentNullException(nameof(opts)); } roots = new HashSet <string>(); if (!string.IsNullOrEmpty(opts.SelectedDirectories)) { foreach (string path in opts.SelectedDirectories.Split(',')) { AddRoot(path); } } }
public ActionResult StartCollection(string Id, bool File, bool Port, bool Service, bool User, bool Registry, bool Certificates, bool Com, bool Firewall, bool Log) { CollectCommandOptions opts = new CollectCommandOptions(); opts.RunId = Id?.Trim(); opts.EnableFileSystemCollector = File; opts.EnableNetworkPortCollector = Port; opts.EnableServiceCollector = Service; opts.EnableRegistryCollector = Registry; opts.EnableUserCollector = User; opts.EnableCertificateCollector = Certificates; opts.EnableComObjectCollector = Com; opts.EnableFirewallCollector = Firewall; opts.EnableEventLogCollector = Log; opts.Verbose = Logger.Verbose; opts.Debug = Logger.Debug; opts.Quiet = Logger.Quiet; opts.DatabaseFilename = DatabaseManager.SqliteFilename; foreach (BaseCollector c in AttackSurfaceAnalyzerClient.GetCollectors()) { // The GUI *should* prevent us from getting here. But this is extra protection. // We won't start new collections while existing ones are ongoing. if (c.RunStatus == RUN_STATUS.RUNNING) { return(Json(ASA_ERROR.ALREADY_RUNNING)); } } AttackSurfaceAnalyzerClient.ClearCollectors(); if (Id is null) { return(Json(ASA_ERROR.INVALID_ID)); } if (DatabaseManager.GetRun(Id) != null) { return(Json(ASA_ERROR.UNIQUE_ID)); } _ = Task.Factory.StartNew(() => AttackSurfaceAnalyzerClient.RunCollectCommand(opts)); return(Json(ASA_ERROR.NONE)); }
public ActionResult StartCollection(string Id, bool File, bool Port, bool Service, bool User, bool Registry, bool Certificates) { CollectCommandOptions opts = new CollectCommandOptions(); opts.RunId = Id; opts.EnableFileSystemCollector = File; opts.EnableNetworkPortCollector = Port; opts.EnableServiceCollector = Service; opts.EnableRegistryCollector = Registry; opts.EnableUserCollector = User; opts.EnableCertificateCollector = Certificates; opts.DatabaseFilename = "asa.sqlite"; opts.FilterLocation = "filters.json"; Dictionary <string, bool> dict = new Dictionary <string, bool>(); foreach (BaseCollector c in AttackSurfaceAnalyzerCLI.GetCollectors()) { // The GUI *should* prevent us from getting here. But this is extra protection. // We won't start new collections while existing ones are ongoing. if (c.IsRunning() == RUN_STATUS.RUNNING) { return(Json(false)); } } AttackSurfaceAnalyzerCLI.ClearCollectors(); string Select_Runs = "select run_id from runs where run_id=@run_id"; using (var cmd = new SqliteCommand(Select_Runs, DatabaseManager.Connection, DatabaseManager.Transaction)) { cmd.Parameters.AddWithValue("@run_id", Id); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { return(Json(ERRORS.UNIQUE_ID)); } } } Task.Factory.StartNew <int>(() => AttackSurfaceAnalyzerCLI.RunCollectCommand(opts)); return(Json(ERRORS.NONE)); }
public FileSystemCollector(CollectCommandOptions opts) { if (opts is null) { throw new ArgumentNullException(nameof(opts)); } downloadCloud = opts.DownloadCloud; parallel = !opts.SingleThread; roots = new HashSet <string>(); INCLUDE_CONTENT_HASH = opts.GatherHashes; if (!string.IsNullOrEmpty(opts.SelectedDirectories)) { foreach (string path in opts.SelectedDirectories.Split(',')) { AddRoot(path); } } }
public FileSystemCollector(CollectCommandOptions opts) { if (opts is null || opts.RunId is null) { throw new ArgumentNullException(nameof(opts)); } RunId = opts.RunId; downloadCloud = opts.DownloadCloud; examineCertificates = opts.CertificatesFromFiles; parallel = opts.Parallelization; roots = new HashSet <string>(); INCLUDE_CONTENT_HASH = opts.GatherHashes; if (!string.IsNullOrEmpty(opts.SelectedDirectories)) { foreach (string path in opts.SelectedDirectories.Split(',')) { AddRoot(path); } } }
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, opts.Shards); 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(); if (opts.RunId.Equals("Timestamp", StringComparison.InvariantCulture)) { opts.RunId = DateTime.Now.ToString("o", CultureInfo.InvariantCulture); } if (opts.MatchedCollectorId != null) { var matchedRun = DatabaseManager.GetRun(opts.MatchedCollectorId); foreach (var resultType in matchedRun.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)ASA_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)ASA_ERROR.UNIQUE_ID); } } Log.Information(Strings.Get("Begin"), opts.RunId); var run = new Run() { RunId = opts.RunId, ResultTypes = dict }; 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); ExceptionEvent.Add("Message", e.Message); AsaTelemetry.TrackEvent("CollectorCrashRogueException", ExceptionEvent); returnValue = 1; } } AsaTelemetry.TrackEvent("End Command", EndEvent); DatabaseManager.Commit(); DatabaseManager.CloseDatabase(); 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()); 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); }
public ComObjectCollector(CollectCommandOptions opts) { this.opts = opts; }
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); }
public EventLogCollector(CollectCommandOptions opts) { this.opts = opts; GatherVerboseLogs = opts?.GatherVerboseLogs ?? false; }
protected BaseCollector(CollectCommandOptions?opts, Action <CollectObject>?changeHandler) { this.opts = opts ?? new CollectCommandOptions(); this.changeHandler = changeHandler; }
public void TestFileCompare() { var FirstRunId = "TestFileCollector-1"; var SecondRunId = "TestFileCollector-2"; var testFolder = AsaHelpers.GetTempFolder(); Directory.CreateDirectory(testFolder); var opts = new CollectCommandOptions() { RunId = FirstRunId, EnableFileSystemCollector = true, GatherHashes = true, SelectedDirectories = testFolder, DownloadCloud = false, CertificatesFromFiles = false }; var fsc = new FileSystemCollector(opts); fsc.Execute(); fsc.Results.AsParallel().ForAll(x => DatabaseManager.Write(x, FirstRunId)); using (var file = File.Open(Path.Combine(testFolder, "AsaLibTesterMZ"), FileMode.OpenOrCreate)) { file.Write(FileSystemUtils.WindowsMagicNumber, 0, 2); file.Write(FileSystemUtils.WindowsMagicNumber, 0, 2); file.Close(); } using (var file = File.Open(Path.Combine(testFolder, "AsaLibTesterJavaClass"), FileMode.OpenOrCreate)) { file.Write(FileSystemUtils.JavaMagicNumber, 0, 4); file.Close(); } opts.RunId = SecondRunId; fsc = new FileSystemCollector(opts); fsc.Execute(); Assert.IsTrue(fsc.Results.Any(x => x is FileSystemObject FSO && FSO.Path.EndsWith("AsaLibTesterMZ"))); Assert.IsTrue(fsc.Results.Any(x => x is FileSystemObject FSO && FSO.Path.EndsWith("AsaLibTesterJavaClass"))); fsc.Results.AsParallel().ForAll(x => DatabaseManager.Write(x, SecondRunId)); while (DatabaseManager.HasElements) { Thread.Sleep(1); } BaseCompare bc = new BaseCompare(); if (!bc.TryCompare(FirstRunId, SecondRunId)) { Assert.Fail(); } var results = bc.Results; Assert.IsTrue(results.ContainsKey((RESULT_TYPE.FILE, CHANGE_TYPE.CREATED))); Assert.IsTrue(results[(RESULT_TYPE.FILE, CHANGE_TYPE.CREATED)].Any(x => x.Identity.Contains("AsaLibTesterMZ") && ((FileSystemObject)x.Compare).IsExecutable == true));