Greenbone Vulnerability Management Libraries  11.0.1
cvss.c
Go to the documentation of this file.
1 /* Copyright (C) 2012-2019 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 
65 #include <glib.h>
66 #include <string.h>
67 
68 // clang-format off
72 #define AV_NETWORK 1.0
73 #define AV_ADJACENT_NETWORK 0.646
74 #define AV_LOCAL 0.395
79 #define AC_LOW 0.71
80 #define AC_MEDIUM 0.61
81 #define AC_HIGH 0.35
86 #define Au_MULTIPLE_INSTANCES 0.45
87 #define Au_SINGLE_INSTANCE 0.56
88 #define Au_NONE 0.704
93 #define C_NONE 0.0
94 #define C_PARTIAL 0.275
95 #define C_COMPLETE 0.660
100 #define I_NONE 0.0
101 #define I_PARTIAL 0.275
102 #define I_COMPLETE 0.660
107 #define A_NONE 0.0
108 #define A_PARTIAL 0.275
109 #define A_COMPLETE 0.660
110 // clang-format on
111 
116 {
117  A,
118  I,
119  C,
120  Au,
121  AC,
122  AV
123 };
124 
129 {
130  const char *name;
131  double nvalue;
132 };
133 
137 struct cvss
138 {
139  double conf_impact;
140  double integ_impact;
141  double avail_impact;
142  double access_vector;
144  double authentication;
145 };
146 
147 static const struct impact_item impact_map[][3] = {
148  [A] =
149  {
150  {"N", A_NONE},
151  {"P", A_PARTIAL},
152  {"C", A_COMPLETE},
153  },
154  [I] =
155  {
156  {"N", I_NONE},
157  {"P", I_PARTIAL},
158  {"C", I_COMPLETE},
159  },
160  [C] =
161  {
162  {"N", C_NONE},
163  {"P", C_PARTIAL},
164  {"C", C_COMPLETE},
165  },
166  [Au] =
167  {
168  {"N", Au_NONE},
169  {"M", Au_MULTIPLE_INSTANCES},
170  {"S", Au_SINGLE_INSTANCE},
171  },
172  [AV] =
173  {
174  {"N", AV_NETWORK},
175  {"A", AV_ADJACENT_NETWORK},
176  {"L", AV_LOCAL},
177  },
178  [AC] =
179  {
180  {"L", AC_LOW},
181  {"M", AC_MEDIUM},
182  {"H", AC_HIGH},
183  },
184 };
185 
194 static int
195 toenum (const char *str, enum base_metrics *res)
196 {
197  int rc = 0; /* let's be optimistic */
198 
199  if (g_strcmp0 (str, "A") == 0)
200  *res = A;
201  else if (g_strcmp0 (str, "I") == 0)
202  *res = I;
203  else if (g_strcmp0 (str, "C") == 0)
204  *res = C;
205  else if (g_strcmp0 (str, "Au") == 0)
206  *res = Au;
207  else if (g_strcmp0 (str, "AU") == 0)
208  *res = Au;
209  else if (g_strcmp0 (str, "AV") == 0)
210  *res = AV;
211  else if (g_strcmp0 (str, "AC") == 0)
212  *res = AC;
213  else
214  rc = -1;
215 
216  return rc;
217 }
218 
227 static double
229 {
230  return (10.41
231  * (1
232  - (1 - cvss->conf_impact) * (1 - cvss->integ_impact)
233  * (1 - cvss->avail_impact)));
234 }
235 
244 static double
246 {
247  return (20 * cvss->access_vector * cvss->access_complexity
248  * cvss->authentication);
249 }
250 
260 static inline int
261 set_impact_from_str (const char *value, enum base_metrics metric,
262  struct cvss *cvss)
263 {
264  int i;
265 
266  for (i = 0; i < 3; i++)
267  {
268  const struct impact_item *impact;
269 
270  impact = &impact_map[metric][i];
271 
272  if (g_strcmp0 (impact->name, value) == 0)
273  {
274  switch (metric)
275  {
276  case A:
277  cvss->avail_impact = impact->nvalue;
278  break;
279 
280  case I:
281  cvss->integ_impact = impact->nvalue;
282  break;
283 
284  case C:
285  cvss->conf_impact = impact->nvalue;
286  break;
287 
288  case Au:
289  cvss->authentication = impact->nvalue;
290  break;
291 
292  case AV:
293  cvss->access_vector = impact->nvalue;
294  break;
295 
296  case AC:
297  cvss->access_complexity = impact->nvalue;
298  break;
299 
300  default:
301  return -1;
302  }
303  return 0;
304  }
305  }
306  return -1;
307 }
308 
317 static double
319 {
320  double impact = 1.176;
321  double impact_sub;
322  double exploitability_sub;
323 
324  impact_sub = get_impact_subscore (cvss);
325  exploitability_sub = get_exploitability_subscore (cvss);
326 
327  if (impact_sub < 0.1)
328  impact = 0.0;
329 
330  return (((0.6 * impact_sub) + (0.4 * exploitability_sub) - 1.5) * impact)
331  + 0.0;
332 }
333 
341 double
342 get_cvss_score_from_base_metrics (const char *cvss_str)
343 {
344  struct cvss cvss;
345  char *token, *base_str, *base_metrics;
346 
347  memset (&cvss, 0x00, sizeof (struct cvss));
348 
349  if (cvss_str == NULL)
350  return -1.0;
351 
352  base_str = base_metrics = g_strdup_printf ("%s/", cvss_str);
353 
354  while ((token = strchr (base_metrics, '/')) != NULL)
355  {
356  char *token2 = strtok (base_metrics, ":");
357  char *metric_name = token2;
358  char *metric_value;
359  enum base_metrics mval;
360  int rc;
361 
362  *token++ = '\0';
363 
364  if (metric_name == NULL)
365  goto ret_err;
366 
367  metric_value = strtok (NULL, ":");
368 
369  if (metric_value == NULL)
370  goto ret_err;
371 
372  rc = toenum (metric_name, &mval);
373  if (rc)
374  goto ret_err;
375 
376  if (set_impact_from_str (metric_value, mval, &cvss))
377  goto ret_err;
378 
379  base_metrics = token;
380  }
381 
382  g_free (base_str);
383  return __get_cvss_score (&cvss);
384 
385 ret_err:
386  g_free (base_str);
387  return (double) -1;
388 }
AV_ADJACENT_NETWORK
#define AV_ADJACENT_NETWORK
Definition: cvss.c:73
AC_MEDIUM
#define AC_MEDIUM
Definition: cvss.c:80
A_PARTIAL
#define A_PARTIAL
Definition: cvss.c:108
__get_cvss_score
static double __get_cvss_score(struct cvss *cvss)
Final CVSS score computation helper.
Definition: cvss.c:318
impact_map
static const struct impact_item impact_map[][3]
Definition: cvss.c:147
I_COMPLETE
#define I_COMPLETE
Definition: cvss.c:102
toenum
static int toenum(const char *str, enum base_metrics *res)
Determine base metric enumeration from a string.
Definition: cvss.c:195
cvss::avail_impact
double avail_impact
Definition: cvss.c:141
C
@ C
Definition: cvss.c:119
get_exploitability_subscore
static double get_exploitability_subscore(const struct cvss *cvss)
Calculate Exploitability Sub Score.
Definition: cvss.c:245
A
@ A
Definition: cvss.c:117
A_NONE
#define A_NONE
AvailabilityImpact (A) Constants.
Definition: cvss.c:107
impact_item::nvalue
double nvalue
Definition: cvss.c:131
I
@ I
Definition: cvss.c:118
Au_SINGLE_INSTANCE
#define Au_SINGLE_INSTANCE
Definition: cvss.c:87
cvss
Describe a CVSS metrics.
Definition: cvss.c:137
Au_NONE
#define Au_NONE
Definition: cvss.c:88
I_NONE
#define I_NONE
IntegrityImpact (I) Constants.
Definition: cvss.c:100
AC
@ AC
Definition: cvss.c:121
get_impact_subscore
static double get_impact_subscore(const struct cvss *cvss)
Calculate Impact Sub Score.
Definition: cvss.c:228
AC_HIGH
#define AC_HIGH
Definition: cvss.c:81
impact_item::name
const char * name
Definition: cvss.c:130
C_PARTIAL
#define C_PARTIAL
Definition: cvss.c:94
C_COMPLETE
#define C_COMPLETE
Definition: cvss.c:95
impact_item
Describe a CVSS impact element.
Definition: cvss.c:128
I_PARTIAL
#define I_PARTIAL
Definition: cvss.c:101
cvss::authentication
double authentication
Definition: cvss.c:144
A_COMPLETE
#define A_COMPLETE
Definition: cvss.c:109
C_NONE
#define C_NONE
ConfidentialityImpact (C) Constants.
Definition: cvss.c:93
Au
@ Au
Definition: cvss.c:120
AC_LOW
#define AC_LOW
AccessComplexity (AC) Constants.
Definition: cvss.c:79
get_cvss_score_from_base_metrics
double get_cvss_score_from_base_metrics(const char *cvss_str)
Calculate CVSS Score.
Definition: cvss.c:342
AV
@ AV
Definition: cvss.c:122
base_metrics
base_metrics
Base metrics.
Definition: cvss.c:115
cvss::access_complexity
double access_complexity
Definition: cvss.c:143
set_impact_from_str
static int set_impact_from_str(const char *value, enum base_metrics metric, struct cvss *cvss)
Set impact score from string representation.
Definition: cvss.c:261
AV_LOCAL
#define AV_LOCAL
Definition: cvss.c:74
cvss::conf_impact
double conf_impact
Definition: cvss.c:139
cvss::access_vector
double access_vector
Definition: cvss.c:142
AV_NETWORK
#define AV_NETWORK
AccessVector (AV) Constants.
Definition: cvss.c:72
Au_MULTIPLE_INSTANCES
#define Au_MULTIPLE_INSTANCES
Authentication (Au) Constants.
Definition: cvss.c:86
cvss::integ_impact
double integ_impact
Definition: cvss.c:140