Completed
Push — master ( 977e2e...a72f25 )
by Juan José
12s queued 10s
created

ospd.cvss.CVSS.roundup()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 4
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 1
dl 4
loc 4
rs 10
c 0
b 0
f 0
1
# Copyright (C) 2014-2018 Greenbone Networks GmbH
2
#
3
# SPDX-License-Identifier: GPL-2.0-or-later
4
#
5
# This program is free software; you can redistribute it and/or
6
# modify it under the terms of the GNU General Public License
7
# as published by the Free Software Foundation; either version 2
8
# of the License, or (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
19
""" Common Vulnerability Scoring System handling class. """
20
21
import math
22
23
cvss_v2_metrics = {
24
    'AV': {'L': 0.395, 'A': 0.646, 'N': 1.0},
25
    'AC': {'H': 0.35 , 'M': 0.61, 'L': 0.71},
26
    'Au': {'M': 0.45, 'S': 0.56, 'N': 0.704},
27
    'C': {'N': 0.0, 'P': 0.275, 'C': 0.660},
28
    'I': {'N': 0.0, 'P': 0.275, 'C': 0.660},
29
    'A': {'N': 0.0, 'P': 0.275, 'C': 0.660},
30
}
31
32
cvss_v3_metrics = {
33
    'AV': {'N': 0.85, 'A': 0.62, 'L': 0.55, 'P': 0.2},
34
    'AC': {'L': 0.77, 'H': 0.44},
35
    'PR_SU': {'N': 0.85, 'L': 0.62, 'H': 0.27},
36
    'PR_SC': {'N': 0.85, 'L': 0.68, 'H': 0.50},
37
    'UI': {'N': 0.85, 'R': 0.62},
38
    'S': {'U': False, 'C': True},
39
    'C': {'H': 0.56, 'L': 0.22, 'N': 0},
40
    'I': {'H': 0.56, 'L': 0.22, 'N': 0},
41
    'A': {'H': 0.56, 'L': 0.22, 'N': 0},
42
}
43
44 View Code Duplication
class CVSS(object):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
45
    """ Handle cvss vectors and calculate the cvss scoring"""
46
47
    @staticmethod
48
    def roundup(value):
49
        """It rounds up to 1 decimal. """
50
        return math.ceil(value * 10) / 10
51
52
    @staticmethod
53
    def _parse_cvss_base_vector(cvss_vector):
54
        """Parse a string containing a cvss base vector.
55
56
        Arguments:
57
            cvss_vector (str): cvss base vector to be parsed.
58
59
        Return list with the string values of each vector element.
60
        """
61
        vector_as_list = cvss_vector.split('/')
62
        return [item.split(':')[1] for item in vector_as_list]
63
64
    @classmethod
65
    def cvss_base_v2_value(cls, cvss_base_vector):
66
        """ Calculate the cvss base score from a cvss base vector
67
        for cvss version 2.
68
        Arguments:
69
            cvss_base_vector (str) Cvss base vector v2.
70
71
        Return the calculated score
72
        """
73
        if not cvss_base_vector:
74
            return None
75
76
        _av, _ac, _au, _c, _i, _a = cls._parse_cvss_base_vector(
77
            cvss_base_vector)
78
79
        _impact = 10.41 * (1 - (1 - cvss_v2_metrics['C'].get(_c)) *
80
                           (1 - cvss_v2_metrics['I'].get(_i)) *
81
                           (1 - cvss_v2_metrics['A'].get(_a)))
82
83
        _exploitability = (20 * cvss_v2_metrics['AV'].get(_av) *
84
                           cvss_v2_metrics['AC'].get(_ac) *
85
                           cvss_v2_metrics['Au'].get(_au))
86
87
        f_impact = 0 if _impact == 0 else 1.176
88
89
        cvss_base = ((0.6 * _impact) + (0.4 * _exploitability) - 1.5) * f_impact
90
91
        return round(cvss_base, 1)
92
93
    @classmethod
94
    def cvss_base_v3_value(cls, cvss_base_vector):
95
        """ Calculate the cvss base score from a cvss base vector
96
        for cvss version 3.
97
        Arguments:
98
            cvss_base_vector (str) Cvss base vector v3.
99
100
        Return the calculated score, None on fail.
101
        """
102
        if not cvss_base_vector:
103
            return None
104
        _ver, _av, _ac, _pr, _ui, _s, _c, _i, _a = cls._parse_cvss_base_vector(
105
            cvss_base_vector)
106
107
        scope_changed = cvss_v3_metrics['S'].get(_s)
108
109
        isc_base = 1 - (
110
            (1 - cvss_v3_metrics['C'].get(_c)) *
111
            (1 - cvss_v3_metrics['I'].get(_i)) *
112
            (1 - cvss_v3_metrics['A'].get(_a))
113
        )
114
115
        if scope_changed:
116
            _priv_req = cvss_v3_metrics['PR_SC'].get(_pr)
117
        else:
118
            _priv_req = cvss_v3_metrics['PR_SU'].get(_pr)
119
120
        _exploitability = (
121
            8.22 *
122
            cvss_v3_metrics['AV'].get(_av) *
123
            cvss_v3_metrics['AC'].get(_ac) *
124
            _priv_req *
125
            cvss_v3_metrics['UI'].get(_ui)
126
        )
127
128
        if scope_changed:
129
            _impact = (7.52 * (isc_base - 0.029) -
130
                       3.25 * pow(isc_base - 0.02, 15))
131
            _base_score = min (1.08 * (_impact + _exploitability), 10)
132
        else:
133
            _impact = 6.42 * isc_base
134
            _base_score = min (_impact + _exploitability, 10)
135
136
        if _impact > 0 :
137
            return cls.roundup(_base_score)
138
139
        return 0
140