Hanno Böck commited on 2019-12-11 18:39:17
Zeige 1 geänderte Dateien mit 40 Einfügungen und 68 Löschungen.
| ... | ... |
@@ -23,13 +23,12 @@ |
| 23 | 23 |
# return your changes to the public. We would be especially happy if you tell |
| 24 | 24 |
# us what you're going to do with this code. |
| 25 | 25 |
|
| 26 |
-import configparser |
|
| 27 |
- |
|
| 28 | 26 |
import os |
| 29 | 27 |
import glob |
| 30 | 28 |
import re |
| 31 | 29 |
import argparse |
| 32 | 30 |
import sys |
| 31 |
+import json |
|
| 33 | 32 |
from xml.sax.saxutils import escape |
| 34 | 33 |
|
| 35 | 34 |
|
| ... | ... |
@@ -73,60 +72,25 @@ parser.add_argument("-3", "--thirdparty", action="store_true",
|
| 73 | 72 |
help="Scan for third-party components like jquery") |
| 74 | 73 |
opts = parser.parse_args() |
| 75 | 74 |
|
| 76 |
-# Parse vulnerability database |
|
| 77 |
-config = configparser.ConfigParser() |
|
| 78 |
-try: |
|
| 79 |
- config.read(glob.glob('/usr/share/freewvs/*.freewvs'))
|
|
| 80 |
- config.read(glob.glob('/usr/local/share/freewvs/*.freewvs'))
|
|
| 81 |
- config.read(glob.glob(os.path.dirname(sys.argv[0]) |
|
| 82 |
- + '/freewvsdb/*.freewvs')) |
|
| 83 |
-except configparser.MissingSectionHeaderError as err: |
|
| 84 |
- print("Error parsing config files: %s" % err)
|
|
| 85 |
- |
|
| 86 |
-vdb = [] |
|
| 87 |
-scanfiles = set() |
|
| 88 |
-for sect in config.sections(): |
|
| 89 |
- item = {}
|
|
| 75 |
+jdir = False |
|
| 76 |
+for p in [os.path.dirname(sys.argv[0]) + '/freewvsdb', '/var/lib/freewvs']: |
|
| 77 |
+ if os.path.isdir(p): |
|
| 78 |
+ jdir = p |
|
| 79 |
+if not jdir: |
|
| 80 |
+ print("Can't find freewvs json db")
|
|
| 81 |
+ sys.exit(1) |
|
| 90 | 82 |
|
| 91 |
- if (config.getboolean(sect, 'thirdparty', fallback=False) |
|
| 92 |
- and not opts.thirdparty): |
|
| 93 |
- continue |
|
| 83 |
+jconfig = [] |
|
| 84 |
+for cfile in glob.glob(jdir + '/*.json'): |
|
| 85 |
+ with open(cfile) as json_file: |
|
| 86 |
+ data = json.load(json_file) |
|
| 87 |
+ jconfig += data |
|
| 94 | 88 |
|
| 95 |
- # base options |
|
| 96 |
- item['name'] = sect |
|
| 97 |
- item['safe'] = config.get(sect, 'safe') |
|
| 98 |
- item['file'] = config.get(sect, 'file') |
|
| 99 |
- item['vuln'] = config.get(sect, 'vuln') |
|
| 100 |
- item['subdir'] = int(config.get(sect, 'subdir')) |
|
| 101 |
- scanfiles.add(item['file']) |
|
| 102 |
- |
|
| 103 |
- # match magic |
|
| 104 |
- item['variable'] = re.compile(re.escape(config.get(sect, 'variable')) |
|
| 105 |
- + r"[^0-9\n\r]*[.]*([0-9.]*[0-9])[^0-9.]") |
|
| 106 |
- |
|
| 107 |
- # optional options |
|
| 108 |
- if config.has_option(sect, 'extra_match'): |
|
| 109 |
- item['extra_match'] = config.get(sect, 'extra_match') |
|
| 110 |
- else: |
|
| 111 |
- item['extra_match'] = False |
|
| 112 |
- if config.has_option(sect, 'extra_nomatch'): |
|
| 113 |
- item['extra_nomatch'] = config.get(sect, 'extra_nomatch') |
|
| 114 |
- else: |
|
| 115 |
- item['extra_nomatch'] = False |
|
| 116 |
- if config.has_option(sect, 'path_match'): |
|
| 117 |
- item['path_match'] = config.get(sect, 'path_match') |
|
| 118 |
- else: |
|
| 119 |
- item['path_match'] = False |
|
| 120 |
- if config.has_option(sect, 'add_minor'): |
|
| 121 |
- item['add_minor'] = config.get(sect, 'add_minor') |
|
| 122 |
- else: |
|
| 123 |
- item['add_minor'] = False |
|
| 124 |
- if config.has_option(sect, 'old_safe'): |
|
| 125 |
- item['old_safe'] = config.get(sect, 'old_safe').split(",")
|
|
| 126 |
- else: |
|
| 127 |
- item['old_safe'] = [] |
|
| 89 |
+scanfiles = set() |
|
| 90 |
+for app in jconfig: |
|
| 91 |
+ for det in app['detection']: |
|
| 92 |
+ scanfiles.add(det['file']) |
|
| 128 | 93 |
|
| 129 |
- vdb.append(item) |
|
| 130 | 94 |
|
| 131 | 95 |
if opts.xml: |
| 132 | 96 |
print('<?xml version="1.0" ?>')
|
| ... | ... |
@@ -137,8 +101,11 @@ if opts.xml: |
| 137 | 101 |
for fdir in opts.dirs: |
| 138 | 102 |
for root, NULL, files in os.walk(fdir): |
| 139 | 103 |
for filename in scanfiles.intersection(files): |
| 140 |
- for item in vdb: |
|
| 141 |
- if filename == item['file']: |
|
| 104 |
+ for item in jconfig: |
|
| 105 |
+ if not opts.thirdparty and 'thirdparty' in item: |
|
| 106 |
+ continue |
|
| 107 |
+ for det in item['detection']: |
|
| 108 |
+ if filename == det['file']: |
|
| 142 | 109 |
mfile = os.path.join(root, filename) |
| 143 | 110 |
try: |
| 144 | 111 |
file = open(mfile, errors='replace') |
| ... | ... |
@@ -147,40 +114,45 @@ for fdir in opts.dirs: |
| 147 | 114 |
filestr = file.read() |
| 148 | 115 |
file.close() |
| 149 | 116 |
|
| 150 |
- if ((item['extra_match'] |
|
| 151 |
- and item['extra_match'] not in filestr) |
|
| 152 |
- or (item['extra_nomatch'] |
|
| 153 |
- and item['extra_nomatch'] in filestr) |
|
| 154 |
- or (item['path_match'] |
|
| 155 |
- and not root.endswith(item['path_match']))): |
|
| 117 |
+ if (('extra_match' in det
|
|
| 118 |
+ and det['extra_match'] not in filestr) |
|
| 119 |
+ or ('extra_nomatch' in det
|
|
| 120 |
+ and det['extra_nomatch'] in filestr) |
|
| 121 |
+ or ('path_match' in det
|
|
| 122 |
+ and not root.endswith(det['path_match']))): |
|
| 156 | 123 |
continue |
| 157 | 124 |
|
| 158 |
- findversion = item['variable'].search(filestr) |
|
| 125 |
+ findversion = re.search(re.escape(det['variable']) |
|
| 126 |
+ + r"[^0-9\n\r]*[.]*" |
|
| 127 |
+ "([0-9.]*[0-9])[^0-9.]", |
|
| 128 |
+ filestr) |
|
| 159 | 129 |
if not findversion: |
| 160 | 130 |
continue |
| 161 | 131 |
findversion = findversion.group(1) |
| 162 | 132 |
|
| 163 | 133 |
# Very ugly phpbb workaround |
| 164 |
- if item['add_minor']: |
|
| 134 |
+ if 'add_minor' in det: |
|
| 165 | 135 |
findversion = findversion.split('.')
|
| 166 | 136 |
findversion[-1] = str(int(findversion[-1]) |
| 167 | 137 |
+ int(item['add_minor'])) |
| 168 | 138 |
findversion = '.'.join(findversion) |
| 169 | 139 |
|
| 170 | 140 |
if (not versioncompare(item['safe'], findversion) |
| 171 |
- or findversion in item['old_safe']): |
|
| 141 |
+ or ('old_safe' in item
|
|
| 142 |
+ and findversion in item['old_safe'].split(','))):
|
|
| 172 | 143 |
if opts.all: |
| 173 | 144 |
vulnprint(item['name'], findversion, "ok", "", |
| 174 |
- mfile, item['subdir'], opts.xml) |
|
| 145 |
+ mfile, det['subdir'], opts.xml) |
|
| 175 | 146 |
continue |
| 176 | 147 |
|
| 177 | 148 |
safev = item['safe'] |
| 178 |
- for ver in item['old_safe']: |
|
| 149 |
+ if 'old_safe' in item: |
|
| 150 |
+ for ver in item['old_safe'].split(','):
|
|
| 179 | 151 |
if versioncompare(ver, findversion): |
| 180 | 152 |
safev = ver |
| 181 | 153 |
|
| 182 |
- vulnprint(item['name'], findversion, safev, item['vuln'], |
|
| 183 |
- mfile, item['subdir'], opts.xml) |
|
| 154 |
+ vulnprint(item['name'], findversion, safev, |
|
| 155 |
+ item['vuln'], mfile, det['subdir'], opts.xml) |
|
| 184 | 156 |
|
| 185 | 157 |
if opts.xml: |
| 186 | 158 |
print('</freewvs>')
|
| 187 | 159 |