Report ransomware sensor coverage in beta
This commit is contained in:
@@ -129,11 +129,26 @@ internal sealed record RansomwareBetaSummary
|
||||
|
||||
public List<RansomwareSignal> Signals { get; init; } = [];
|
||||
|
||||
public List<RansomwareSensorStatus> Sensors { get; init; } = [];
|
||||
|
||||
public List<RansomwareSmbSession> SmbSessions { get; init; } = [];
|
||||
|
||||
public RansomwareFileChurnSummary FileChurn { get; init; } = new();
|
||||
}
|
||||
|
||||
internal sealed record RansomwareSensorStatus
|
||||
{
|
||||
public string Name { get; init; } = string.Empty;
|
||||
|
||||
public bool Enabled { get; init; }
|
||||
|
||||
public bool Available { get; init; }
|
||||
|
||||
public string State { get; init; } = "unknown";
|
||||
|
||||
public int EventCount { get; init; }
|
||||
}
|
||||
|
||||
internal sealed record RansomwareFileChurnSummary
|
||||
{
|
||||
public bool Enabled { get; init; }
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
<RootNamespace>OCSentinelCli</RootNamespace>
|
||||
<Product>OfficeCom Sentinel</Product>
|
||||
<Company>OfficeCom</Company>
|
||||
<Version>1.5.0-beta.4</Version>
|
||||
<Version>1.5.0-beta.5</Version>
|
||||
<AssemblyVersion>1.5.0.0</AssemblyVersion>
|
||||
<FileVersion>1.5.0.0</FileVersion>
|
||||
<InformationalVersion>1.5.0-beta.4</InformationalVersion>
|
||||
<InformationalVersion>1.5.0-beta.5</InformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -18,11 +18,22 @@ internal static class RansomwareBetaDetector
|
||||
int lookbackMinutes = Math.Clamp(configuration.RansomwareLookbackMinutes, 1, 60);
|
||||
DateTimeOffset since = DateTimeOffset.UtcNow.AddMinutes(-lookbackMinutes);
|
||||
var signals = new List<RansomwareSignal>();
|
||||
var sensors = new List<RansomwareSensorStatus>
|
||||
{
|
||||
ScanSecurityProcesses(signals, errors, since, configuration),
|
||||
ScanPowerShellScriptBlocks(signals, errors, since, configuration),
|
||||
ScanSysmonProcesses(signals, errors, since, configuration)
|
||||
};
|
||||
|
||||
ScanSecurityProcesses(signals, errors, since, configuration);
|
||||
ScanPowerShellScriptBlocks(signals, errors, since, configuration);
|
||||
ScanSysmonProcesses(signals, errors, since, configuration);
|
||||
RansomwareFileChurnSummary fileChurn = RansomwareFileChurnDetector.Scan(configuration, errors);
|
||||
sensors.Add(new RansomwareSensorStatus
|
||||
{
|
||||
Name = "security-file-audit-4663",
|
||||
Enabled = fileChurn.Enabled,
|
||||
Available = fileChurn.DataAvailable,
|
||||
State = !fileChurn.Enabled ? "disabled" : fileChurn.IsTruncated ? "truncated" : fileChurn.DataAvailable ? "available" : "unavailable",
|
||||
EventCount = fileChurn.FileOperationCount
|
||||
});
|
||||
RansomwareSignal? fileChurnSignal = RansomwareFileChurnDetector.CreateSignal(fileChurn, configuration);
|
||||
if (fileChurnSignal is not null)
|
||||
{
|
||||
@@ -61,24 +72,25 @@ internal static class RansomwareBetaDetector
|
||||
Reason = reason,
|
||||
LookbackMinutes = lookbackMinutes,
|
||||
Signals = distinctSignals,
|
||||
Sensors = sensors,
|
||||
SmbSessions = smbSessions,
|
||||
FileChurn = fileChurn
|
||||
};
|
||||
}
|
||||
|
||||
private static void ScanSecurityProcesses(List<RansomwareSignal> signals, List<string> errors, DateTimeOffset since, ScannerConfiguration configuration)
|
||||
private static RansomwareSensorStatus ScanSecurityProcesses(List<RansomwareSignal> signals, List<string> errors, DateTimeOffset since, ScannerConfiguration configuration)
|
||||
{
|
||||
TryScan("Security", 4688, since, errors, record => AddSignal(signals, record, ReadProperty(record, 5), ReadProperty(record, 8), "Security", configuration));
|
||||
return TryScan("security-process-4688", "Security", 4688, since, errors, record => AddSignal(signals, record, ReadProperty(record, 5), ReadProperty(record, 8), "Security", configuration));
|
||||
}
|
||||
|
||||
private static void ScanPowerShellScriptBlocks(List<RansomwareSignal> signals, List<string> errors, DateTimeOffset since, ScannerConfiguration configuration)
|
||||
private static RansomwareSensorStatus ScanPowerShellScriptBlocks(List<RansomwareSignal> signals, List<string> errors, DateTimeOffset since, ScannerConfiguration configuration)
|
||||
{
|
||||
TryScan("Microsoft-Windows-PowerShell/Operational", 4104, since, errors, record => AddSignal(signals, record, "powershell", FormatDescription(record), "PowerShell", configuration));
|
||||
return TryScan("powershell-script-block-4104", "Microsoft-Windows-PowerShell/Operational", 4104, since, errors, record => AddSignal(signals, record, "powershell", FormatDescription(record), "PowerShell", configuration));
|
||||
}
|
||||
|
||||
private static void ScanSysmonProcesses(List<RansomwareSignal> signals, List<string> errors, DateTimeOffset since, ScannerConfiguration configuration)
|
||||
private static RansomwareSensorStatus ScanSysmonProcesses(List<RansomwareSignal> signals, List<string> errors, DateTimeOffset since, ScannerConfiguration configuration)
|
||||
{
|
||||
TryScan("Microsoft-Windows-Sysmon/Operational", 1, since, errors, record => AddSignal(signals, record, "sysmon-process", FormatDescription(record), "Sysmon", configuration));
|
||||
return TryScan("sysmon-process-1", "Microsoft-Windows-Sysmon/Operational", 1, since, errors, record => AddSignal(signals, record, "sysmon-process", FormatDescription(record), "Sysmon", configuration));
|
||||
}
|
||||
|
||||
private static void AddSignal(List<RansomwareSignal> signals, EventRecord record, string process, string commandLine, string source, ScannerConfiguration configuration)
|
||||
@@ -146,8 +158,9 @@ internal static class RansomwareBetaDetector
|
||||
|
||||
private static bool ContainsAll(string value, params string[] needles) => needles.All(needle => value.Contains(needle, StringComparison.Ordinal));
|
||||
|
||||
private static void TryScan(string logName, int eventId, DateTimeOffset since, List<string> errors, Action<EventRecord> processRecord)
|
||||
private static RansomwareSensorStatus TryScan(string sensorName, string logName, int eventId, DateTimeOffset since, List<string> errors, Action<EventRecord> processRecord)
|
||||
{
|
||||
int eventCount = 0;
|
||||
try
|
||||
{
|
||||
long milliseconds = Math.Max(1, (long)(DateTimeOffset.UtcNow - since).TotalMilliseconds);
|
||||
@@ -157,16 +170,39 @@ internal static class RansomwareBetaDetector
|
||||
{
|
||||
using (record)
|
||||
{
|
||||
eventCount++;
|
||||
processRecord(record);
|
||||
}
|
||||
}
|
||||
|
||||
return new RansomwareSensorStatus
|
||||
{
|
||||
Name = sensorName,
|
||||
Enabled = true,
|
||||
Available = true,
|
||||
State = "available",
|
||||
EventCount = eventCount
|
||||
};
|
||||
}
|
||||
catch (EventLogNotFoundException)
|
||||
{
|
||||
return new RansomwareSensorStatus
|
||||
{
|
||||
Name = sensorName,
|
||||
Enabled = true,
|
||||
State = "not-installed"
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
errors.Add($"Ransomware beta query failed for {logName}: {exception.Message}");
|
||||
return new RansomwareSensorStatus
|
||||
{
|
||||
Name = sensorName,
|
||||
Enabled = true,
|
||||
State = "query-failed",
|
||||
EventCount = eventCount
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user