Exemplo n.º 1
0
        private async Task WriteSingleItem(SubscriptionScanDetails result, CancellationToken cancellation)
        {
            var resultFolder = Path.Combine(this.folderPath, result.Id);

            if (!Directory.Exists(resultFolder))
            {
                Directory.CreateDirectory(resultFolder);
            }

            for (var i = 0; i < result.ResultFiles.Count; i++)
            {
                var destPath = Path.Combine(resultFolder, result.ResultFiles[i].FileName);
                await using (Stream source = File.Open(result.ResultFiles[i].FullPath, FileMode.Open))
                {
                    await using Stream destination = File.Create(destPath);
                    await source.CopyToAsync(destination, cancellation);
                }

                result.ResultFiles[i].FullPath = destPath;
            }

            var metadata   = Path.Combine(resultFolder, $"meta.json");
            var jsonResult = JsonSerializerWrapper.Serialize(result);
            await File.WriteAllTextAsync(metadata, jsonResult, cancellation);

            Logger.Information("{AzureSubscription} scanning result was written to {Folder}", result.Subscription, resultFolder);
        }
Exemplo n.º 2
0
        /// <inheritdoc />
        public async Task UploadAsync(SubscriptionScanDetails details, CancellationToken cancellation)
        {
            Logger.Information("Uploading scan details for {AzureSubscription} with result {ScanResult}", details.Subscription, details.ScanResult);

            var folder = BlobFolderNameGenerator.ForDate(details.Timestamp);

            var metadata = await this.UploadAuditResult(details, folder, cancellation);

            await this.UploadAuditMetadata(folder, metadata, cancellation);

            await this.UpdateScannerMetadata(cancellation);
        }
Exemplo n.º 3
0
        private async Task <string> UploadSingleAuditFile(SubscriptionScanDetails details, string folder, CancellationToken cancellation, ResultFile resultFile)
        {
            var auditPath = $"{folder}/{resultFile.FileName}";

            Logger.Information("Uploading scan result for {AzureSubscription} to {AuditPath}", details.Subscription, auditPath);

            var resultUrl  = new Uri($"{this.blobCfg.BasePath}/{auditPath}?{this.blobCfg.Sas}");
            var resultBlob = new CloudBlockBlob(resultUrl);
            await resultBlob.UploadFromFileAsync(
                resultFile.FullPath,
                AccessCondition.GenerateEmptyCondition(),
                new BlobRequestOptions
            {
                RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(10), 3),
            },
                new OperationContext(),
                cancellation);

            return(auditPath);
        }
Exemplo n.º 4
0
        private async Task <AuditMetadata> UploadAuditResult(SubscriptionScanDetails details, string folder, CancellationToken cancellation)
        {
            var metadata = new AuditMetadata
            {
                AuditId        = Guid.NewGuid().ToString(),
                ScannerVersion = this.scannerVersion,
                Periodicity    = this.scannerCfg.Periodicity,
                AzSkVersion    = this.azskVersion,
                Timestamp      = ((DateTimeOffset)details.Timestamp).ToUnixTimeSeconds(),
            };

            if (details.ScanResult == ScanResult.Succeeded)
            {
                try
                {
                    var tasks = details
                                .ResultFiles
                                .Select(rf => this.UploadSingleAuditFile(details, folder, cancellation, rf))
                                .ToArray();
                    var taskResults = await Task.WhenAll(tasks);

                    metadata.AuditResult    = "succeeded";
                    metadata.AzSkAuditPaths = tasks.Select(i => i.Result).ToArray();
                }
                catch (Exception ex)
                {
                    Logger.Warning(ex, "Audit result upload failed");
                    metadata.AuditResult        = "upload-failed";
                    metadata.FailureDescription = ex.Message;
                }
            }
            else
            {
                // TODO: add failure description
                metadata.AuditResult = "audit-failed";
            }

            return(metadata);
        }
Exemplo n.º 5
0
 public async Task UploadAsync(SubscriptionScanDetails details, CancellationToken cancellation)
 {
     await this.WriteSingleItem(details, cancellation);
 }
Exemplo n.º 6
0
        public async Task <SubscriptionScanDetails> Scan(string subscription, DateTime scanDate)
        {
            Logger.Information("{AzureSubscription} scan was started", subscription);

            var customOutputFolder = Path.Combine(ScanResultsFolder, CreateRandomFileName($"{subscription}_", 6));

            Directory.CreateDirectory(customOutputFolder);
            Logger.Information("Output directory is {OutputDirectory}", customOutputFolder);

            // commands that will be executed by powershell
            var arguments =
                $"-File {this.scannerCfg.AuditScriptPath} " +
                $"-SubscriptionId {subscription} -TenantId {this.scannerCfg.TenantId} " +
                $"-ServicePrincipalId {this.scannerCfg.ServicePrincipalId} -ServicePrincipalPassword {this.scannerCfg.ServicePrincipalPassword} " +
                $"-OutputFolder {customOutputFolder} -NonInteractive";

            Logger.Debug("Powershell arguments: {StandardError}", arguments);

            try
            {
                var processStartInfo = new ProcessStartInfo
                {
                    FileName  = "powershell",
                    Arguments = arguments,
                };

                var cts = new CancellationTokenSource(TimeSpan.FromMinutes(60));

                var processResults = await ProcessEx.RunAsync(processStartInfo, cts.Token);

                if (processResults.StandardError != null && processResults.StandardError.Length > 0)
                {
                    Logger.Warning("Errors: {StandardError}", string.Join(Environment.NewLine, processResults.StandardError));
                }

                Logger.Debug("Stdout: {StandardOutput}", string.Join(Environment.NewLine, processResults.StandardOutput));

                Logger
                .Information(
                    "{AzureSubscription} scan was finished with exit code {ExitCode} in {ScanningTime}",
                    subscription,
                    processResults.ExitCode,
                    processResults.RunTime);

                var result = SubscriptionScanDetails.New();
                result.Subscription = subscription;
                result.ResultFiles  = new List <ResultFile>();

                // Results directory looks like ./AzSKLogs/Sub_VSE BizSpark/20200211_153220_GRS/
                // Log files and json result are located in subfolder "Etc"
                var dirs = new DirectoryInfo(customOutputFolder).GetDirectories()[0].GetDirectories()[0].GetDirectories();

                foreach (var dir in dirs)
                {
                    result.ResultFiles.Add(await AggregateLogs(dir.GetFileSystemInfos("Etc/*.LOG"), dir));

                    var report = dir.GetFileSystemInfos("Etc/SecurityEvaluationData*.json").FirstOrDefault();
                    if (report != null)
                    {
                        result.ResultFiles.Add(new ResultFile(report.Name, report.FullName));
                    }
                }

                if (processResults.ExitCode != 0)
                {
                    var logs = string.Join(Environment.NewLine, processResults.StandardOutput);
                    Logger.Error("{AzureSubscription} scan failed: {FailedScanLogs}", subscription, logs);

                    result.ScanResult = ScanResult.Failed;
                }
                else
                {
                    Logger.Information("{AzureSubscription} was succeeded", subscription);

                    result.ScanResult = ScanResult.Succeeded;
                }

                return(result);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "{AzureSubscription} scan failed", subscription);

                var result = SubscriptionScanDetails.New();
                result.Subscription = subscription;
                result.ScanResult   = ScanResult.Failed;

                return(result);
            }
        }