Gfs/reduce hash calls (#613)
* Reduce number of calls to hash the analysis file. * Add Comments to Rule File * Clean up test. * Try explicitly calling SHA512Managed for #602 * Add Managed Crypto Tests
This commit is contained in:
Родитель
476414b133
Коммит
18768e7dac
|
@ -13,7 +13,6 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Benchmarks
|
|||
public class CryptoTests : AsaDatabaseBenchmark
|
||||
{
|
||||
public CryptoTests()
|
||||
#nullable restore
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -21,9 +20,13 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Benchmarks
|
|||
[Params(100000)]
|
||||
public int N { get; set; }
|
||||
|
||||
// The number of iterations per run
|
||||
[Params(1000)]
|
||||
public int NumObjects { get; set; }
|
||||
|
||||
// The amount of padding to add to the object in bytes Default size is approx 530 bytes serialized
|
||||
// Does not include SQL overhead
|
||||
[Params(0)]
|
||||
[Params(1000)]
|
||||
public int ObjectPadding { get; set; }
|
||||
|
||||
[Benchmark]
|
||||
|
@ -31,10 +34,10 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Benchmarks
|
|||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
hashObjects.TryDequeue(out string? result);
|
||||
if (result is string)
|
||||
hashObjects.TryDequeue(out byte[]? result);
|
||||
if (result is byte[])
|
||||
{
|
||||
_ = murmur128.ComputeHash(Encoding.UTF8.GetBytes(result));
|
||||
_ = murmur128.ComputeHash(result);
|
||||
hashObjects.Enqueue(result);
|
||||
}
|
||||
else
|
||||
|
@ -49,10 +52,28 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Benchmarks
|
|||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
hashObjects.TryDequeue(out string? result);
|
||||
if (result is string)
|
||||
hashObjects.TryDequeue(out byte[]? result);
|
||||
if (result is byte[])
|
||||
{
|
||||
_ = sha256.ComputeHash(Encoding.UTF8.GetBytes(result));
|
||||
_ = sha256.ComputeHash(result);
|
||||
hashObjects.Enqueue(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Information("The queue is polluted with nulls");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void Generate_N_SHA256Managed_Hashes()
|
||||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
hashObjects.TryDequeue(out byte[]? result);
|
||||
if (result is byte[])
|
||||
{
|
||||
_ = sha256managed.ComputeHash(result);
|
||||
hashObjects.Enqueue(result);
|
||||
}
|
||||
else
|
||||
|
@ -67,10 +88,28 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Benchmarks
|
|||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
hashObjects.TryDequeue(out string? result);
|
||||
if (result is string)
|
||||
hashObjects.TryDequeue(out byte[]? result);
|
||||
if (result is byte[])
|
||||
{
|
||||
_ = sha512.ComputeHash(Encoding.UTF8.GetBytes(result));
|
||||
_ = sha512.ComputeHash(result);
|
||||
hashObjects.Enqueue(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Information("The queue is polluted with nulls");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void Generate_N_SHA512_Managed_Hashes()
|
||||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
hashObjects.TryDequeue(out byte[]? result);
|
||||
if (result is byte[])
|
||||
{
|
||||
_ = sha512managed.ComputeHash(result);
|
||||
hashObjects.Enqueue(result);
|
||||
}
|
||||
else
|
||||
|
@ -83,9 +122,9 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Benchmarks
|
|||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
while (hashObjects.Count < N)
|
||||
while (hashObjects.Count < NumObjects)
|
||||
{
|
||||
hashObjects.Enqueue(JsonConvert.SerializeObject(GetRandomObject(ObjectPadding)));
|
||||
hashObjects.Enqueue(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(GetRandomObject(ObjectPadding))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,9 +132,12 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Benchmarks
|
|||
|
||||
private static readonly HashAlgorithm sha256 = SHA256.Create();
|
||||
|
||||
private static readonly HashAlgorithm sha256managed = SHA256Managed.Create();
|
||||
|
||||
private static readonly HashAlgorithm sha512 = SHA512.Create();
|
||||
|
||||
private readonly ConcurrentQueue<string> hashObjects = new ConcurrentQueue<string>();
|
||||
#nullable disable
|
||||
private static readonly HashAlgorithm sha512managed = SHA512Managed.Create();
|
||||
|
||||
private readonly ConcurrentQueue<byte[]> hashObjects = new ConcurrentQueue<byte[]>();
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Benchmarks
|
|||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var summary = BenchmarkRunner.Run<InsertTestsWithoutTransactions>();
|
||||
var summary = BenchmarkRunner.Run<CryptoTests>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -126,6 +126,13 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Cli
|
|||
Environment.Exit((int)argsResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the rules from the provided file, if it is not null or empty. Or falls back to the embedded rules if it is.
|
||||
/// </summary>
|
||||
/// <param name="analysisFile"></param>
|
||||
/// <returns>The loaded RuleFile</returns>
|
||||
private static RuleFile LoadRulesFromFileOrEmbedded(string? analysisFile) => string.IsNullOrEmpty(analysisFile) ? RuleFile.LoadEmbeddedFilters() : RuleFile.FromFile(analysisFile);
|
||||
|
||||
private static ASA_ERROR RunGuidedModeCommand(GuidedModeCommandOptions opts)
|
||||
{
|
||||
opts.RunId = opts.RunId?.Trim() ?? DateTime.Now.ToString("o", CultureInfo.InvariantCulture);
|
||||
|
@ -156,7 +163,13 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Cli
|
|||
|
||||
RunCollectCommand(collectorOpts);
|
||||
|
||||
var analysisFile = string.IsNullOrEmpty(opts.AnalysesFile) ? RuleFile.LoadEmbeddedFilters() : RuleFile.FromFile(opts.AnalysesFile);
|
||||
var analysisFile = LoadRulesFromFileOrEmbedded(opts.AnalysesFile);
|
||||
|
||||
if (!analysisFile.Rules.Any())
|
||||
{
|
||||
Log.Warning(Strings.Get("Err_NoRules"));
|
||||
return ASA_ERROR.INVALID_RULES;
|
||||
}
|
||||
|
||||
var compareOpts = new CompareCommandOptions(firstCollectRunId, secondCollectRunId)
|
||||
{
|
||||
|
@ -211,6 +224,7 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Cli
|
|||
{
|
||||
if (opts is null) { return new ConcurrentDictionary<(RESULT_TYPE, CHANGE_TYPE), List<CompareResult>>(); }
|
||||
var results = new ConcurrentDictionary<(RESULT_TYPE, CHANGE_TYPE), List<CompareResult>>();
|
||||
var analysesHash = ruleFile.GetHash();
|
||||
Parallel.ForEach(collectObjects, monitorResult =>
|
||||
{
|
||||
var shellResult = new CompareResult()
|
||||
|
@ -220,7 +234,7 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Cli
|
|||
};
|
||||
|
||||
shellResult.Rules = analyzer.Analyze(ruleFile.Rules, shellResult).ToList();
|
||||
shellResult.AnalysesHash = ruleFile.GetHash();
|
||||
shellResult.AnalysesHash = analysesHash;
|
||||
|
||||
if (opts.ApplySubObjectRulesToMonitor)
|
||||
{
|
||||
|
@ -247,8 +261,13 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Cli
|
|||
private static ASA_ERROR RunVerifyRulesCommand(VerifyOptions opts)
|
||||
{
|
||||
var analyzer = new AsaAnalyzer(new AnalyzerOptions(opts.RunScripts));
|
||||
var ruleFile = string.IsNullOrEmpty(opts.AnalysisFile) ? RuleFile.LoadEmbeddedFilters() : RuleFile.FromFile(opts.AnalysisFile);
|
||||
var violations = analyzer.EnumerateRuleIssues(ruleFile.GetRules());
|
||||
var ruleFile = LoadRulesFromFileOrEmbedded(opts.AnalysisFile);
|
||||
if (!ruleFile.Rules.Any())
|
||||
{
|
||||
Log.Warning(Strings.Get("Err_NoRules"));
|
||||
return ASA_ERROR.INVALID_RULES;
|
||||
}
|
||||
var violations = analyzer.EnumerateRuleIssues(ruleFile.Rules);
|
||||
OAT.Utils.Strings.Setup();
|
||||
OAT.Utils.Helpers.PrintViolations(violations);
|
||||
if (violations.Any())
|
||||
|
@ -469,12 +488,19 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Cli
|
|||
}
|
||||
}
|
||||
|
||||
var ruleFile = LoadRulesFromFileOrEmbedded(opts.AnalysesFile);
|
||||
if (!ruleFile.Rules.Any())
|
||||
{
|
||||
Log.Warning(Strings.Get("Err_NoRules"));
|
||||
return ASA_ERROR.INVALID_RULES;
|
||||
}
|
||||
|
||||
Log.Information(Strings.Get("Comparing"), opts.FirstRunId, opts.SecondRunId);
|
||||
|
||||
CompareCommandOptions options = new CompareCommandOptions(opts.FirstRunId, opts.SecondRunId)
|
||||
{
|
||||
DatabaseFilename = opts.DatabaseFilename,
|
||||
AnalysesFile = string.IsNullOrEmpty(opts.AnalysesFile) ? RuleFile.LoadEmbeddedFilters() : RuleFile.FromFile(opts.AnalysesFile),
|
||||
AnalysesFile = ruleFile,
|
||||
DisableAnalysis = opts.DisableAnalysis,
|
||||
SaveToDatabase = opts.SaveToDatabase,
|
||||
RunScripts = opts.RunScripts
|
||||
|
@ -659,10 +685,17 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Cli
|
|||
return ASA_ERROR.INVALID_ID;
|
||||
}
|
||||
}
|
||||
|
||||
var ruleFile = LoadRulesFromFileOrEmbedded(opts.AnalysesFile);
|
||||
if (!ruleFile.Rules.Any())
|
||||
{
|
||||
Log.Warning(Strings.Get("Err_NoRules"));
|
||||
return ASA_ERROR.INVALID_RULES;
|
||||
}
|
||||
var monitorCompareOpts = new CompareCommandOptions(null, opts.RunId)
|
||||
{
|
||||
DisableAnalysis = opts.DisableAnalysis,
|
||||
AnalysesFile = string.IsNullOrEmpty(opts.AnalysesFile) ? RuleFile.LoadEmbeddedFilters() : RuleFile.FromFile(opts.AnalysesFile),
|
||||
AnalysesFile = ruleFile,
|
||||
ApplySubObjectRulesToMonitor = opts.ApplySubObjectRulesToMonitor,
|
||||
RunScripts = opts.RunScripts
|
||||
};
|
||||
|
@ -883,7 +916,8 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Cli
|
|||
watch = Stopwatch.StartNew();
|
||||
var analyzer = new AsaAnalyzer(new AnalyzerOptions(opts.RunScripts));
|
||||
var platform = DatabaseManager.RunIdToPlatform(opts.SecondRunId);
|
||||
var violations = analyzer.EnumerateRuleIssues(opts.AnalysesFile.GetRules());
|
||||
var violations = analyzer.EnumerateRuleIssues(opts.AnalysesFile.Rules);
|
||||
var analysesHash = opts.AnalysesFile.GetHash();
|
||||
OAT.Utils.Strings.Setup();
|
||||
OAT.Utils.Helpers.PrintViolations(violations);
|
||||
if (violations.Any())
|
||||
|
@ -910,7 +944,7 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Cli
|
|||
res.Rules = analyzer.Analyze(selectedRules, res.Base, res.Compare).ToList();
|
||||
res.Analysis = res.Rules.Count
|
||||
> 0 ? res.Rules.Max(x => ((AsaRule)x).Flag) : opts.AnalysesFile.DefaultLevels[res.ResultType];
|
||||
res.AnalysesHash = opts.AnalysesFile.GetHash();
|
||||
res.AnalysesHash = analysesHash;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,20 +13,48 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Objects
|
|||
{
|
||||
public class RuleFile
|
||||
{
|
||||
public RuleFile(Dictionary<RESULT_TYPE, ANALYSIS_RESULT_TYPE>? DefaultLevels = null, List<AsaRule>? Rules = null)
|
||||
/// <summary>
|
||||
/// Create a RuleFile with provided DefaultLevels, Rules and Source name.
|
||||
/// </summary>
|
||||
/// <param name="DefaultLevels"></param>
|
||||
/// <param name="Rules"></param>
|
||||
/// <param name="Source"></param>
|
||||
[JsonConstructor]
|
||||
public RuleFile(Dictionary<RESULT_TYPE, ANALYSIS_RESULT_TYPE>? DefaultLevels = null, IEnumerable<AsaRule>? Rules = null, string? Source = null)
|
||||
{
|
||||
this.DefaultLevels = DefaultLevels ?? this.DefaultLevels;
|
||||
this.Rules = Rules ?? new List<AsaRule>();
|
||||
this.Source = Source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a RuleFile with the default Default Levels and null Source name.
|
||||
/// </summary>
|
||||
/// <param name="Rules"></param>
|
||||
public RuleFile(IEnumerable<AsaRule>? Rules = null) : this(null, Rules, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an empty RuleFile.
|
||||
/// </summary>
|
||||
public RuleFile()
|
||||
{
|
||||
}
|
||||
|
||||
public string? Source { get; set; } // An Identifier for the source of the rules
|
||||
/// <summary>
|
||||
/// An Identifier for the source of the Rules
|
||||
/// </summary>
|
||||
public string? Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The List of Rules
|
||||
/// </summary>
|
||||
public IEnumerable<AsaRule> Rules { get; set; } = new List<AsaRule>();
|
||||
|
||||
/// <summary>
|
||||
/// The Default Levels to apply to objects if there is no corresponding rule.
|
||||
/// </summary>
|
||||
public Dictionary<RESULT_TYPE, ANALYSIS_RESULT_TYPE> DefaultLevels { get; set; } = new Dictionary<RESULT_TYPE, ANALYSIS_RESULT_TYPE>()
|
||||
{
|
||||
{ RESULT_TYPE.CERTIFICATE, ANALYSIS_RESULT_TYPE.INFORMATION },
|
||||
|
@ -46,7 +74,13 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Objects
|
|||
{ RESULT_TYPE.FILEMONITOR, ANALYSIS_RESULT_TYPE.INFORMATION }
|
||||
};
|
||||
|
||||
public static RuleFile FromStream(Stream? stream)
|
||||
/// <summary>
|
||||
/// Generate a RuleFile from a given stream containing a serialized RuleFile.
|
||||
/// </summary>
|
||||
/// <param name="stream">The Stream to Deserialize</param>
|
||||
/// <param name="streamName">The Source Name to set in the RuleFile</param>
|
||||
/// <returns></returns>
|
||||
public static RuleFile FromStream(Stream? stream, string? streamName)
|
||||
{
|
||||
if (stream is null)
|
||||
throw new NullReferenceException(nameof(stream));
|
||||
|
@ -55,8 +89,7 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Objects
|
|||
using (StreamReader file = new StreamReader(stream))
|
||||
{
|
||||
var config = JsonConvert.DeserializeObject<RuleFile>(file.ReadToEnd());
|
||||
if (config.Source is null)
|
||||
config.Source = "Stream";
|
||||
config.Source = streamName ?? (config.Source ?? "Stream");
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
@ -75,11 +108,17 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Objects
|
|||
return new RuleFile();
|
||||
}
|
||||
|
||||
public string GetHash()
|
||||
{
|
||||
return CryptoHelpers.CreateHash(JsonConvert.SerializeObject(this));
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the Hash of the RuleFile
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetHash() => CryptoHelpers.CreateHash(JsonConvert.SerializeObject(this));
|
||||
|
||||
/// <summary>
|
||||
/// Load rules from a serialized RuleFile on disk.
|
||||
/// </summary>
|
||||
/// <param name="filterLoc"></param>
|
||||
/// <returns></returns>
|
||||
public static RuleFile FromFile(string? filterLoc = "")
|
||||
{
|
||||
if (!string.IsNullOrEmpty(filterLoc))
|
||||
|
@ -89,8 +128,7 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Objects
|
|||
using (StreamReader file = System.IO.File.OpenText(filterLoc))
|
||||
{
|
||||
var config = JsonConvert.DeserializeObject<RuleFile>(file.ReadToEnd());
|
||||
if (config.Source is null)
|
||||
config.Source = filterLoc;
|
||||
config.Source = filterLoc;
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
@ -110,6 +148,10 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Objects
|
|||
return new RuleFile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load the default AttackSurfaceAnalyzer Rules embedded in the binary.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static RuleFile LoadEmbeddedFilters()
|
||||
{
|
||||
try
|
||||
|
@ -117,8 +159,7 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Objects
|
|||
var assembly = typeof(FileSystemObject).Assembly;
|
||||
var resourceName = "AttackSurfaceAnalyzer.analyses.json";
|
||||
using Stream stream = assembly.GetManifestResourceStream(resourceName) ?? throw new NullReferenceException($"assembly.GetManifestResourceStream couldn't load {resourceName}");
|
||||
var file = FromStream(stream);
|
||||
file.Source = "Embedded Rules";
|
||||
var file = FromStream(stream, "Embedded Rules");
|
||||
return file;
|
||||
}
|
||||
catch (Exception e) when (
|
||||
|
@ -135,20 +176,13 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Objects
|
|||
return new RuleFile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print a serialization of the filters to the verbose console.
|
||||
/// </summary>
|
||||
public void DumpFilters()
|
||||
{
|
||||
Log.Verbose("Filter dump:");
|
||||
Log.Verbose(JsonConvert.SerializeObject(this));
|
||||
}
|
||||
|
||||
public List<Rule> GetRules()
|
||||
{
|
||||
return Rules.Select(x => (Rule)x).ToList(); ;
|
||||
}
|
||||
|
||||
public List<Rule> GetRulesForPlatform(PLATFORM platform)
|
||||
{
|
||||
return (List<Rule>)Rules.Where(x => x.Platforms.Contains(platform) || !x.Platforms.Any());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,11 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Utils
|
|||
{
|
||||
public static class CryptoHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Perform a hash of a string.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static string CreateHash(string input)
|
||||
{
|
||||
try
|
||||
|
@ -24,19 +29,6 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Utils
|
|||
}
|
||||
}
|
||||
|
||||
public static byte[] CreateHash(byte[] input)
|
||||
{
|
||||
try
|
||||
{
|
||||
return sha512.ComputeHash(input);
|
||||
}
|
||||
catch (CryptographicException e)
|
||||
{
|
||||
Log.Warning(e, Strings.Get("Err_CreateHash"), "bytes");
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
}
|
||||
|
||||
public static string CreateHash(Stream stream)
|
||||
{
|
||||
try
|
||||
|
@ -76,7 +68,6 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Utils
|
|||
|
||||
private static readonly RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
|
||||
|
||||
// These are not intended to be cryptographically secure hashes These are used as a uniqueness check
|
||||
private static readonly HashAlgorithm sha512 = SHA512.Create();
|
||||
private static readonly HashAlgorithm sha512 = SHA512Managed.Create();
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Tests
|
|||
{
|
||||
var analyzer = new AsaAnalyzer();
|
||||
var ruleFile = RuleFile.LoadEmbeddedFilters();
|
||||
Assert.IsTrue(!analyzer.EnumerateRuleIssues(ruleFile.GetRules()).Any());
|
||||
Assert.IsTrue(!analyzer.EnumerateRuleIssues(ruleFile.Rules).Any());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -61,13 +61,14 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Tests
|
|||
|
||||
var opts = new CompareCommandOptions(null, "SecondRun") { ApplySubObjectRulesToMonitor = true };
|
||||
|
||||
var results = AttackSurfaceAnalyzerClient.AnalyzeMonitored(opts, analyzer, new MonitorObject[] { testPathOneObject }, new RuleFile() { Rules = new AsaRule[] { andRule } });
|
||||
var ruleFile = new RuleFile(new AsaRule[] { andRule });
|
||||
var results = AttackSurfaceAnalyzerClient.AnalyzeMonitored(opts, analyzer, new MonitorObject[] { testPathOneObject }, ruleFile);
|
||||
|
||||
Assert.IsTrue(results.Any(x => x.Value.Any(y => y.Identity == testPathOneObject.Identity && y.Rules.Contains(andRule))));
|
||||
|
||||
opts = new CompareCommandOptions(null, "SecondRun") { ApplySubObjectRulesToMonitor = false };
|
||||
|
||||
results = AttackSurfaceAnalyzerClient.AnalyzeMonitored(opts, analyzer, new MonitorObject[] { testPathOneObject }, new RuleFile() { Rules = new AsaRule[] { andRule } });
|
||||
results = AttackSurfaceAnalyzerClient.AnalyzeMonitored(opts, analyzer, new MonitorObject[] { testPathOneObject }, ruleFile);
|
||||
|
||||
Assert.IsFalse(results.Any(x => x.Value.Any(y => y.Identity == testPathOneObject.Identity && y.Rules.Contains(andRule))));
|
||||
}
|
||||
|
@ -75,18 +76,5 @@ namespace Microsoft.CST.AttackSurfaceAnalyzer.Tests
|
|||
private const string TestPathOne = "TestPath1";
|
||||
|
||||
private readonly FileMonitorObject testPathOneObject = new FileMonitorObject(TestPathOne) { FileSystemObject = new FileSystemObject(TestPathOne) { IsExecutable = true } };
|
||||
|
||||
private Analyzer GetAnalyzerForRule(AsaRule rule)
|
||||
{
|
||||
var file = new RuleFile()
|
||||
{
|
||||
Rules = new List<AsaRule>()
|
||||
{
|
||||
rule
|
||||
}
|
||||
};
|
||||
|
||||
return new AsaAnalyzer();
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче