Содержание
Getting Started
Getting AsaLib
Search Nuget for Microsoft.CST.AttackSurfaceAnalyzer.
API Documentation
API Documentation is available at https://microsoft.github.io/AttackSurfaceAnalyzer/.
Using AsaLib
Setting up for using the database (optional)
DatabaseManager.Setup(dbPath);
For logging messages (optional)
Logger.Setup(false, true);
Strings.Setup();
Disable telemetry (optional)
AsaTelemetry.Setup(test: true);
Collecting
Collecting gathers the current state of the system.
Collecting using a Delegate (recommended)
The recommended use pattern is to provide your own Change Handler that will be called on every CollectObject discovered by the Collector.
If you collect using a delegate the results will not be populated in the Results field of the Collector (thus reducing memory usage).
ConcurrentStack<CollectObject> stack = new ConcurrentStack<CollectObject>();
void MyFunction(CollectObject collectObject) {
// Do something with each CollectObject
// For example, print it out and put it on a stack
Console.WriteLine($"Found {collectObject.Identity}");
stack.Push(collectObject);
}
var cc = new CertificateCollector(changeHandler: collectObject => MyFunction(collectObject));
cc.Execute();
In-Memory
You can also perform collections and store the results in the Collector.
For larger collections, for example, full File System or Registry collections, this will consume large amounts of memory. If you can perform actions as results are processed, you should use the Delegate declaration available for each Collector instead.
var cc = new CertificateCollector();
cc.Execute();
ConcurrentStack<CollectObject> results = cc.Results;
Collecting using the ASA Database API
Alternately, you can write the results to the database.
The call to DatabaseManager.Write
actually adds the result into a queue to be written asynchronously. You must ensure that all results have been written before Committing the results to the database. You can use WaitUntilFlushed()
to sleep the main thread until the queue has been flushed.
var cc = new CertificateCollector(
changeHandler: collectObject => DatabaseManager.Write(collectObject, RunId));
cc.Execute();
DatabaseManager.WaitUntilFlushed();
DatabaseManager.Commit();
Monitoring
Monitoring gathers changes as they happen, but does not gather an underlying snapshot of the system.
Monitoring the File System
void PrintFileName(FileMonitorObject fmo)
{
Console.WriteLine($"{fmo.NotifyFilters} type change was detected on {fmo.Path}");
}
MonitorCommandOptions opts = new MonitorCommandOptions()
{
MonitoredDirectories = "paths/to/monitor,separated/by/commas"
}
var monitor = new FileSystemMonitor(opts, x => PrintFileName(x)));
monitor.StartRun();
// Behavior under test
monitor.StopRun();
Comparing
From the database
BaseCompare bc = new BaseCompare();
if (bc.TryCompare(FirstRunId, SecondRunId))
{
ConcurrentDictionary<(RESULT_TYPE, CHANGE_TYPE), List<CompareResult>> results = bc.Results;
}
else
{
// There was some error while comparing
}
From memory
IEnumerable<CollectObject> FirstRunItems; // Your results from the first collection
IEnumerable<CollectObject> SecondRunItems; // Your results from the second collection
BaseCompare bc = new BaseCompare();
bc.TryCompare(FirstRunItems, FirstRunItems, FirstRunId, SecondRunId);
ConcurrentDictionary<(RESULT_TYPE, CHANGE_TYPE), List<CompareResult>> results = bc.Results;
Analyzing
Analysis is performed on CompareResult
objects from BaseCompare.Compare
. The sample code below updates the CompareResult
s with their analysis status in place.
BaseCompare bc = new BaseCompare();
bc.TryCompare(DifferentItems,ModifiedItems,FirstRunId,SecondRunId);
IEnumerable<Rule> rules; // Your rules
var analyzer = new AsaAnalyzer();
if (analyzer.EnumerateRuleIssues(rules).Any()){
// Error With Rules
}
else {
foreach (var key in bc.Results.Keys)
{
if (bc.Results[key] is List<CompareResult> queue)
{
queue.AsParallel().ForAll(res =>
{
res.Rules = analyzer.Analyze(rules, res);
res.Analysis = res.Rules.Max(x => x.Flag);
});
}
}
}