comparison farolluz/parsers/cve.py @ 43:b87f2a6e613a

Add CVE parsing (from OpenVAS GSA)
author Benoît Allard <benoit.allard@greenbone.net>
date Mon, 29 Dec 2014 16:33:34 +0100
parents
children b7e64d0a3a7c
comparison
equal deleted inserted replaced
42:9ed24f48df01 43:b87f2a6e613a
1 # -*- coding: utf-8 -*-
2 # Description:
3 # Methods for parsing CVE XML documents
4 #
5 # Authors:
6 # BenoƮt Allard <benoit.allard@greenbone.net>
7 #
8 # Copyright:
9 # Copyright (C) 2014 Greenbone Networks GmbH
10 #
11 # This program is free software; you can redistribute it and/or
12 # modify it under the terms of the GNU General Public License
13 # as published by the Free Software Foundation; either version 2
14 # of the License, or (at your option) any later version.
15 #
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24
25 """\
26 Methods for parsing of CVE XML Documents
27
28 Ref: http://scap.nist.gov/schema/vulnerability/0.4
29 """
30
31 from __future__ import absolute_import
32
33 import xml.etree.ElementTree as ET
34
35 from .xml import parseDate
36
37 from ..common import CVRFNote, CVRFReference
38 from ..document import CVRF, CVRFPublisher, CVRFTracking, CVRFTrackingID, CVRFRevision
39 from ..producttree import CVRFFullProductName
40 from ..utils import utcnow
41 from ..vulnerability import CVRFVulnerability, CVRFCVSSSet, CVRFCWE, CVRFProductStatus
42
43 NAMESPACES = {
44 'cve': "http://scap.nist.gov/schema/feed/vulnerability/2.0",
45 'vuln': "http://scap.nist.gov/schema/vulnerability/0.4",
46 'cvss': "http://scap.nist.gov/schema/cvss-v2/0.2",
47 'xml': "http://www.w3.org/XML/1998/namespace",
48 }
49
50
51 def UN(ns, name):
52 """ returns a Universal Name """
53 return "{%s}%s" % (NAMESPACES[ns], name)
54
55 def parseCVSS(xmlElem):
56 """ Make a vector out of a list of elements """
57 def get(name):
58 return xmlElem.findtext('/'.join([UN('cvss', 'base_metrics'), UN('cvss', name)]))
59
60 cvss_set = CVRFCVSSSet(float(get('score')))
61 vector = [
62 'AV:%s' % {'LOCAL': 'L',
63 'ADJACENT_NETWORK': 'A',
64 'NETWORK': 'N'}[get('access-vector')],
65 'AC:%s' % {'HIGH': 'H',
66 'MEDIUM': 'M',
67 'LOW': 'L'}[get('access-complexity')],
68 'Au:%s' % {'MULTIPLE': 'M',
69 'SINGLE': 'S',
70 'NONE': 'N'}[get('authentication')],
71 'C:%s' % {'NONE': 'N',
72 'PARTIAL': 'P',
73 'COMPLETE': 'C'}[get('confidentiality-impact')],
74 'I:%s' % {'NONE': 'N',
75 'PARTIAL': 'P',
76 'COMPLETE': 'C'}[get('integrity-impact')],
77 'A:%s' % {'NONE': 'N',
78 'PARTIAL': 'P',
79 'COMPLETE': 'C'}[get('availability-impact')],
80 ]
81 cvss_set.setVector('/'.join(vector))
82 return cvss_set
83
84 def parseXML(data):
85 """ returns am ET.Element from the input stuff.
86 input can be:
87 - a string
88 - a file handle
89 - an ET.Element instance
90 """
91 if isinstance(data, ET.Element):
92 return data
93 # To allow passing file handles
94 if hasattr(data, 'read'):
95 data = data.read()
96 # Parse it.
97 return ET.fromstring(data)
98
99 def parse_CVE_from_GSA(data):
100 xml = parseXML(data)
101 return parse(xml.find('/'.join(['get_info', 'get_info_response', 'info', 'cve', 'raw_data', UN('cve', 'entry')])))
102
103 def parse(xml):
104 xml = parseXML(xml)
105
106 # Create an extra-minimal document
107 doc = CVRF(xml.findtext(UN('vuln', 'cve-id')),
108 'Vulnerability Description')
109 pub = CVRFPublisher("Other")
110 doc.setPublisher(pub)
111 now = utcnow()
112 tracking = CVRFTracking(
113 CVRFTrackingID('000000'),
114 "Draft",
115 (0,),
116 now, now
117 )
118 doc.setTracking(tracking)
119 tracking.addRevision(CVRFRevision((0,), now, 'Document created'))
120
121 # Add the CVE to that document
122 return addToDoc(doc, xml)
123
124 def addToDoc(doc, xml):
125 """ Adds the CVE as vulnerability in the document """
126 xml = parseXML(xml)
127
128 vulnid = xml.attrib['id']
129
130 # Get a new ordinal for our new Vulnerability
131 if len(doc._vulnerabilities) == 0:
132 ordinal = 1
133 else:
134 ordinal = doc._vulnerabilities[-1]._ordinal + 1
135
136 # Create a Vulnerability
137 vuln = CVRFVulnerability(ordinal)
138 doc.addVulnerability(vuln)
139
140 vulnerable_products = []
141 # Set the vulnerable products in productTree
142 for i, cpe in enumerate(xml.findall(
143 '/'.join([UN('vuln', 'vulnerable-software-list'),
144 UN('vuln', 'product')]))):
145 if doc._producttree is None:
146 doc.createProductTree()
147 try:
148 prod = doc._producttree.getProductForCPE(cpe.text)
149 except KeyError:
150 prod = CVRFFullProductName('%s-P%d' % (vulnid, i), cpe.text, doc._producttree, cpe.text)
151 doc._producttree.addProduct(prod)
152 vulnerable_products.append(prod)
153
154 if vulnerable_products:
155 status = CVRFProductStatus('Known Affected')
156 for product in vulnerable_products:
157 status.addProductID(product._productid)
158 vuln.addProductStatus(status)
159
160 # Add the CVE-id
161 vuln.setCVE(xml.findtext(UN('vuln', 'cve-id')))
162
163 # The release date
164 vuln.setReleaseDate(parseDate(xml.findtext(UN('vuln', 'published-datetime'))))
165
166 # Add the CVSS
167 xmlcvss = xml.find(UN('vuln', 'cvss'))
168 if xmlcvss is not None:
169 vuln.addCVSSSet(parseCVSS(xmlcvss))
170
171 # Add the CWE id
172 xmlcwe = xml.find(UN('vuln', 'cwe'))
173 if xmlcwe is not None:
174 # XXX: Get a Description for the CWE !
175 vuln.addCWE(CVRFCWE(xmlcwe.attrib['id'], xmlcwe.attrib['id']))
176
177 # Add references
178 for xmlref in xml.findall(UN('vuln', 'references')):
179 vuln.addReference(CVRFReference(xmlref.find(UN('vuln','reference')).attrib['href'],
180 xmlref.findtext(UN('vuln', 'reference'))))
181
182 xmlsummary = xml.findtext(UN('vuln', 'summary'))
183 if xmlsummary is not None:
184 vuln.addNote(CVRFNote(
185 'Summary',
186 1,
187 xmlsummary
188 ))
189
190 return doc
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)