~ubuntu-security/ubuntu-cve-tracker/master

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")