예제 #1
0
        public ImportResult Import(Import import)
        {
            var csvConfiguration = new Configuration();

            csvConfiguration.RegisterClassMap(new ImportDataMap());
            csvConfiguration.MissingFieldFound = null;

            // Get all the records out of the CSV file
            List <ImportData> importRecords;
            bool isDescription = true;

            // Special validation for Verbiage and Description
            using (var reader = _csvFactory.CreateReader(new StreamReader(import.File), csvConfiguration))
            {
                reader.Read();
                reader.ReadHeader();
                List <string> headers = reader.Context.HeaderRecord.ToList();

                if (headers.Contains("Finding (Verbiage)") && headers.Contains("Finding (Description)"))
                {
                    throw new ArgumentException("You can't have both Verbiage and Description columns.");
                }
                else if (headers.Contains("Finding (Verbiage)"))
                {
                    isDescription = false;
                }

                reader.Configuration.UnregisterClassMap();

                if (!isDescription)
                {
                    reader.Configuration.RegisterClassMap(new ImportVerbiageDataMap());
                }
                else
                {
                    reader.Configuration.RegisterClassMap(new ImportDataMap());
                }

                List <ImportData> records = reader.GetRecords <ImportData>().ToList();
                importRecords = records;
            }

            // Get engagement ID and phase ID
            int engagementId = Convert.ToInt32(import.EngagementId);
            var phaseId      = Convert.ToInt32(import.PhaseId);

            // Create and save import entity
            var importEntity = _importMapper.Map(import);

            importEntity.ImportedDate   = DateTime.Now;
            importEntity.AssessmentDate = DateTime.Now;  // TODO: AssessmentDate will eventually be entered in by the user
            _importRepository.Add(importEntity);
            _importRepository.Save();
            _importMapper.Map(importEntity, import);

            // Use this to store HostVulnerabilities and display them properly after importing those rows
            var importId            = importEntity.Id;
            var penultimateImportId = _importRepository.GetPenultimate(engagementId)?.Id ?? null;

            // Get all existing hosts for this engagement and phase
            // Hosts and Vulnerabilities records must be unique (per phase), and so they're only imported once (per phase).
            // Hence, we do not need to worry about the import ID for Hosts and Vulnerabilities.
            var hostEntities = _hostRepository
                               .GetByEngagementId(engagementId)
                               .Where(x => x.PhaseId == phaseId)
                               .ToList();
            var hostsToAdd    = new List <HostEntity>();
            var hostsToUpdate = new List <HostEntity>();

            // Get all existing vulns for this engagement and phase
            var vulnerabilityEntities = _vulnerabilityRepository
                                        .GetByEngagementId(engagementId)
                                        .Where(x => x.PhaseId == phaseId)
                                        .ToList();
            var vulnerabilitiesToAdd    = new List <VulnerabilityEntity>();
            var vulnerabilitiesToUpdate = new List <VulnerabilityEntity>();

            // Get all existing hostVulnerabilities for this engagement and phase
            var hostVulnerabilityEntities = _hostVulnerabilityRepository
                                            .GetByEngagementId(engagementId)
                                            .Where(x => x.Vulnerability.PhaseId == phaseId && x.Host.PhaseId == phaseId && x.ImportId == importId)
                                            .ToList();
            var hostVulnerabilitiesToAdd    = new List <HostVulnerabilityEntity>();
            var hostVulnerabilitiesToUpdate = new List <HostVulnerabilityEntity>();

            // Iterate through each CSV record, grouped by Finding ("Title")
            var hostVulnerabilityImportGroups = importRecords.GroupBy(x => new { x.Title, x.Port, x.Service, x.IPAddress, x.HostName });

            foreach (var importRecordGroup in hostVulnerabilityImportGroups)
            {
                // Encrypt sensitive fields
                var titleBytes             = Encrypt(importRecordGroup.Key.Title);
                var portBytes              = Encrypt(int.Parse(importRecordGroup.Key.Port));
                var serviceBytes           = Encrypt(importRecordGroup.Key.Service);
                var ipAddressBytes         = Encrypt(importRecordGroup.Key.IPAddress);
                var hostNameBytes          = Encrypt(importRecordGroup.Key.HostName);
                var firstImportRecordGroup = importRecordGroup.First();

                // Create or update a vulnerability entity for this CSV record
                // NOTE: All imports share a single set of unique vulnerabilities
                var vulnerabilityEntity = AddOrUpdateEntity(
                    x => x.TitleBytes.SequenceEqual(titleBytes) &&
                    x.PortBytes.SequenceEqual(portBytes) &&
                    x.ServiceBytes.SequenceEqual(serviceBytes),
                    vulnerabilityEntities,
                    vulnerabilitiesToAdd,
                    vulnerabilitiesToUpdate);
                vulnerabilityEntity.IsStatusUnknown = false;
                if (vulnerabilityEntity.IsHistorical)
                {
                    vulnerabilityEntity.IsHistorical        = false;
                    vulnerabilityEntity.RemediationStatusId = 1; // MitigationStatus.NotMitigated.Value;
                    vulnerabilityEntity.MitigatedDate       = null;
                }

                // RemediationStatusId is technically a nullable field, but upon import we should always
                // set a default of NotMitigated.
                if (vulnerabilityEntity.RemediationStatusId == null)
                {
                    vulnerabilityEntity.RemediationStatusId = 1; //MitigationStatus.NotMitigated.Value;
                }
                _importVulnerabilityMapper.Map(firstImportRecordGroup, import, vulnerabilityEntity);

                // Create or update a host for this CSV record
                // NOTE: All imports in a phase share a single set of unique hosts
                var hostEntity = AddOrUpdateEntity(
                    x => x.IPAddressBytes.SequenceEqual(ipAddressBytes) &&
                    x.NameBytes.SequenceEqual(hostNameBytes),
                    hostEntities,
                    hostsToAdd,
                    hostsToUpdate);
                hostEntity.Status  = "Active";
                hostEntity.PhaseId = phaseId;
                _importHostMapper.Map(firstImportRecordGroup, import, hostEntity);

                // Create a partially-encrypted hostVuln for this CSV record
                // NOTE: HostVulnerabilities are always added as new records during the import process
                AddEntity(
                    x => x.Vulnerability.TitleBytes.SequenceEqual(titleBytes) &&
                    x.Vulnerability.PortBytes.SequenceEqual(portBytes) &&
                    x.Vulnerability.ServiceBytes.SequenceEqual(serviceBytes) &&
                    x.Host.IPAddressBytes.SequenceEqual(ipAddressBytes) &&
                    x.Host.NameBytes.SequenceEqual(hostNameBytes),
                    hostVulnerabilityEntities,
                    hostVulnerabilitiesToAdd,
                    hostVulnerabilitiesToUpdate,
                    CreateHostVulnerability(engagementId, phaseId, hostEntity, vulnerabilityEntity, importEntity));
            }

            // Write new HostVulnerabilities to the database
            if (hostVulnerabilitiesToAdd.Any())
            {
                _hostVulnerabilityRepository.AddRange(hostVulnerabilitiesToAdd);
            }
            _hostVulnerabilityRepository.Save();
            _hostRepository.Save();
            _vulnerabilityRepository.Save();

            // Determine status of every host entity
            var hostsToAddOrUpdate = hostsToAdd.Union(hostsToUpdate).ToArray();
            var hostsToMarkOffline = hostEntities.Except(hostsToAddOrUpdate);

            // Another pass through the host entities is required to figure out which hosts are missing, i.e., 'Offline'
            foreach (var hostEntity in hostEntities)
            {
                // TODO offline vs. retired
                if (hostsToMarkOffline.Contains(hostEntity))
                {
                    hostEntity.Status = "Offline";
                }
                else if (hostsToAddOrUpdate.Contains(hostEntity))
                {
                    hostEntity.Status = "Active";
                }
            }

            // Do a vuln delta check between latest and penultimate imports and adjust vuln remediation metadata
            var vulnerabilityEntitiesToAdd = ProcessVulnerabilityChanges(
                hostVulnerabilityEntities,
                vulnerabilityEntities,
                hostEntities,
                importId,
                penultimateImportId,
                phaseId,
                importEntity.AssessmentDate);

            // Save Hosts and Vulnerabilities
            _hostVulnerabilityRepository.Save();
            _hostRepository.Save();
            _vulnerabilityRepository.Save();

            // Return vuln and host insert and update counts
            return(new ImportResult(vulnerabilitiesToAdd.Count, vulnerabilitiesToUpdate.Count, hostsToAdd.Count, hostsToUpdate.Count));
        }
예제 #2
0
        public Dashboard Get(string chartSet, int engagementId)
        {
            var dashboard = new Dashboard();

            if (_engagementService.Get(engagementId) == null)
            {
                return(dashboard);
            }

            var engagement = _engagementRepository.Get(engagementId);
            var customer   = _customerRepository.Get(engagement.CustomerId);

            var latestImportId      = _importRepository.GetLatest(engagementId)?.Id;
            var penultimateImportId = _importRepository.GetPenultimate(engagementId)?.Id;

            MapEngagement(engagement, dashboard);
            MapCustomer(customer, dashboard);

            if (chartSet == "dashboard")
            {
                var phaseEntities = _phaseRepository.GetByEngagementId(engagementId).ToList();
                var riskEntities  = _riskRepository.GetByEngagementId(engagementId).ToList();

                MapRiskGauge(engagement, dashboard);
                MapMitigationSummaryVulnsByRisk(riskEntities, dashboard);
                MapMitigationSummaryRisksByPhase(phaseEntities, dashboard);
                MapMitigationSummaryRisksAndVulns(engagementId, riskEntities, phaseEntities, dashboard);
            }

            else if (chartSet == "compliance")
            {
                foreach (var complianceScheme in _complianceSchemeRepository.GetByEngagementId(engagementId))
                {
                    var complianceEntities = _complianceRepository.GetByEngagementId(engagementId, complianceScheme.Id).ToList();

                    MapComplianceByGapReview(complianceEntities, complianceScheme, dashboard);
                    MapComplianceByMaturityLevel(complianceEntities, complianceScheme, dashboard);
                }
            }

            else if (chartSet == "governance")
            {
                var governanceControlEntities = _governanceControlRepository.GetByEngagementId(engagementId).ToList();

                MapGovernanceControlsByRiskLevel(governanceControlEntities, dashboard);
                MapGovernanceControlsByMaturityLevel(governanceControlEntities, dashboard);
            }

            else if (chartSet == "risk")
            {
                var riskEntities = _riskRepository.GetByEngagementId(engagementId).ToList();

                MapRiskByImpact(riskEntities, dashboard);
                MapRiskByLikelihood(riskEntities, dashboard);
                MapRiskByScore(riskEntities, dashboard);
                MapRiskByPhase(riskEntities, dashboard);
                MapTopRiskByScore(riskEntities, dashboard);
            }

            else if (chartSet == "host")
            {
                var hostEntities = _hostRepository.GetByEngagementId(engagementId).ToList();

                MapHostsByOperatingSystem(hostEntities, dashboard);
            }

            else if (chartSet == "vulnerability")
            {
                var vulnerabilityEntities = _vulnerabilityRepository.GetByEngagementId(engagementId).ToList();

                MapVulnerabilitiesBySeverity(vulnerabilityEntities, dashboard);
                MapVulnerabilitiesByCategory(vulnerabilityEntities, dashboard, latestImportId);
                MapVulnerabilities(vulnerabilityEntities, dashboard);
            }

            else if (chartSet == "risk")
            {
                var phaseEntities = _phaseRepository.GetByEngagementId(engagementId).ToList();

                MapRiskScoreByPhase(phaseEntities, dashboard);
            }

            return(dashboard);
        }