1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#!/usr/bin/python
# Author: Marc Deslauriers <marc.deslauriers@ubuntu.com>
# Copyright (C) 2014 Canonical Ltd.
#
# This script is distributed under the terms and conditions of the GNU General
# Public License, Version 3 or later. See http://www.gnu.org/copyleft/gpl.html
# for details.
#
# This script will load all known CVE from UCT, and then will parse the
# mailbox files specified on the command line to identify CVEs that are
# unknown.
import mailbox
import optparse
import os
import re
import sys
import cve_lib
parser = optparse.OptionParser()
parser.add_option("-d", "--debug", help="Enable debug reporting", action='store_true')
(opt, args) = parser.parse_args()
if len(args) == 0:
os.write(sys.stderr.fileno(), "Must specify one or more mbox files!\n")
sys.exit(1)
cve_pat = re.compile(r'CVE-\d\d\d\d-\d{4,7}')
# Load a list of known CVEs from the tracker
known_cves = []
check_dirs = [cve_lib.active_dir, cve_lib.retired_dir, cve_lib.ignored_dir]
for dir in check_dirs:
cve_files = [elem for elem in os.listdir(dir) \
if re.match('^CVE-\d+-(\d|N)+$', elem)]
known_cves += cve_files
ignored = cve_lib.parse_CVEs_from_uri('%s/not-for-us.txt' % cve_lib.ignored_dir)
known_cves += ignored
for mbox_file in args:
print("Searching mail file: %s\n" % mbox_file)
if not os.path.exists(mbox_file):
os.write(sys.stderr.fileno(), "Could not open file: %s\n" % mbox_file)
continue
if os.path.isfile(mbox_file):
messages = mailbox.mbox(mbox_file)
else:
# assume maildir
messages = mailbox.Maildir(mbox_file, factory=None)
for message in messages:
subject = message['subject']
date = message['date']
if message.is_multipart():
body = ""
try:
for bodies in message:
body += bodies.get_payload()
except:
pass
else:
body = message.get_payload()
patterns = cve_pat.findall(body)
if patterns:
matches = list(set(patterns))
if matches:
if opt.debug:
print("Found: %s in message %s" % (matches, subject))
for cve in matches:
if cve not in known_cves:
print("Couldn't find %s in tracker!" % cve)
print("Message date: %s" % date)
if subject:
print("Message subject: %s\n" % subject)
else:
print("Message subject: <empty>\n")
|