Skip to content

Calculator 计算器

Calculator 是 CVSS Parser 中用于计算 CVSS 评分的核心组件。它提供了完整的 CVSS 3.x 评分计算功能,包括基础评分、时间评分和环境评分。

接口定义

go
type Calculator interface {
    Calculate() (float64, error)
    CalculateBaseScore() (float64, error)
    CalculateTemporalScore() (float64, error)
    CalculateEnvironmentalScore() (float64, error)
    GetSeverityRating(score float64) string
}

创建计算器

NewCalculator

go
func NewCalculator(vector *Cvss3x) Calculator

创建一个新的计算器实例。

参数:

  • vector: 要计算的 CVSS 3.x 向量

返回值:

  • Calculator: 计算器实例

示例:

go
calculator := cvss.NewCalculator(cvssVector)

主要方法

Calculate

go
func (c *Calculator) Calculate() (float64, error)

计算最终的 CVSS 评分。根据向量中包含的指标类型,自动选择合适的计算方法:

  • 仅基础指标:返回基础评分
  • 包含时间指标:返回时间评分
  • 包含环境指标:返回环境评分

返回值:

  • float64: CVSS 评分 (0.0-10.0)
  • error: 计算错误

示例:

go
score, err := calculator.Calculate()
if err != nil {
    log.Fatalf("计算失败: %v", err)
}
fmt.Printf("CVSS 评分: %.1f\n", score)

CalculateBaseScore

go
func (c *Calculator) CalculateBaseScore() (float64, error)

计算 CVSS 基础评分,仅基于基础指标。

计算公式:

如果 (影响子分 <= 0)
    基础评分 = 0
否则
    如果 (范围 == 不变)
        基础评分 = 向上取整(最小值((影响 + 可利用性), 10))
    否则
        基础评分 = 向上取整(最小值(1.08 × (影响 + 可利用性), 10))

示例:

go
baseScore, err := calculator.CalculateBaseScore()
if err != nil {
    log.Fatalf("基础评分计算失败: %v", err)
}
fmt.Printf("基础评分: %.1f\n", baseScore)

CalculateTemporalScore

go
func (c *Calculator) CalculateTemporalScore() (float64, error)

计算时间评分,基于基础评分和时间指标。

计算公式:

时间评分 = 向上取整(基础评分 × 利用代码成熟度 × 修复级别 × 报告置信度)

示例:

go
temporalScore, err := calculator.CalculateTemporalScore()
if err != nil {
    log.Fatalf("时间评分计算失败: %v", err)
}
fmt.Printf("时间评分: %.1f\n", temporalScore)

CalculateEnvironmentalScore

go
func (c *Calculator) CalculateEnvironmentalScore() (float64, error)

计算环境评分,基于修改后的基础指标和环境指标。

计算公式:

修改后影响 = 最小值(1 - [(1-机密性需求×修改后机密性影响) × (1-完整性需求×修改后完整性影响) × (1-可用性需求×修改后可用性影响)], 0.915)

修改后可利用性 = 8.22 × 修改后攻击向量 × 修改后攻击复杂性 × 修改后权限要求 × 修改后用户交互

如果 (修改后影响 <= 0)
    环境评分 = 0
否则
    如果 (修改后范围 == 不变)
        环境评分 = 向上取整(向上取整(最小值((修改后影响 + 修改后可利用性), 10)) × 利用代码成熟度 × 修复级别 × 报告置信度)
    否则
        环境评分 = 向上取整(向上取整(最小值(1.08 × (修改后影响 + 修改后可利用性), 10)) × 利用代码成熟度 × 修复级别 × 报告置信度)

示例:

go
envScore, err := calculator.CalculateEnvironmentalScore()
if err != nil {
    log.Fatalf("环境评分计算失败: %v", err)
}
fmt.Printf("环境评分: %.1f\n", envScore)

GetSeverityRating

go
func (c *Calculator) GetSeverityRating(score float64) string

根据 CVSS 评分获取对应的严重性等级。

评分范围和等级:

评分范围严重性等级英文
0.0None
0.1-3.9低危Low
4.0-6.9中危Medium
7.0-8.9高危High
9.0-10.0严重Critical

示例:

go
score := 7.5
severity := calculator.GetSeverityRating(score)
fmt.Printf("评分 %.1f 对应严重性: %s\n", score, severity) // "High"

完整示例

基本使用

go
package main

import (
    "fmt"
    "log"
    
    "github.com/scagogogo/cvss-parser/pkg/cvss"
    "github.com/scagogogo/cvss-parser/pkg/parser"
)

func main() {
    // 解析 CVSS 向量
    vectorStr := "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
    p := parser.NewCvss3xParser(vectorStr)
    vector, err := p.Parse()
    if err != nil {
        log.Fatalf("解析失败: %v", err)
    }
    
    // 创建计算器
    calculator := cvss.NewCalculator(vector)
    
    // 计算各种评分
    baseScore, err := calculator.CalculateBaseScore()
    if err != nil {
        log.Fatalf("基础评分计算失败: %v", err)
    }
    
    finalScore, err := calculator.Calculate()
    if err != nil {
        log.Fatalf("最终评分计算失败: %v", err)
    }
    
    severity := calculator.GetSeverityRating(finalScore)
    
    // 输出结果
    fmt.Printf("CVSS 向量: %s\n", vectorStr)
    fmt.Printf("基础评分: %.1f\n", baseScore)
    fmt.Printf("最终评分: %.1f\n", finalScore)
    fmt.Printf("严重性等级: %s\n", severity)
}

批量计算

go
func calculateBatch(vectors []string) {
    for _, vectorStr := range vectors {
        p := parser.NewCvss3xParser(vectorStr)
        vector, err := p.Parse()
        if err != nil {
            fmt.Printf("解析失败 %s: %v\n", vectorStr, err)
            continue
        }
        
        calculator := cvss.NewCalculator(vector)
        score, err := calculator.Calculate()
        if err != nil {
            fmt.Printf("计算失败 %s: %v\n", vectorStr, err)
            continue
        }
        
        severity := calculator.GetSeverityRating(score)
        fmt.Printf("%s -> %.1f (%s)\n", vectorStr, score, severity)
    }
}

详细分析

go
func detailedAnalysis(vectorStr string) {
    p := parser.NewCvss3xParser(vectorStr)
    vector, err := p.Parse()
    if err != nil {
        log.Fatalf("解析失败: %v", err)
    }
    
    calculator := cvss.NewCalculator(vector)
    
    // 计算所有类型的评分
    baseScore, _ := calculator.CalculateBaseScore()
    
    var temporalScore, envScore float64
    
    // 检查是否有时间指标
    if vector.Cvss3xTemporal != nil {
        temporalScore, _ = calculator.CalculateTemporalScore()
    }
    
    // 检查是否有环境指标
    if vector.Cvss3xEnvironmental != nil {
        envScore, _ = calculator.CalculateEnvironmentalScore()
    }
    
    finalScore, _ := calculator.Calculate()
    severity := calculator.GetSeverityRating(finalScore)
    
    fmt.Printf("=== CVSS 评分分析 ===\n")
    fmt.Printf("向量: %s\n", vectorStr)
    fmt.Printf("基础评分: %.1f\n", baseScore)
    
    if temporalScore > 0 {
        fmt.Printf("时间评分: %.1f\n", temporalScore)
    }
    
    if envScore > 0 {
        fmt.Printf("环境评分: %.1f\n", envScore)
    }
    
    fmt.Printf("最终评分: %.1f\n", finalScore)
    fmt.Printf("严重性等级: %s\n", severity)
}

错误处理

计算器可能返回以下类型的错误:

常见错误

go
score, err := calculator.Calculate()
if err != nil {
    switch e := err.(type) {
    case *cvss.InvalidVectorError:
        fmt.Printf("无效向量: %s\n", e.Message)
    case *cvss.MissingMetricError:
        fmt.Printf("缺少必需指标: %s\n", e.Metric)
    case *cvss.CalculationError:
        fmt.Printf("计算错误: %s\n", e.Message)
    default:
        fmt.Printf("未知错误: %v\n", err)
    }
}

验证向量

go
func validateVector(vector *cvss.Cvss3x) error {
    // 检查基础指标是否完整
    if vector.Cvss3xBase.AttackVector == nil {
        return fmt.Errorf("缺少攻击向量指标")
    }
    
    if vector.Cvss3xBase.AttackComplexity == nil {
        return fmt.Errorf("缺少攻击复杂性指标")
    }
    
    // ... 检查其他必需指标
    
    return nil
}

性能优化

重用计算器

go
// 对于大量计算,重用计算器实例
calculator := cvss.NewCalculator(nil)

for _, vector := range vectors {
    calculator.SetVector(vector)
    score, err := calculator.Calculate()
    if err != nil {
        continue
    }
    
    // 处理评分...
}

并发计算

go
func concurrentCalculation(vectors []*cvss.Cvss3x) []float64 {
    results := make([]float64, len(vectors))
    var wg sync.WaitGroup
    
    for i, vector := range vectors {
        wg.Add(1)
        go func(index int, v *cvss.Cvss3x) {
            defer wg.Done()
            
            calculator := cvss.NewCalculator(v)
            score, err := calculator.Calculate()
            if err != nil {
                results[index] = 0
                return
            }
            
            results[index] = score
        }(i, vector)
    }
    
    wg.Wait()
    return results
}

相关文档

Released under the MIT License.