예제 #1
0
// Calculate a risk scenario, uses information from the RRA
func riskRRAScenario(op opContext, rs *slib.RRAServiceRisk, src slib.RRAAttribute, desc string) error {
	newscen := slib.RiskScenario{
		Name:     "RRA derived risk for " + desc,
		Coverage: "none",
		NoData:   true,
	}
	if src.Impact != 0 && src.Probability != 0 {
		// Cap the maximum probability we will use on the RRA at 2.0 (MEDIUM).
		// Some older RRAs (and some new ones) don't have correct probability
		// values set; once these are revisted we might be able to remove the
		// cap but for now set it to 2.
		if src.Probability > 2 {
			newscen.Probability = 2
		} else {
			newscen.Probability = src.Probability
		}
		newscen.Impact = src.Impact
		newscen.Score = newscen.Impact * newscen.Probability
		newscen.Coverage = "complete"
		newscen.NoData = false
	}
	err := newscen.Validate()
	if err != nil {
		return err
	}
	rs.Scenarios = append(rs.Scenarios, newscen)
	return nil
}
예제 #2
0
func riskVulnerabilityScenario(op opContext, rs *slib.RRAServiceRisk,
	src slib.RRAAttribute, desc string) error {
	// Utilize the likelihood indicator set with the vulnerabilty score
	// as the probability for the calculation; this will range from
	// 1 to 4.
	datacount := 0
	hostcount := 0
	highest := 1.0
	probincrease := 0.0
	for _, x := range rs.RRA.SupportGrps {
		for _, y := range x.Host {
			hostcount++
			if !y.VulnStatus.Coverage {
				continue
			}
			datacount++
			if float64(y.VulnStatus.LikelihoodIndicator) > highest {
				highest = float64(y.VulnStatus.LikelihoodIndicator)
			}

			// If the host currently has known high or maximum impact issues,
			// take a look at the number of days max or high impact issues
			// have been known to exist for this host. If it meets or exceeds the
			// vuln_maxhigh_graceperiod configuration option in days, the
			// probability will be increased by 1.
			if y.VulnStatus.Maximum > 0 || y.VulnStatus.High > 0 {
				if y.VulnStatus.Last90Days.DaysWithMaximum >= cfg.Risk.VulnMaxHighGracePeriod ||
					y.VulnStatus.Last90Days.DaysWithHigh >= cfg.Risk.VulnMaxHighGracePeriod {
					probincrease = 1.0
				}
			}
		}
	}
	if datacount == 0 || src.Impact == 0 {
		newscan := slib.RiskScenario{
			Name:     "Vulnerability scenario for " + desc,
			Coverage: "none",
			NoData:   true,
		}
		rs.Scenarios = append(rs.Scenarios, newscan)
		return nil
	}
	coverage := "complete"
	if datacount != hostcount {
		coverage = "partial"
	}

	// Apply the probability increase if we aren't already at 4.0; assume it can be
	// a max increase of one for now.
	if highest <= 3.0 {
		highest += probincrease
	}

	// Set coverage to unknown as currently it is not possible to tell
	// if all hosts are being assessed; we can't go by there being no
	// known issues on the asset.
	newscen := slib.RiskScenario{
		Name:        "Vulnerability scenario for " + desc,
		Impact:      src.Impact,
		Probability: highest,
		Score:       highest * src.Impact,
		Coverage:    coverage,
		NoData:      false,
	}
	err := newscen.Validate()
	if err != nil {
		return err
	}
	rs.Scenarios = append(rs.Scenarios, newscen)

	return nil
}
예제 #3
0
// Calculate a risk scenario, uses compliance data as probability metric
func riskComplianceScenario(op opContext, rs *slib.RRAServiceRisk,
	src slib.RRAAttribute, desc string) error {
	// Calculate our step value based on the number of compliance checks
	// that have been executed for supporting hosts
	//
	// XXX We should filter compliance checks here that do not make sense
	// for a the service (e.g., filter out MAXIMUM related checks for low
	// requirement services, but this information isn't really captured
	// anywhere right now
	totalcnt := 0
	coverage := "complete"
	for _, x := range rs.RRA.SupportGrps {
		for _, y := range x.Host {
			var inc int
			inc += y.CompStatus.HighFail
			inc += y.CompStatus.HighPass
			inc += y.CompStatus.MediumFail
			inc += y.CompStatus.MediumPass
			inc += y.CompStatus.LowFail
			inc += y.CompStatus.LowPass
			totalcnt += inc

			// See if a host reported nothing, if so downgrade the
			// coverage
			if inc == 0 {
				coverage = "partial"
			}
		}
	}
	// If totalcnt is zero, or the Impact value is 0, we didn't have any data points.
	if totalcnt == 0 || src.Impact == 0 {
		ndp := slib.RiskScenario{
			Name:     "Compliance scenario for " + desc,
			NoData:   true,
			Coverage: "none",
		}
		rs.Scenarios = append(rs.Scenarios, ndp)
		return nil
	}
	stepv := 3.0 / float64(totalcnt)
	scr := 1.0
	for _, x := range rs.RRA.SupportGrps {
		for _, y := range x.Host {
			scr += stepv * float64(y.CompStatus.HighFail)
			scr += stepv * float64(y.CompStatus.MediumFail)
			scr += stepv * float64(y.CompStatus.LowFail)
		}
	}

	// Cap the maximum possible probability for compliance scenarios
	// off at 2.0; these events do not include a likelihood indicator
	// we will use directly but they are not considered to ever raise
	// probability to "high" or greater
	if scr > 2.0 {
		scr = 2.0
	}

	newscen := slib.RiskScenario{
		Name:        "Compliance scenario for " + desc,
		Impact:      src.Impact,
		Probability: scr,
		Score:       src.Impact * scr,
		Coverage:    coverage,
		NoData:      false,
	}
	err := newscen.Validate()
	if err != nil {
		return err
	}
	rs.Scenarios = append(rs.Scenarios, newscen)

	return nil
}
예제 #4
0
// Add scenarios based on available HTTP observatory metrics
func riskHTTPObsScenario(op opContext, rs *slib.RRAServiceRisk,
	src slib.RRAAttribute, desc string) error {
	// The score here will range from 1 to 4, based on deriving the
	// value from the 0 -> 100 score returned by the httpobs scanner
	// and grader.
	totalcnt := 0
	havecnt := 0
	highest := 0.0
	for _, x := range rs.RRA.SupportGrps {
		for _, y := range x.Website {
			totalcnt++
			if !y.HTTPObs.Coverage {
				continue
			}
			havecnt++
			var uval int
			// If the site scores 75 or higher, treat is as LOW.
			// probability. The observatory does not provide a likelihood
			// indicator directly. If the score is below 75, treat
			// it as MEDIUM.
			if y.HTTPObs.Score >= 75 {
				uval = 1
			} else {
				uval = 2
			}
			if float64(uval) >= highest {
				highest = float64(uval)
			}
		}
	}

	if havecnt == 0 {
		newscan := slib.RiskScenario{
			Name:     "httpobs scenario for " + desc,
			Coverage: "none",
			NoData:   true,
		}
		rs.Scenarios = append(rs.Scenarios, newscan)
		return nil
	}
	coverage := "complete"
	if havecnt != totalcnt {
		coverage = "partial"
	}
	// Set coverage to unknown as currently it is not possible to tell
	// if all hosts are being assessed; we can't go by there being no
	// known issues on the asset.
	newscen := slib.RiskScenario{
		Name:        "httpobs scenario for " + desc,
		Impact:      src.Impact,
		Probability: highest,
		Score:       highest * src.Impact,
		Coverage:    coverage,
		NoData:      false,
	}
	err := newscen.Validate()
	if err != nil {
		return err
	}
	rs.Scenarios = append(rs.Scenarios, newscen)

	return nil
}