Skip to content

Commit

Permalink
TryExecute (#457)
Browse files Browse the repository at this point in the history
* Better Exception Handling in Collectors (#455)

Fix #454
Fix #453

* Catch all collector Exceptions

* Replace Execute with TryExecute (#456)
  • Loading branch information
gfs authored May 21, 2020
1 parent fee5e76 commit 0f97498
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 80 deletions.
5 changes: 4 additions & 1 deletion Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,10 @@ public static int RunCollectCommand(CollectCommandOptions opts)
{
DatabaseManager.BeginTransaction();

Task.Run(() => c.Execute());
Task.Run(() =>
{
c.TryExecute();
});

Thread.Sleep(1);

Expand Down
11 changes: 9 additions & 2 deletions Lib/Collectors/BaseCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public abstract class BaseCollector : IPlatformRunnable
{
public ConcurrentStack<CollectObject> Results { get; } = new ConcurrentStack<CollectObject>();
internal CollectCommandOptions opts = new CollectCommandOptions();
public void Execute()
public void TryExecute()
{
if (!CanRunOnPlatform())
{
Expand All @@ -29,7 +29,14 @@ public void Execute()
else
{
Start();
ExecuteInternal();
try
{
ExecuteInternal();
}
catch(Exception e)
{
Log.Debug("Failed to run {0} ({1}:{2})", GetType(), e.GetType(), e.Message);
}
Stop();
}
}
Expand Down
142 changes: 77 additions & 65 deletions Lib/Collectors/ServiceCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,96 +36,108 @@ public override bool CanRunOnPlatform()
/// </summary>
public void ExecuteWindows()
{
var fsc = new FileSystemCollector(new CollectCommandOptions() { SingleThread = opts.SingleThread });
System.Management.SelectQuery sQuery = new System.Management.SelectQuery("select * from Win32_Service"); // where name = '{0}'", "MCShield.exe"));
using System.Management.ManagementObjectSearcher mgmtSearcher = new System.Management.ManagementObjectSearcher(sQuery);
foreach (System.Management.ManagementObject service in mgmtSearcher.Get())
try
{
try
System.Management.SelectQuery sQuery = new System.Management.SelectQuery("select * from Win32_Service"); // where name = '{0}'", "MCShield.exe"));
using System.Management.ManagementObjectSearcher mgmtSearcher = new System.Management.ManagementObjectSearcher(sQuery);
foreach (System.Management.ManagementObject service in mgmtSearcher.Get())
{
var val = service.GetPropertyValue("Name").ToString();
if (val != null)
try
{
var obj = new ServiceObject(val);
var val = service.GetPropertyValue("Name").ToString();
if (val != null)
{
var obj = new ServiceObject(val);

val = service.GetPropertyValue("AcceptPause")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.AcceptPause = bool.Parse(val);
val = service.GetPropertyValue("AcceptPause")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.AcceptPause = bool.Parse(val);

val = service.GetPropertyValue("AcceptStop")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.AcceptStop = bool.Parse(val);
val = service.GetPropertyValue("AcceptStop")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.AcceptStop = bool.Parse(val);

obj.Caption = service.GetPropertyValue("Caption")?.ToString();
obj.Caption = service.GetPropertyValue("Caption")?.ToString();

val = service.GetPropertyValue("CheckPoint")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.CheckPoint = uint.Parse(val, CultureInfo.InvariantCulture);
val = service.GetPropertyValue("CheckPoint")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.CheckPoint = uint.Parse(val, CultureInfo.InvariantCulture);

obj.CreationClassName = service.GetPropertyValue("CreationClassName")?.ToString();
obj.CreationClassName = service.GetPropertyValue("CreationClassName")?.ToString();

val = service.GetPropertyValue("DelayedAutoStart")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.DelayedAutoStart = bool.Parse(val);
val = service.GetPropertyValue("DelayedAutoStart")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.DelayedAutoStart = bool.Parse(val);

obj.Description = service.GetPropertyValue("Description")?.ToString();
obj.Description = service.GetPropertyValue("Description")?.ToString();

val = service.GetPropertyValue("DesktopInteract")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.DesktopInteract = bool.Parse(val);
val = service.GetPropertyValue("DesktopInteract")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.DesktopInteract = bool.Parse(val);

obj.DisplayName = service.GetPropertyValue("DisplayName")?.ToString();
obj.ErrorControl = service.GetPropertyValue("ErrorControl")?.ToString();
obj.DisplayName = service.GetPropertyValue("DisplayName")?.ToString();
obj.ErrorControl = service.GetPropertyValue("ErrorControl")?.ToString();

val = service.GetPropertyValue("ExitCode")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.ExitCode = uint.Parse(val, CultureInfo.InvariantCulture);
val = service.GetPropertyValue("ExitCode")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.ExitCode = uint.Parse(val, CultureInfo.InvariantCulture);

if (DateTime.TryParse(service.GetPropertyValue("InstallDate")?.ToString(), out DateTime dateTime))
{
obj.InstallDate = dateTime;
}
obj.PathName = service.GetPropertyValue("PathName")?.ToString();
if (DateTime.TryParse(service.GetPropertyValue("InstallDate")?.ToString(), out DateTime dateTime))
{
obj.InstallDate = dateTime;
}
obj.PathName = service.GetPropertyValue("PathName")?.ToString();

val = service.GetPropertyValue("ProcessId")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.ProcessId = uint.Parse(val, CultureInfo.InvariantCulture);
val = service.GetPropertyValue("ProcessId")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.ProcessId = uint.Parse(val, CultureInfo.InvariantCulture);

val = service.GetPropertyValue("ServiceSpecificExitCode")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.ServiceSpecificExitCode = uint.Parse(val, CultureInfo.InvariantCulture);
val = service.GetPropertyValue("ServiceSpecificExitCode")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.ServiceSpecificExitCode = uint.Parse(val, CultureInfo.InvariantCulture);

obj.ServiceType = service.GetPropertyValue("ServiceType")?.ToString();
obj.ServiceType = service.GetPropertyValue("ServiceType")?.ToString();

val = service.GetPropertyValue("Started").ToString();
if (!string.IsNullOrEmpty(val))
obj.Started = bool.Parse(val);
val = service.GetPropertyValue("Started").ToString();
if (!string.IsNullOrEmpty(val))
obj.Started = bool.Parse(val);

obj.StartMode = service.GetPropertyValue("StartMode")?.ToString();
obj.StartName = service.GetPropertyValue("StartName")?.ToString();
obj.State = service.GetPropertyValue("State")?.ToString();
obj.Status = service.GetPropertyValue("Status")?.ToString();
obj.SystemCreationClassName = service.GetPropertyValue("SystemCreationClassName")?.ToString();
obj.SystemName = service.GetPropertyValue("SystemName")?.ToString();
obj.StartMode = service.GetPropertyValue("StartMode")?.ToString();
obj.StartName = service.GetPropertyValue("StartName")?.ToString();
obj.State = service.GetPropertyValue("State")?.ToString();
obj.Status = service.GetPropertyValue("Status")?.ToString();
obj.SystemCreationClassName = service.GetPropertyValue("SystemCreationClassName")?.ToString();
obj.SystemName = service.GetPropertyValue("SystemName")?.ToString();

val = service.GetPropertyValue("TagId")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.TagId = uint.Parse(val, CultureInfo.InvariantCulture);
val = service.GetPropertyValue("TagId")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.TagId = uint.Parse(val, CultureInfo.InvariantCulture);

val = service.GetPropertyValue("WaitHint")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.WaitHint = uint.Parse(val, CultureInfo.InvariantCulture);
val = service.GetPropertyValue("WaitHint")?.ToString();
if (!string.IsNullOrEmpty(val))
obj.WaitHint = uint.Parse(val, CultureInfo.InvariantCulture);

Results.Push(obj);
Results.Push(obj);
}
}
catch (Exception e) when (
e is TypeInitializationException ||
e is PlatformNotSupportedException)
{
Log.Warning(Strings.Get("CollectorNotSupportedOnPlatform"), GetType().ToString());
}
catch (Exception e)
{
Log.Warning(e, "Failed to grok Service Collector object at {0}.",service.Path);
}
}
catch (Exception e) when (
e is TypeInitializationException ||
e is PlatformNotSupportedException)
{
Log.Warning(Strings.Get("CollectorNotSupportedOnPlatform"), GetType().ToString());
}
}
catch (Exception e)
{
Log.Warning(e, "Failed to run Service Collector.");
}

var fsc = new FileSystemCollector(new CollectCommandOptions() { SingleThread = opts.SingleThread });

foreach (var file in Directory.EnumerateFiles("C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup"))
{
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ All data collected is stored in a set of local SQLite databases.
Run the following commands in an Administrator Shell (or as root). Replace ```asa``` with ```asa.exe``` as appropriate for your platform.

### CLI Mode
To start a default all collectors run: ```asa collect```
To start a default all collectors run: ```asa collect -a```

To compare the last two collection runs: ```asa export-collect```

Expand Down
22 changes: 11 additions & 11 deletions Tests/CollectorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void TestFileCollector()
}

var fsc = new FileSystemCollector(opts);
fsc.Execute();
fsc.TryExecute();

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));
Expand Down Expand Up @@ -93,7 +93,7 @@ public void TestEventCollectorWindows()
eventLog.WriteEntry("This Log Entry was created for testing the Attack Surface Analyzer library.", EventLogEntryType.Warning, 101, 1);

var fsc = new EventLogCollector(new CollectCommandOptions());
fsc.Execute();
fsc.TryExecute();

EventLog.DeleteEventSource(source);
EventLog.Delete(logname);
Expand All @@ -108,7 +108,7 @@ public void TestEventCollectorWindows()
public void TestCertificateCollectorWindows()
{
var fsc = new CertificateCollector();
fsc.Execute();
fsc.TryExecute();

Assert.IsTrue(fsc.Results.Where(x => x.ResultType == RESULT_TYPE.CERTIFICATE).Count() > 0);
}
Expand Down Expand Up @@ -137,7 +137,7 @@ public void TestPortCollectorWindows()
Console.WriteLine("Failed to open port.");
}
var fsc = new OpenPortCollector();
fsc.Execute();
fsc.TryExecute();
server.Stop();

Assert.IsTrue(fsc.Results.Any(x => x is OpenPortObject OPO && OPO.Port == 13000));
Expand All @@ -154,7 +154,7 @@ public void TestFirewallCollectorOSX()
_ = ExternalCommandRunner.RunExternalCommand("/usr/libexec/ApplicationFirewall/socketfilterfw", "--add /bin/bash");

var fwc = new FirewallCollector();
fwc.Execute();
fwc.TryExecute();
_ = ExternalCommandRunner.RunExternalCommand("/usr/libexec/ApplicationFirewall/socketfilterfw", "--remove /bin/bash");
Assert.IsTrue(fwc.Results.Any(x => x is FirewallObject FWO && FWO.ApplicationName == "/bin/bash"));
}
Expand All @@ -171,7 +171,7 @@ public void TestFirewallCollectorLinux()
var result = ExternalCommandRunner.RunExternalCommand("iptables", "-A INPUT -p tcp --dport 19999 -j DROP");

var fwc = new FirewallCollector();
fwc.Execute();
fwc.TryExecute();

Assert.IsTrue(fwc.Results.Any(x => x is FirewallObject FWO && FWO.LocalPorts.Contains("19999")));

Expand Down Expand Up @@ -204,7 +204,7 @@ public void TestFirewallCollectorWindows()
FirewallManager.Instance.Rules.Add(rule);

var fwc = new FirewallCollector();
fwc.Execute();
fwc.TryExecute();

Assert.IsTrue(fwc.Results.Any(x => x is FirewallObject FWO && FWO.LocalPorts.Contains("9999")));
Assert.IsTrue(fwc.Results.Any(x => x is FirewallObject FWO && FWO.ApplicationName is string && FWO.ApplicationName.Equals(@"C:\MyApp.exe")));
Expand Down Expand Up @@ -243,7 +243,7 @@ public void TestRegistryCollectorWindows()
key.Close();

var rc = new RegistryCollector(new List<(RegistryHive, string)>() { (RegistryHive.CurrentUser, name) }, new CollectCommandOptions() { SingleThread = true });
rc.Execute();
rc.TryExecute();

Registry.CurrentUser.DeleteSubKey(name);

Expand All @@ -267,7 +267,7 @@ public void TestServiceCollectorWindows()
ExternalCommandRunner.RunExternalCommand("sc.exe", cmd);

var sc = new ServiceCollector();
sc.Execute();
sc.TryExecute();

Assert.IsTrue(sc.Results.Any(x => x is ServiceObject RO && RO.Name.Equals(serviceName)));

Expand All @@ -286,7 +286,7 @@ public void TestComObjectCollector()
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var coc = new ComObjectCollector(new CollectCommandOptions());
coc.Execute();
coc.TryExecute();

Assert.IsTrue(coc.Results.Any(x => x is ComObject y && y.x86_Binary != null));
}
Expand All @@ -308,7 +308,7 @@ public void TestUserCollectorWindows()
ExternalCommandRunner.RunExternalCommand("net", cmd);

var uac = new UserAccountCollector();
uac.Execute();
uac.TryExecute();

Assert.IsTrue(uac.Results.Any(x => x is UserAccountObject y && y.Name.Equals(user)));

Expand Down

0 comments on commit 0f97498

Please sign in to comment.