.
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | DESCRIPTION
2 | ===========
3 | This tool compares a targets patch levels against the Microsoft vulnerability
4 | database in order to detect potential missing patches on the target. It also
5 | notifies the user if there are public exploits and Metasploit modules
6 | available for the missing bulletins.
7 |
8 | It requires the 'systeminfo' command output from a Windows host in order to
9 | compare that the Microsoft security bulletin database and determine the
10 | patch level of the host.
11 |
12 | It has the ability to automatically download the security bulletin database
13 | from Microsoft with the --update flag, and saves it as an Excel spreadsheet.
14 |
15 | When looking at the command output, it is important to note that it assumes
16 | all vulnerabilities and then selectively removes them based upon the hotfix
17 | data. This can result in many false-positives, and it is key to know what
18 | software is actually running on the target host. For example, if there are
19 | known IIS exploits it will flag them even if IIS is not running on the
20 | target host.
21 |
22 | The output shows either public exploits (E), or Metasploit modules (M) as
23 | indicated by the character value.
24 |
25 | It was heavily inspired by Linux_Exploit_Suggester by Pentura.
26 |
27 | Blog Post: "Introducing Windows Exploit Suggester", https://blog.gdssecurity.com/labs/2014/7/11/introducing-windows-exploit-suggester.html
28 |
29 | USAGE
30 | =====
31 | update the database
32 | ```
33 | $ ./windows-exploit-suggester.py --update
34 | [*] initiating...
35 | [*] successfully requested base url
36 | [*] scraped ms download url
37 | [+] writing to file 2014-06-06-mssb.xlsx
38 | [*] done
39 | ```
40 | install dependencies
41 |
42 | (install python-xlrd, $ pip install xlrd --upgrade)
43 |
44 | feed it "systeminfo" input, and point it to the microsoft database
45 | ```
46 | $ ./windows-exploit-suggester.py --database 2014-06-06-mssb.xlsx --systeminfo win7sp1-systeminfo.txt
47 | [*] initiating...
48 | [*] database file detected as xls or xlsx based on extension
49 | [*] reading from the systeminfo input file
50 | [*] querying database file for potential vulnerabilities
51 | [*] comparing the 15 hotfix(es) against the 173 potential bulletins(s)
52 | [*] there are now 168 remaining vulns
53 | [+] windows version identified as 'Windows 7 SP1 32-bit'
54 | [*]
55 | [M] MS14-012: Cumulative Security Update for Internet Explorer (2925418) - Critical
56 | [E] MS13-101: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Elevation of Privilege (2880430) - Important
57 | [M] MS13-090: Cumulative Security Update of ActiveX Kill Bits (2900986) - Critical
58 | [M] MS13-080: Cumulative Security Update for Internet Explorer (2879017) - Critical
59 | [M] MS13-069: Cumulative Security Update for Internet Explorer (2870699) - Critical
60 | [M] MS13-059: Cumulative Security Update for Internet Explorer (2862772) - Critical
61 | [M] MS13-055: Cumulative Security Update for Internet Explorer (2846071) - Critical
62 | [M] MS13-053: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Remote Code Execution (2850851) - Critical
63 | [M] MS13-009: Cumulative Security Update for Internet Explorer (2792100) - Critical
64 | [M] MS13-005: Vulnerability in Windows Kernel-Mode Driver Could Allow Elevation of Privilege (2778930) - Important
65 | [*] done
66 | ```
67 |
68 | possible exploits for an operating system can be used without hotfix data
69 | ```
70 | $ ./windows-exploit-suggester.py --database 2014-06-06-mssb.xlsx --ostext 'windows server 2008 r2'
71 | [*] initiating...
72 | [*] database file detected as xls or xlsx based on extension
73 | [*] getting OS information from command line text
74 | [*] querying database file for potential vulnerabilities
75 | [*] comparing the 0 hotfix(es) against the 196 potential bulletins(s)
76 | [*] there are now 196 remaining vulns
77 | [+] windows version identified as 'Windows 2008 R2 64-bit'
78 | [*]
79 | [M] MS13-009: Cumulative Security Update for Internet Explorer (2792100) - Critical
80 | [M] MS13-005: Vulnerability in Windows Kernel-Mode Driver Could Allow Elevation of Privilege (2778930) - Important
81 | [E] MS11-011: Vulnerabilities in Windows Kernel Could Allow Elevation of Privilege (2393802) - Important
82 | [M] MS10-073: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Elevation of Privilege (981957) - Important
83 | [M] MS10-061: Vulnerability in Print Spooler Service Could Allow Remote Code Execution (2347290) - Critical
84 | [E] MS10-059: Vulnerabilities in the Tracing Feature for Services Could Allow Elevation of Privilege (982799) - Important
85 | [E] MS10-047: Vulnerabilities in Windows Kernel Could Allow Elevation of Privilege (981852) - Important
86 | [M] MS10-002: Cumulative Security Update for Internet Explorer (978207) - Critical
87 | [M] MS09-072: Cumulative Security Update for Internet Explorer (976325) - Critical
88 | ```
89 |
90 | LIMITATIONS
91 | ===========
92 | Currently, if the 'systeminfo' command reveals 'File 1' as the output for
93 | the hotfixes, it will not be able to determine which are installed on
94 | the target. If this occurs, the list of hotfixes will need to be
95 | retrieved from the target host and passed in using the --hotfixes flag
96 |
97 | It currently does not seperate 'editions' of the Windows OS such as
98 | 'Tablet' or 'Media Center' for example, or different architectures, such as
99 | Itanium-based only
100 |
101 | False positives also occur where it assumes EVERYTHING is installed
102 | on the target Windows operating system. If you receive the 'File 1'
103 | output, try executing 'wmic qfe list full' and feed that as input
104 | with the --hotfixes flag, along with the 'systeminfo'
105 |
106 | LICENSE
107 | =======
108 | This program is free software: you can redistribute it and/or modify
109 | it under the terms of the GNU General Public License as published by
110 | the Free Software Foundation, either version 3 of the License, or
111 | (at your option) any later version.
112 |
113 | This program is distributed in the hope that it will be useful,
114 | but WITHOUT ANY WARRANTY; without even the implied warranty of
115 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
116 | GNU General Public License for more details.
117 |
118 | You should have received a copy of the GNU General Public License
119 | along with this program. If not, see .
120 |
121 |
--------------------------------------------------------------------------------
/windows-exploit-suggester.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Windows Exploit Suggester for Python 3
5 | # revision 3.3, 2017-02-13
6 | #
7 | # original WES author: Sam Bertram, Gotham Digital Science
8 | # ported to python3 and supported libraries by: Conor Rynne
9 | # contact: pwnistry@gmail.com
10 | # blog post: "Modernising Windows Exploit Suggester", http://blog.pwnistry.com/
11 | #
12 | # DESCRIPTION
13 | #
14 | # The purpose of this project is to port the original Windows Exploit Suggester
15 | # to Python 3 and openpyxl (since xlrd dropped support for .xlsx files a while
16 | # ago)
17 | #
18 | # This tool compares a targets patch levels against the Microsoft vulnerability
19 | # database in order to detect potential missing patches on the target. It also
20 | # notifies the user if there are public exploits and Metasploit modules
21 | # available for the missing bulletins.
22 | #
23 | # It requires the 'systeminfo' command output from a Windows host in order to
24 | # compare that the Microsoft security bulletin database and determine the
25 | # patch level of the host.
26 | #
27 | # It has the ability to automatically download the security bulletin database
28 | # from Microsoft with the --update flag, and saves it as an Excel spreadsheet.
29 | #
30 | # When looking at the command output, it is important to note that it assumes
31 | # all vulnerabilities and then selectively removes them based upon the hotfix
32 | # data. This can result in many false-positives, and it is key to know what
33 | # software is actually running on the target host. For example, if there are
34 | # known IIS exploits it will flag them even if IIS is not running on the
35 | # target host.
36 | #
37 | # The output shows either public exploits (E), or Metasploit modules (M) as
38 | # indicated by the character value.
39 | #
40 | # It was heavily inspired by Linux_Exploit_Suggester by Pentura.
41 | #
42 | # Blog Post: "Introducing Windows Exploit Suggester", https://blog.gdssecurity.com/labs/2014/7/11/introducing-windows-exploit-suggester.html
43 | #
44 | # USAGE
45 | #
46 | # update the database
47 | #
48 | # $ ./windows-exploit-suggester.py --update
49 | # [*] initiating...
50 | # [*] successfully requested base url
51 | # [*] scraped ms download url
52 | # [+] writing to file 2014-06-06-mssb.xlsx
53 | # [*] done
54 | #
55 | # install dependencies
56 | #
57 | # (install python-xlrd, $ pip install xlrd --upgrade)
58 | #
59 | # feed it "systeminfo" input, and point it to the microsoft database
60 | #
61 | # $ ./windows-exploit-suggester.py --database 2014-06-06-mssb.xlsx --systeminfo win7sp1-systeminfo.txt
62 | # [*] initiating...
63 | # [*] database file detected as xls or xlsx based on extension
64 | # [*] reading from the systeminfo input file
65 | # [*] querying database file for potential vulnerabilities
66 | # [*] comparing the 15 hotfix(es) against the 173 potential bulletins(s)
67 | # [*] there are now 168 remaining vulns
68 | # [+] windows version identified as 'Windows 7 SP1 32-bit'
69 | # [*]
70 | # [M] MS14-012: Cumulative Security Update for Internet Explorer (2925418) - Critical
71 | # [E] MS13-101: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Elevation of Privilege (2880430) - Important
72 | # [M] MS13-090: Cumulative Security Update of ActiveX Kill Bits (2900986) - Critical
73 | # [M] MS13-080: Cumulative Security Update for Internet Explorer (2879017) - Critical
74 | # [M] MS13-069: Cumulative Security Update for Internet Explorer (2870699) - Critical
75 | # [M] MS13-059: Cumulative Security Update for Internet Explorer (2862772) - Critical
76 | # [M] MS13-055: Cumulative Security Update for Internet Explorer (2846071) - Critical
77 | # [M] MS13-053: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Remote Code Execution (2850851) - Critical
78 | # [M] MS13-009: Cumulative Security Update for Internet Explorer (2792100) - Critical
79 | # [M] MS13-005: Vulnerability in Windows Kernel-Mode Driver Could Allow Elevation of Privilege (2778930) - Important
80 | # [*] done
81 | #
82 | # possible exploits for an operating system can be used without hotfix data
83 | # $ ./windows-exploit-suggester.py --database 2014-06-06-mssb.xlsx --ostext 'windows server 2008 r2'
84 | # [*] initiating...
85 | # [*] database file detected as xls or xlsx based on extension
86 | # [*] getting OS information from command line text
87 | # [*] querying database file for potential vulnerabilities
88 | # [*] comparing the 0 hotfix(es) against the 196 potential bulletins(s)
89 | # [*] there are now 196 remaining vulns
90 | # [+] windows version identified as 'Windows 2008 R2 64-bit'
91 | # [*]
92 | # [M] MS13-009: Cumulative Security Update for Internet Explorer (2792100) - Critical
93 | # [M] MS13-005: Vulnerability in Windows Kernel-Mode Driver Could Allow Elevation of Privilege (2778930) - Important
94 | # [E] MS11-011: Vulnerabilities in Windows Kernel Could Allow Elevation of Privilege (2393802) - Important
95 | # [M] MS10-073: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Elevation of Privilege (981957) - Important
96 | # [M] MS10-061: Vulnerability in Print Spooler Service Could Allow Remote Code Execution (2347290) - Critical
97 | # [E] MS10-059: Vulnerabilities in the Tracing Feature for Services Could Allow Elevation of Privilege (982799) - Important
98 | # [E] MS10-047: Vulnerabilities in Windows Kernel Could Allow Elevation of Privilege (981852) - Important
99 | # [M] MS10-002: Cumulative Security Update for Internet Explorer (978207) - Critical
100 | # [M] MS09-072: Cumulative Security Update for Internet Explorer (976325) - Critical
101 | #
102 | # LIMITATIONS
103 | #
104 | # Currently, if the 'systeminfo' command reveals 'File 1' as the output for
105 | # the hotfixes, it will not be able to determine which are installed on
106 | # the target. If this occurs, the list of hotfixes will need to be
107 | # retrieved from the target host and passed in using the --hotfixes flag
108 | #
109 | # It currently does not seperate 'editions' of the Windows OS such as
110 | # 'Tablet' or 'Media Center' for example, or different architectures, such as
111 | # Itanium-based only
112 | #
113 | # False positives also occur where it assumes EVERYTHING is installed
114 | # on the target Windows operating system. If you receive the 'File 1'
115 | # output, try executing 'wmic qfe list full' and feed that as input
116 | # with the --hotfixes flag, along with the 'systeminfo'
117 | #
118 | # LICENSE
119 | #
120 | # This program is free software: you can redistribute it and/or modify
121 | # it under the terms of the GNU General Public License as published by
122 | # the Free Software Foundation, either version 3 of the License, or
123 | # (at your option) any later version.
124 | #
125 | # This program is distributed in the hope that it will be useful,
126 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
127 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
128 | # GNU General Public License for more details.
129 | #
130 | # You should have received a copy of the GNU General Public License
131 | # along with this program. If not, see .
132 | #
133 | # TODOLIST
134 | #
135 | # TODO better if/then/case when detecting OS. more flexibility with parsing
136 | # different systeminfo output
137 | # TODO seperate by editions? may result in false positives
138 | # TODO count the number of exploits in the summary prior to outputting it?
139 | # TODO finish -s --search function so that all info on an MS number can be
140 | # returned
141 | # TODO add titles to exploit list so that it is more portable
142 | # TODO test for Windows RT systeminfo output
143 | # TODO improved msf/poc output? perhaps adding details on each MS number?
144 | # TODO if it's running on windows, then try and execute the systeminfo command?
145 | # TODO SPEED. this is now way too slow... somewhat improved!
146 | # TODO automatically install python module? xlrd.
147 | # TODO manually override MS11-011 for Non-Affected Products. The bulletin
148 | # database is wrong.
149 | # Windows 7 for 32-bit Systems Service Pack 1
150 | # Windows 7 for x64-based Systems Service Pack 1
151 | # Windows Server 2008 R2 for x64-based Systems Service Pack 1
152 | # Windows Server 2008 R2 for Itanium-based Systems Service Pack 1
153 | #
154 | # CHANGE LOG
155 | # v33 2017-02-13
156 | # - added links to exploits and resources for each bulletins. can be ignored with the -q/--quiet flag
157 | # - hard coded ms11-011 to ignore false positives
158 | # - added additional resources
159 | #
160 | # v31 2016-02-10
161 | # - changed bulletin url, microsoft 404'd it
162 | #
163 | # v30 2016-01-04
164 | # - added exploits and bulletins from the past six months
165 | #
166 | # v29 2015-09-16
167 | # - adding support for windows 10
168 | #
169 | # v28 2015-07-30
170 | # - added bulletin scraping for xlsx and xls files using regex. thanks to
171 | # edebernis for reporting the bug
172 | # - added ms15-022, ms15-015 update to msf
173 | #
174 | # v27 2015-06-18
175 | # - added new bulletin url that is only xls and not xlsx. thanks to bstork for
176 | # reporting the bug
177 | # - added ms15-010, ms15-051, and ms15-052
178 | #
179 | # v26 2015-06-02
180 | # - small bug fix with linked output
181 | # - added duplicates flag that can allow for bulletins to be displayed
182 | # multiple times. this will allow for greater analysis on linked bulletins
183 | #
184 | # v25 2015-05-18
185 | # - added ms15-051 local priv
186 | #
187 | # v24 2015-01-30
188 | # - added --sub/-s command in order to display output of msids as linked
189 | # this aides in demonstrating what patches need to be applied precisely.
190 | # this change was implemented in v23, but only followed the depth to level
191 | # 1 instead of the entire way.
192 | # - fixed a bug that know allows for multiple supercedes msids in the db
193 | # - allowed for getarchitecture to be recursive, and reduced redunancy when
194 | # it is called throughout the program
195 | # - added ms14-070
196 | #
197 | # v23 2015-01-26
198 | # - typo in --local flag case (pontential vs potential). issue #5 closed.
199 | #
200 | # v22 2015-01-23
201 | # - speed optimisations! it was too slow beforehand. realised i could easily
202 | # make it a bit more efficient
203 | #
204 | # v21 2015-01-22
205 | # - changed display formatting to include nested/linked MS numbers. makes it
206 | # easier to determine the dependencies
207 | # - made args global
208 | # - changed some code formatting, including double-space instead of \t
209 | # - added some additional comments
210 | # - disable ANSI output if on windows platform
211 | # - added recent exploits
212 | #
213 | # v20 2014-12-16
214 | # - added ms14-068,ms14-064,ms14-060, and ms14-058 to the internal vuln list
215 | #
216 | # v19 2014-10-08
217 | # - added support for windows server 2012, this includes ignoring the
218 | # architecture for 2012, and forcing from 32-bit to 64-bit
219 | #
220 | # v18 2014-09-02
221 | # - added ms14-029 poc
222 | #
223 | # v17 2014-08-05
224 | # - fixed a bug where it would not detect OS version when a unicode char comes
225 | # before search string
226 | #
227 | # v16 2014-07-28
228 | # - improved reading of various file encodings for systeminfo. now attempts to
229 | # detect the file first, otherwise loops through common encodings
230 | # - improved OS, service pack, architecture, and release detection. this is now
231 | # not English-dependent as it was previously
232 | # - better architecture detection of systeminfo input (look for -based string)
233 | # - added /usr/bin/env python
234 | # - added ms14-035 poc
235 | #
236 | # v15 2014-07-15
237 | # - changed file open to io, and attempt to decode as utf-8; otherwise attempt
238 | # utf-16
239 | #
240 | # v14 2014-07-13
241 | # - allowed for --ostext flag to properly supersede OS detection of systeminfo
242 | # input
243 | #
244 | # v13a 2014-07-01
245 | # - added new msf flags for ms13-097, and ms14-009
246 | #
247 | # v12a 2014-06-06
248 | # - quick cleanup for release
249 | #
250 | # v11a 2014-05-02
251 | # - fixed the bulletin scrape regex for the update command. ms changed it
252 | #
253 | # v10a 2014-03-24
254 | # - added a hotfixes argument, that can be used to supplement the list
255 | # of hotfixes detected in the systeminfo input
256 | # - added severity at the end of the output when reporting bulletins
257 | # - added a 'patches' argument, that can be used to determine any
258 | # of the hotfixes for a specific bulletin. this is good for debugging.
259 | #
260 | # v09a 2014-03-18
261 | # - again, another massive bug on the linked kb searching function
262 | # getlinkedms(). should be fixed now
263 | # - also checks columns 11 and 12 for superseded, i think it has to
264 | # do with dos and *nix output
265 | #
266 | # v08a 2014-02-14
267 | # - bug where the superseded column wasn't being checked
268 | # this may be because it's only xlsx and it parsed differently in csv
269 | # - added some new exploits from edb
270 | #
271 | # v07a 2014-02-12
272 | # - added indicator for os version, and in green
273 | # - better parsing of architecture for itanium based support
274 | #
275 | # v06a 2014-01-19
276 | # - added 'ostext' or 'o' option, when don't have any patch information
277 | # but just know the OS
278 | #
279 | # v05a
280 | # - added a check for "Kernel version" column, as well as "OS version"
281 | #
282 | # v04a
283 | # - added support for XLSX files directly with the updated XLRD library, this
284 | # requires the python-xlrd library to be installed and upgraded with:
285 | # $ pip install xlrd --upgrade
286 | # - changed MS13-101 to E, as there isn't a metasploit module (yet!)
287 | #
288 | # v03a
289 | # - fixed an issue where component KB wasn't being checked
290 | #
291 | # FUNCTIONS
292 | #
293 | # def main():
294 | # def run(database):
295 | # def detect_encoding(filename):
296 | # def trace(database):
297 | # def patches(database):
298 | # def getversion(name, release, servicepack, architecture):
299 | # def getname(ostext):
300 | # def getrelease(ostext):
301 | # def getservicepack(ostext):
302 | # def getarchitecture(ostext):
303 | # def getitanium(ostext):
304 | # def getpatch(ostext):
305 | # def getbulletinids(haystack):
306 | # def isaffected(name, release, servicepack, architecture, haystack):
307 | # def getlinkedms(msids, database):
308 | # def getexploit(msid = 0):
309 | # def update():
310 | # def merge_list(li):
311 | #
312 | import re
313 | import platform
314 | import argparse
315 | import subprocess
316 | import csv
317 | from io import StringIO
318 | import os
319 | import datetime
320 | import urllib.request
321 | import urllib.error
322 | import io
323 | from random import randint
324 | from time import sleep
325 | from tempfile import NamedTemporaryFile
326 | from sys import exit
327 |
328 | # constants/globals
329 | MSSB_URL = 'http://www.microsoft.com/en-gb/download/confirmation.aspx?id=36982'
330 | BULLETIN_URL = 'http://download.microsoft.com/download/6/7/3/673E4349-1CA5-40B9-8879-095C72D5B49D/BulletinSearch.xlsx'
331 | VERSION = "3.4"
332 |
333 | # global parser
334 | parser = argparse.ArgumentParser(description="search microsoft security bulletins for exploits based upon the patch level of the machine by feeding in systeminfo command")
335 | parser.add_argument("-v", "--verbose", help="verbose output", action="store_true")
336 | parser.add_argument("-i", "--systeminfo", help="feed in an input file that contains the 'systeminfo' command")
337 | parser.add_argument("-d", "--database", help="the file that contains the microsoft security bulletin database")
338 | parser.add_argument("-u", "--update", help="required flag to even run the script", action="store_true")
339 | parser.add_argument("-a", "--audit", help="show all entries, not only exploits", action="store_true")
340 | parser.add_argument("-t", "--trace", help="used to determine linked ms bulletins")
341 | parser.add_argument("-p", "--patches", help="used to determine specific patches for a ms bulletin")
342 | parser.add_argument("-o", "--ostext", help="a loose text representation of the windows OS (ex: \"windows xp home edition sp2\")")
343 | parser.add_argument("-s", "--sub", help="generate output using linked/sub bulletins. WARNING: SLOW!", action="store_true")
344 | parser.add_argument("-2", "--duplicates", help="allow duplicate ms bulletin output within the results. this will produce a lot of output, but is useful when determining linked ms bulletins", action="store_true")
345 | parser.add_argument("-q", "--quiet", help="don't show exploit information. shorter output", action="store_true")
346 | # hotfixes
347 | # used to parse "wmic qfe list full" input, and to solve the 'File 1' errors
348 | parser.add_argument("-H", "--hotfixes", help="a loose list of hotfixes to be added, for use with the following command: 'wmic qfe list full'")
349 |
350 | # search by exploit type only
351 | exptypegroup = parser.add_mutually_exclusive_group()
352 | exptypegroup.add_argument("-r", "--remote", help="search remote exploits only", action="store_true")
353 | exptypegroup.add_argument("-l", "--local", help="search local exploits only", action="store_true")
354 |
355 | # global args parsed
356 | ARGS = parser.parse_args()
357 |
358 | def main():
359 | ALERT("initiating winsploit version %s..." % VERSION)
360 |
361 | database = ''
362 |
363 | # if there is a database switch
364 | if ARGS.database:
365 |
366 | # split name and extension
367 | name, extension = os.path.splitext(ARGS.database)
368 |
369 | # csv
370 | if 'csv' in extension:
371 |
372 | ALERT("database file detected as csv based on extension", ALERT.NORMAL)
373 |
374 | # attempt to open the file
375 | try:
376 | dbfile = open(ARGS.database, 'r')
377 |
378 | except IOError as e:
379 | ALERT("could not open the file %s" % filename, ALERT.BAD)
380 | exit(1)
381 |
382 | data = ''
383 | for line in dbfile:
384 | data += line
385 | database = data
386 |
387 | dbfile.close()
388 |
389 | # xslx
390 | elif 'xlsx' in extension:
391 |
392 | ALERT("database file detected as xlsx based on extension", ALERT.NORMAL)
393 |
394 | try:
395 | import openpyxl
396 | except ImportError as e:
397 | ALERT("please install and upgrade the openpyxl library", ALERT.BAD)
398 | exit(1)
399 |
400 | # open the xls file
401 | try:
402 | wb = openpyxl.load_workbook(ARGS.database)
403 | except IOError as e:
404 | ALERT("no such file or directory '%s'. ensure you have the correct database file passed in --database/-d" % ARGS.database, ALERT.BAD)
405 | exit(1)
406 | #sh = wb.sheet_by_name('Export Bulletin Search Spreadsh')
407 | shlist=wb.sheetnames
408 | sh = wb[shlist[0]]
409 |
410 | # read the spreadsheet into a temp file
411 | f = NamedTemporaryFile(mode='wb')
412 | wr = csv.writer(f, quoting=csv.QUOTE_NONE, delimiter=',')
413 |
414 | data = ''
415 |
416 | # loop through xls
417 | rowcount=0
418 | for row in sh:
419 | rowcount+=1
420 | for rownum in range(1, rowcount+1):
421 |
422 | values = []
423 | rowObjs=sh[rownum]
424 | for rowobj in rowObjs:
425 | values.append(rowobj.value)
426 |
427 | # loop through row values, and process input
428 | for i in range(len(values)):
429 | values[i] = str(values[i])
430 | values[i] = values[i].replace('\n',' ')
431 | values[i] = values[i].replace(',','')
432 | values[i] = values[i].replace('.0','')
433 |
434 | data += ",".join(values)
435 | data += '\n'
436 |
437 | # set the database to the csv data
438 | database = data
439 |
440 | #xls
441 | elif 'xls' in extension:
442 |
443 | ALERT("database file detected as xls or xlsx based on extension", ALERT.NORMAL)
444 |
445 | try:
446 | import xlrd
447 | except ImportError as e:
448 | ALERT("please install and upgrade the python-xlrd library", ALERT.BAD)
449 | exit(1)
450 |
451 | # open the xls file
452 | try:
453 | wb = xlrd.open_workbook(ARGS.database)
454 | except IOError as e:
455 | ALERT("no such file or directory '%s'. ensure you have the correct database file passed in --database/-d" % ARGS.database, ALERT.BAD)
456 | exit(1)
457 | #sh = wb.sheet_by_name('Export Bulletin Search Spreadsh')
458 | sh = wb.sheet_by_index(0)
459 |
460 | # read the spreadsheet into a temp file
461 | f = NamedTemporaryFile(mode='wb')
462 | wr = csv.writer(f, quoting=csv.QUOTE_NONE, delimiter=',')
463 |
464 | data = ''
465 |
466 | # loop through xls
467 | for rownum in range(sh.nrows):
468 |
469 | values = sh.row_values(rownum)
470 |
471 | # loop through row values, and process input
472 | for i in range(len(values)):
473 | values[i] = str(values[i])
474 | values[i] = values[i].replace('\n',' ')
475 | values[i] = values[i].replace(',','')
476 | values[i] = values[i].replace('.0','')
477 |
478 | data += ",".join(values)
479 | data += '\n'
480 |
481 | # set the database to the csv data
482 | database = data
483 |
484 |
485 | # unknown filetype, error
486 | else:
487 | ALERT("unknown filetype. change file extension to indicate csv or xls/xlsx", ALERT.BAD)
488 | exit(1)
489 |
490 | if ARGS.trace: trace(database)
491 | elif ARGS.systeminfo or ARGS.ostext: run(database)
492 | elif ARGS.update: update()
493 | elif ARGS.patches: patches(database)
494 |
495 | # error
496 | else:
497 | ALERT("an error occured while running, not enough arguments", ALERT.BAD)
498 | exit(1)
499 |
500 | ALERT("done")
501 | # end main()
502 |
503 | def run(database):
504 |
505 | # variables used
506 | ostext=None
507 | name=None
508 | release=None
509 | servicepack=None
510 |
511 | # will default to 32-bit, but can be 64 bit or itanium
512 | architecture=None
513 |
514 | hotfixes=set([])
515 | bulletinids=set([])
516 |
517 | potential=[]
518 |
519 | vulns={}
520 | ids=set([])
521 |
522 | cmdoutput = []
523 |
524 | # test for database
525 | if not ARGS.database:
526 | ALERT("please supply a MSSB database file with the --database or -d flag, this can be downloaded using the --update command", ALERT.BAD)
527 | exit(1)
528 |
529 | # read from ostext first
530 | if ARGS.ostext:
531 | ALERT("getting OS information from command line text")
532 |
533 | name=getname(ARGS.ostext)
534 | release=getrelease(ARGS.ostext)
535 | servicepack=getservicepack(ARGS.ostext)
536 | architecture=getarchitecture(ARGS.ostext)
537 |
538 | # the os name at least has to be identified
539 | if not name:
540 | ALERT("unable to determine the windows version command line text from '%s'" % ARGS.ostext, ALERT.BAD)
541 | exit(1)
542 |
543 | # get the systeminfo information from the input file
544 | if ARGS.systeminfo:
545 |
546 | ALERT("attempting to read from the systeminfo input file")
547 |
548 | # when reading the systeminfo file, we want to attempt to detect it using chardet
549 | # if this doesn't work, we will loop through a list of common encodings and try them all
550 | encodings = ['utf-8', 'utf-16', 'utf-16-le', 'utf-16-be', 'iso-8859-2']
551 |
552 | detected_encoding = detect_encoding(ARGS.systeminfo)
553 |
554 | # insert detected encoding to the front of the list
555 | if detected_encoding:
556 | if ARGS.verbose: ALERT("detected encoding of file as '%s'" % detected_encoding)
557 | encodings.insert(0, detected_encoding)
558 |
559 | cmdfile = None
560 | cmdoutput = None
561 |
562 | # now loop through all encodings, with the detected one first (if it was possible)
563 | for encoding in encodings:
564 |
565 | if ARGS.verbose: ALERT(" attempting to read with '%s' encoding" % encoding)
566 |
567 | # if we can read the file, and read the command output, we are done with the loop
568 | try:
569 | cmdfile = io.open(ARGS.systeminfo, "r", encoding=encoding) # throws UnicodeDecodeError
570 | cmdoutput = cmdfile.readlines() # throws UnicodeError
571 | break
572 |
573 | except (UnicodeError, UnicodeDecodeError) as e:
574 | ALERT("could not read file using '%s' encoding: %s" % (encoding, e), ALERT.BAD)
575 |
576 | # file might not exist
577 | except:
578 | ALERT("could not read from input file specified: %s" % ARGS.systeminfo, ALERT.BAD)
579 | exit(1)
580 |
581 | # general catchall if somehow it was able to keep processing
582 | if not cmdfile or not cmdoutput:
583 | ALERT("could not read from input file, or could not detect encoding", ALERT.BAD)
584 | exit(1)
585 |
586 | # file read successfully
587 | ALERT("systeminfo input file read successfully (%s)" % encoding, ALERT.GOOD)
588 |
589 | # error
590 | if not ARGS.systeminfo and not ARGS.ostext and platform.system() != 'Windows':
591 | ALERT("please run from a Windows machine, or provide an input file using --systeminfo, or use the --ostext option to get data with no patch information", ALERT.BAD)
592 | exit(1)
593 |
594 | # parse the systeminfo information
595 | hotfix=False
596 |
597 | # loop through the systeminfo input
598 | for haystack in cmdoutput:
599 |
600 | # only attempt to set the version, arch, service pack if there is no
601 | # ostext flag
602 | if not ARGS.ostext:
603 |
604 | # when detecting the operating system version, every line (independent of language)
605 | # appears to have Microsoft Windows in it, sometimes with (R)
606 | if "Microsoft" in haystack and "Windows" in haystack and not name:
607 | name = getname(haystack)
608 |
609 | # the windows release is similar to the above and has the text 'Microsoft Windows' in the text
610 | if "Microsoft" in haystack and "Windows" in haystack and not release:
611 | release = getrelease(haystack)
612 |
613 | # similar to OS, there is the words 'Service Pack'
614 | if "Service Pack" in haystack and not servicepack:
615 | servicepack = getservicepack(haystack)
616 |
617 | # get architecture only if -based is in the line, and --ostext hasn't been used
618 | if "-based" in haystack and not architecture:
619 | architecture=getarchitecture(haystack)
620 |
621 | # look for kbs
622 | if ("KB" in haystack or "]: " in haystack):
623 | patch=getpatch(haystack)
624 |
625 | # if a patch was parsed
626 | if patch:
627 | if ARGS.verbose: ALERT("found hotfix %s" % patch)
628 | hotfixes.add(patch)
629 |
630 | # now process the hotfixes argument input
631 | if ARGS.hotfixes:
632 |
633 | encodings = ['utf-8', 'utf-16', 'utf-16-le', 'utf-16-be', 'iso-8859-2']
634 |
635 | detected_encoding = detect_encoding(ARGS.systeminfo)
636 |
637 | # insert detected encoding to the front of the list
638 | if detected_encoding:
639 | if ARGS.verbose: ALERT("detected encoding of file as '%s'" % detected_encoding)
640 | encodings.insert(0, detected_encoding)
641 |
642 | cmdfile = None
643 | hotfixesfile = None
644 |
645 | # now loop through all encodings, with the detected one first (if it was possible)
646 | for encoding in encodings:
647 |
648 | if ARGS.verbose: ALERT(" attempting to read with '%s' encoding" % encoding)
649 |
650 | # if we can read the file, and read the command output, we are done with the loop
651 | try:
652 | cmdfile = io.open(ARGS.hotfixes, "r", encoding=encoding) # throws UnicodeDecodeError
653 | hotfixesfile = cmdfile.readlines() # throws UnicodeError
654 | break
655 |
656 | except (UnicodeError, UnicodeDecodeError) as e:
657 | if ARGS.verbose: ALERT("could not read file using '%s' encoding: %s" % (encoding, e), ALERT.BAD)
658 |
659 | # file might not exist
660 | except:
661 | ALERT("could not read from input file specified: %s" % ARGS.hotfixes, ALERT.BAD)
662 | exit(1)
663 |
664 | # general catchall if somehow it was able to keep processing
665 | if not cmdfile or not hotfixesfile:
666 | ALERT("could not read from input file, or could not detect encoding", ALERT.BAD)
667 | exit(1)
668 |
669 | # file read successfully
670 | ALERT("hotfixes input file read successfully (%s)" % encoding, ALERT.GOOD)
671 |
672 | # loop through hotfixes file input
673 | for haystack in hotfixesfile:
674 | # look for kbs
675 | if ("KB" in haystack or "]: " in haystack):
676 | patch=getpatch(haystack)
677 |
678 | # if a patch was parsed
679 | if patch:
680 | if ARGS.verbose: ALERT("found hotfix %s" % patch)
681 | hotfixes.add(patch)
682 |
683 | if ARGS.verbose:
684 | ALERT("name: %s; release: %s; servicepack: %s; architecture: %s" % (name, release, servicepack, architecture))
685 |
686 | # verify that a windows os was at least able to be parsed
687 | if not name:
688 | if ARGS.systeminfo:
689 | ALERT("unable to determine the windows versions from the input file specified. consider using --ostext option to force detection (example: --ostext 'windows 7 sp1 64-bit')", ALERT.BAD)
690 | exit(1)
691 |
692 | if ARGS.verbose:
693 | ALERT("name: %s" % name)
694 | ALERT("release: %s" % release)
695 | ALERT("service pack: %s" % servicepack)
696 | ALERT("architecture: %s" % architecture)
697 |
698 | ALERT("querying database file for potential vulnerabilities")
699 |
700 | # potential, all matches within the CSV database for the name,release,sp,arch
701 | # bulletinds, set of the above with MSIDs (good to keep count)
702 |
703 | # get the potential bulletins
704 | try:
705 | for row in csv.reader(StringIO(database)):
706 | bulletinid=row[1]
707 | affected=row[6]
708 |
709 | if isaffected(name, release, servicepack, architecture, affected):
710 |
711 | # only add the bulletin if it's not already in the list
712 | if bulletinid not in bulletinids:
713 | potential.append(row)
714 | bulletinids.add(bulletinid)
715 |
716 | if ARGS.verbose:
717 | ALERT("%s has been added to potential list '%s'" % (bulletinid, affected))
718 |
719 | except csv.Error as e:
720 | ALERT('could not parse database file, make sure it is in the proper format', ALERT.BAD)
721 | exit(1)
722 |
723 | # there should always be some potential vulns, because of the amount of windows software and false positives
724 | if len(bulletinid) == 0:
725 | ALERT("there are no potential vulnerabilities for, ensure you're searching a valid windows OS", ALERT.BAD)
726 | exit(1)
727 |
728 | ALERT("comparing the %s hotfix(es) against the %s potential bulletins(s) with a database of %s known exploits" % (len(hotfixes), len(bulletinids), getexploit()))
729 |
730 | # start removing the vulns because of hotfixes
731 | for row in list(potential):
732 |
733 | # ms bulletin
734 | bulletinid=row[1]
735 | kb=row[2]
736 | componentkb=row[7]
737 |
738 | for hotfix in hotfixes:
739 |
740 | # if either the hotfixes match the kb or componentkb columns, and the bulletin is in the list
741 | # of potential bulletins
742 | if (hotfix == kb or hotfix == componentkb) and bulletinid in bulletinids:
743 |
744 | if ARGS.verbose:
745 | ALERT(" %s hotfix triggered a removal of %skb and the %s bulletin; componentkb is %s" % (hotfix,kb,bulletinid,componentkb))
746 |
747 | # get the linked ms, this will automatically calculate the superseded by as well
748 | linkedms = getlinkedms([bulletinid], csv.reader(StringIO(database)))
749 | linkedmsstr = ''
750 |
751 | # calculate the pretty string, only care when verbose
752 | if len(linkedms) > 0:
753 | for m in linkedms:
754 | linkedmsstr += ' ' + m
755 |
756 | if ARGS.verbose:
757 |
758 | if hotfix == kb:
759 | ALERT(" due to presence of KB%s (Bulletin KB) removing%s bulletin(s)" % (kb, linkedmsstr))
760 |
761 | elif componentkb == kb:
762 | ALERT(" due to presence of KB%s (Component KB) removing%s bulletin(s)" % (componentkb, linkedmsstr))
763 |
764 | bulletinids = bulletinids.difference(linkedms)
765 | potential.remove(row)
766 |
767 | ALERT("there are now %s remaining vulns" % len(bulletinids))
768 |
769 | # search local exploits only
770 | if ARGS.local:
771 | ALERT("searching for local exploits only")
772 | for row in list(potential):
773 | bulletinid = row[1]
774 | impact = row[4]
775 |
776 | if bulletinid in bulletinids and not "elevation of privilege" in impact.lower():
777 |
778 | remove = getlinkedms([bulletinid], csv.reader(StringIO(database)))
779 |
780 | if ARGS.verbose:
781 | ALERT(" removing %s (total of %s MS ids), because of its impact %s" % (bulletinid, len(remove), impact))
782 |
783 | bulletinids = bulletinids.difference(remove)
784 | potential.remove(row)
785 |
786 | # search remote exploits only
787 | if ARGS.remote:
788 | ALERT("searching for remote exploits only")
789 | for row in list(potential):
790 | bulletinid = row[1]
791 | impact = row[4]
792 |
793 | if bulletinid in bulletinids and not "remote code execution" in impact.lower():
794 |
795 | remove = getlinkedms([bulletinid], csv.reader(StringIO(database)))
796 |
797 | if ARGS.verbose:
798 | ALERT(" removing %s (total of %s MS ids), because of its impact %s" % (bulletinid, len(remove), impact))
799 |
800 | bulletinids = bulletinids.difference(remove)
801 | potential.remove(row)
802 |
803 | # print windows version
804 | version=getversion(name, release, servicepack, architecture)
805 |
806 | ALERT("[E] exploitdb PoC, [M] Metasploit module, [*] missing bulletin", ALERT.GOOD)
807 | ALERT("windows version identified as '%s'" % version, ALERT.GOOD)
808 |
809 | # spacer
810 | ALERT("")
811 |
812 | # vulns, the dictionary of the bulletins based off of the potential bulletins
813 | # also, a good opportunity to remove false-positives due to the
814 | # differences in the technet post and bulletin
815 | for row in potential:
816 | id = row[1]
817 |
818 | # start removing vulns because of false-positives
819 | # Manual override for MS11-011 to reduce false positives. The article was updated, but the bulletin database wasn't (https://technet.microsoft.com/en-us/library/security/ms11-011.aspx)
820 | # V1.2 (March 18, 2011): Added Windows 7 for 32-bit Systems Service Pack 1, Windows 7 for x64-based Systems Service Pack 1, Windows Server 2008 R2 for x64-based Systems Service Pack 1, and Windows Server 2008 R2 for Itanium-based Systems Service Pack 1 to Non-Affected Software. This is an informational change only. There were no changes to the security update files or detection logic.
821 | if id == 'MS11-011':
822 | ms11_011 = ['Windows 7 for 32-bit Systems Service Pack 1', 'Windows 7 for x64-based Systems Service Pack 1', 'Windows Server 2008 R2 for x64-based Systems Service Pack 1','Windows Server 2008 R2 for Itanium-based Systems Service Pack 1']
823 | for not_affected in ms11_011:
824 | compare_version = getversion(getname(not_affected),getrelease(not_affected),getservicepack(not_affected),getarchitecture(not_affected))
825 | if version == compare_version:
826 | if ARGS.verbose: ALERT("Ignoring MS11-011 false positive due to it not affecting '%s'" % compare_version)
827 | id = False
828 |
829 | for bulletinid in bulletinids:
830 | if bulletinid == id:
831 | title = row[5]
832 | kb = row[2]
833 | severity = row[3]
834 | if id not in ids:
835 | vulns[id] = [title,kb,severity]
836 | ids.add(id)
837 |
838 | # alerted, if a bulletin has been alerted to the user so that it doesn't appear twice
839 | # this occurs when a bulletin has multiple parents
840 | # msids, the actual data for all of the relevant msids (the row from the CSV)
841 | alerted = set()
842 | msids = sorted(vulns, reverse=True)
843 |
844 | # loop through the bulletinids which is the set of the actual bulletins that are to
845 | # be alerted
846 | for msid in msids:
847 |
848 | ## don't alert twice, no matter the case
849 | if msid not in alerted:
850 |
851 | # get the msid, exploitability alert rating, and resources
852 | m,exploit,resources = getexploit(msid)
853 |
854 | # only display the message, if the exploit flag isn't used
855 | # or if it is used, and the alert level is MSF or EXP
856 | if ARGS.audit or (exploit == ALERT.MSF or exploit == ALERT.EXP):
857 |
858 | alert = ALERT.NORMAL
859 | if exploit: alert = exploit
860 |
861 | ALERT("%s: %s (%s) - %s" % (msid, vulns[msid][0], vulns[msid][1], vulns[msid][2]), alert)
862 | if resources and not ARGS.quiet:
863 | for resource in resources:
864 | ALERT(" %s" % resource)
865 | ALERT("")
866 |
867 | alerted.add(msid)
868 |
869 | # only attempt to display linked/sub msids based on cli arguments
870 | if ARGS.sub:
871 |
872 | # linked ms, the children of this msid
873 | linked = set(getlinkedms([msid], csv.reader(StringIO(database))))
874 | linked = linked.intersection(msids)
875 |
876 | # loop through the linked msids, and only display those that qualify and
877 | # those that have not been alerted yet
878 | for lmsid in sorted(linked, reverse=True):
879 | if lmsid in msids and lmsid not in alerted:
880 | lexploit = getexploit(lmsid)
881 | lalert = ALERT.NORMAL
882 | if ARGS.audit or (lexploit == ALERT.MSF or lexploit == ALERT.EXP):
883 | if lexploit: lalert = lexploit
884 | ALERT("|_%s: %s (%s) - %s" % (lmsid, vulns[lmsid][0], vulns[lmsid][1], vulns[lmsid][2]), lalert)
885 |
886 | # only allow duplicate events to be displayed when command-line args passed
887 | if not ARGS.duplicates: alerted.add(lmsid)
888 |
889 | # end run()
890 |
891 |
892 | # attempt to detect character encoding of a file
893 | # otherwise return None
894 | # https://stackoverflow.com/questions/3323770/character-detection-in-a-text-file-in-python-using-the-universal-encoding-detect
895 | def detect_encoding(filename):
896 | try:
897 | import chardet
898 | data = open(filename, "r").read()
899 | result = chardet.detect(data)
900 | encoding = result['encoding']
901 | return encoding
902 | except:
903 | return None
904 |
905 | # the trace command is used to determine linked MS bulletins
906 | # TODO much of this is duplicated from run(). should be merged
907 | def trace(database):
908 |
909 | # convert to upper
910 | bulletinid = ARGS.trace.upper()
911 | ALERT("searching for bulletin id %s" % bulletinid)
912 |
913 | # get linked msids
914 | lmsids = getlinkedms([bulletinid], csv.reader(StringIO(database)))
915 |
916 | msids = []
917 |
918 | if ARGS.ostext:
919 | ALERT("getting OS information from command line text")
920 |
921 | name=getname(ARGS.ostext)
922 | release=getrelease(ARGS.ostext)
923 | servicepack=getservicepack(ARGS.ostext)
924 | architecture=getarchitecture(ARGS.ostext)
925 |
926 | if ARGS.verbose:
927 | ALERT("name: %s" % name)
928 | ALERT("release: %s" % release)
929 | ALERT("service pack: %s" % servicepack)
930 | ALERT("architecture: %s" % architecture)
931 |
932 | # the os name at least has to be identified
933 | if not name:
934 | ALERT("unable to determine the windows version command line text from '%s'" % ARGS.ostext, ALERT.BAD)
935 | exit(1)
936 |
937 | # get linked msids, loop through the row
938 | for row in csv.reader(StringIO(database)):
939 | msid = row[1]
940 | affected = row[6]
941 |
942 | if msid in lmsids:
943 | # debug
944 | #print ("%s,%s,%s,%s,%s,%s" % (msid, name, release, servicepack, architecture, affected))
945 |
946 | if isaffected(name, release, servicepack, architecture, affected) and msid not in msids: msids.append(msid)
947 |
948 |
949 | else: msids = lmsids
950 |
951 | ALERT("linked msids %s" % msids, ALERT.GOOD)
952 |
953 |
954 | def patches(database):
955 |
956 | kbs = []
957 |
958 | # convert to upper
959 | bulletinid = ARGS.patches.upper()
960 | ALERT("searching all kb's for bulletin id %s" % bulletinid)
961 |
962 | # get linked msids, loop through the row
963 | for row in csv.reader(StringIO(database)):
964 |
965 | bulletinkb=row[2]
966 | componentkb=row[7]
967 |
968 | # if there's a match
969 | if bulletinid in row[1]:
970 | kbs.append(bulletinkb)
971 | kbs.append(componentkb)
972 |
973 | ALERT("relevant kbs %s" % (sorted(set(kbs), reverse=True)), ALERT.GOOD)
974 |
975 | def getversion(name, release, servicepack, architecture):
976 |
977 | version = "Windows " + name
978 |
979 | # append release first
980 | if release: version += " R" + release
981 |
982 | # then service pack
983 | if servicepack: version += " SP" + servicepack
984 |
985 | # architecture
986 | if architecture == "Itanium": version += " Itanium-based"
987 | else: version += " %s-bit" % architecture
988 |
989 | return version
990 |
991 |
992 | def getname(ostext):
993 |
994 | if ostext == False:
995 | return False
996 |
997 | osname=False
998 |
999 | osnamearray=[["xp","XP"],
1000 | ["2000","2000"],
1001 | ["2003","2003"],
1002 | ["vista","Vista"],
1003 | ["2008","2008"],
1004 | [" 7","7"],
1005 | [" 8","8"],
1006 | ["2012","2012"],
1007 | ["8.1","8.1"],
1008 | [" 10","10"]]
1009 |
1010 | for needle in osnamearray:
1011 | ostext = ostext.lower()
1012 | if "windows" + needle[0] in ostext or "windows " + needle[0] in ostext or "server" + needle[0] in ostext or "server " + needle[0] in ostext:
1013 | osname = needle[1]
1014 |
1015 | # the first loop is a more restrictive detection of the OS name, but it does not detect the following
1016 | # > Microsoft Windows\xFF7 Entreprise
1017 | # so if there is no detection from the first attempt, then search on a more loosely based string of
1018 | # needle and space
1019 | if not osname:
1020 | for needle in osnamearray:
1021 | if needle[0] + " " in ostext.lower():
1022 | osname = needle[1]
1023 |
1024 | return osname
1025 |
1026 |
1027 | def getrelease(ostext):
1028 |
1029 | if ostext == False:
1030 | return False
1031 |
1032 | osrelease=False
1033 |
1034 | regex="( r| rc|release|rel)[ ]*(\d)"
1035 | m=re.search(regex, ostext.lower())
1036 |
1037 | if m and m.group(2):
1038 | osrelease=m.group(2)
1039 |
1040 | return osrelease
1041 |
1042 | def getservicepack(ostext):
1043 |
1044 | if ostext == False:
1045 | return False
1046 |
1047 | servicepack=False
1048 |
1049 | regex="(sp|pack|pack:)[ ]*(\d)"
1050 | m=re.search(regex, ostext.lower())
1051 | if m and m.group(2):
1052 | servicepack=m.group(2)
1053 |
1054 | return servicepack
1055 |
1056 |
1057 | # architecture defaults to 32, but can be 64-bit
1058 | # or itanium based
1059 | def getarchitecture(ostext):
1060 |
1061 | # default to 32-bit
1062 | architecture="32"
1063 |
1064 | # haystack
1065 | s = ostext.lower()
1066 |
1067 | # attempt to be as flexible as possible
1068 | # matching '64-based', 'x64', ' 64', 'i64', '64bit', '64 bit', '64-bit'
1069 | if ("64-based" in s) or ("x64" in s) or (" 64" in s) or ("i64" in s) or ("64bit" in s) or ("64 bit" in s) or ("64-bit" in s): architecture="64"
1070 |
1071 | # target Itanium with a simple search for 'tani'
1072 | if "tani" in s: architecture="Itanium"
1073 |
1074 | if getname(ostext) == "2008" and getrelease(ostext) == "2" and architecture == "32":
1075 | if ARGS.verbose:
1076 | ALERT("forcing unidentified architecture to 64-bit because OS identified as Windows 2008 R2 (although could be Itanium and wasn't detected?)")
1077 | architecture = "64"
1078 |
1079 | # windows server 2012 is only 64-bit arch
1080 | if getname(ostext) == "2012" and architecture == "32":
1081 | if ARGS.verbose:
1082 | ALERT("forcing unidentified architecture to 64-bit because OS identified as Windows Server 2012 does not support 32-bit")
1083 | architecture = "64"
1084 |
1085 | return architecture
1086 |
1087 | # itanium build search string
1088 | def getitanium(ostext):
1089 |
1090 | if ostext == False:
1091 | return False
1092 |
1093 | regex="(tanium)"
1094 | m=re.search(regex, ostext.lower())
1095 |
1096 | if m:
1097 | return True
1098 |
1099 | return False
1100 |
1101 | def getpatch(ostext):
1102 |
1103 | patch=False
1104 |
1105 | regex="(\d){5,10}"
1106 | m=re.search(regex, ostext.lower())
1107 | if m and m.group():
1108 | patch=m.group()
1109 |
1110 | return patch
1111 |
1112 | # get the bulletin ids from the haystack
1113 | # these are typically in the form of:
1114 | # MS14-009[2898860]
1115 | # MS13-052[2833940],MS14-009[2898856]
1116 | # will return a list if found, otherwise false
1117 | def getbulletinids(haystack):
1118 | regex="MS[\d]{2,3}-[\d]{2,3}"
1119 | m = re.findall(regex, haystack)
1120 | if len(m) > 0: return m
1121 | return False
1122 |
1123 | def isaffected(name, release, servicepack, architecture, haystack):
1124 |
1125 | if name == getname(haystack):
1126 |
1127 | # ensure None are set to False
1128 | # example, if getservicepack() does not get called in the systeminfo parsing
1129 | # then servicepack will be None. this will then fail when comparing to False.
1130 | if release == None: release = False
1131 | if servicepack == None: servicepack = False
1132 | if architecture == None: architecture = False
1133 |
1134 | # print "%s,%s,%s,%s" % (name, release, servicepack, architecture)
1135 | # print "%s,%s,%s,%s" % (getname(haystack),getrelease(haystack),getservicepack(haystack),getarchitecture(haystack))
1136 |
1137 | n = (name == getname(haystack))
1138 | r = (release == getrelease(haystack))
1139 | s = (servicepack == getservicepack(haystack))
1140 | a = (architecture == getarchitecture(haystack))
1141 |
1142 | # we ignore the architecture for 2012 servers, as there is only 64-bit
1143 | if name == "2012": return r and s
1144 |
1145 | # print "%s,%s,%s,%s,%s" % (name, release, servicepack, architecture, (a and r and s))
1146 |
1147 | return a and r and s
1148 |
1149 | # search entire database for linked msids
1150 | # this will also search the superseded column (11)
1151 | def getlinkedms(msids, database):
1152 |
1153 | lmsids = []
1154 |
1155 | # go through each row in the database
1156 | for row in database:
1157 |
1158 | # base MS-XX
1159 | rowid=row[1]
1160 |
1161 | # superseded MS-XX
1162 |
1163 | # first try row 12, and then row 11 for the supercedes column due to
1164 | # differences in csv and xlrd parsing. this was a bug that might be
1165 | # fixed now
1166 | rowidsuper = getbulletinids(row[12])
1167 | if rowidsuper == False: rowidsuper=getbulletinids(row[11])
1168 |
1169 | rowidsuper = merge_list(rowidsuper)
1170 |
1171 | # loop through each msid for each row
1172 | for msid in msids:
1173 |
1174 | # debug output, what we're working with
1175 | #print "%s,%s,%s" % (msid, rowid, rowidsuper)
1176 | # MS14-053,MS14-053,['MS13-052', 'MS14-009']
1177 | # MS14-053,MS14-053,['MS13-004']
1178 | # MS14-053,MS14-053,['MS13-004']
1179 | # MS14-053,MS14-053,['MS13-004']
1180 | # MS14-053,MS14-053,['MS13-004']
1181 | # MS14-053,MS14-053,[]
1182 |
1183 | # if the msid matches the row, get the supercedes column (which is a list)
1184 | if msid == rowid or rowid in lmsids:
1185 | #print "%s,%s,%s" % (msid, rowid, rowidsuper)
1186 | lmsids.append(msid)
1187 | lmsids = lmsids + rowidsuper
1188 |
1189 | return sorted(set(lmsids), reverse=True)
1190 |
1191 | # determines whether or not an msid is in a list of exploits. if msid = 0
1192 | # then it will just return the count
1193 | def getexploit(msid = 0):
1194 | # search using searchsploit
1195 | #MS Windows (ListBox/ComboBox Control) Local Exploit (MS03-045) /windows/local/122.c
1196 | #MS Windows Utility Manager Local SYSTEM Exploit (MS04-011) /windows/local/271.c
1197 | #MS Windows 2000 Utility Manager Privilege Elevation Exploit (MS04-019) /windows/local/350.c
1198 | #MS Windows 2K POSIX Subsystem Privilege Escalation Exploit (MS04-020) /windows/local/351.c
1199 | #MS Windows 2000 Universal Language Utility Manager Exploit (MS04-019) /windows/local/352.c
1200 | #MS Windows 2K/XP Task Scheduler .job Exploit (MS04-022) /windows/local/353.c
1201 | #MS Windows 2k Utility Manager (All-In-One) Exploit (MS04-019) /windows/local/355.c
1202 | #MS Windows XP Task Scheduler (.job) Universal Exploit (MS04-022) /windows/local/368.c
1203 | #MS Windows (HTA) Script Execution Exploit (MS05-016) /windows/local/938.cpp
1204 | #MS Windows COM Structured Storage Local Exploit (MS05-012) /windows/local/1019.c
1205 | #MS Windows CSRSS Local Privilege Escalation Exploit (MS05-018) /windows/local/1198.c
1206 | #MS Windows 2k Kernel APC Data-Free Local Escalation Exploit (MS05-055) /windows/local/1407.c
1207 | #MS Windows Telephony Service Command Execution Exploit (MS05-040) /windows/local/1584.cpp
1208 | #MS Windows (NtClose DeadLock) Vulnerability PoC (MS06-030) /windows/local/1910.c
1209 | #MS Windows XP/2K (Mrxsmb.sys) Privilege Escalation PoC (MS06-030) /windows/local/1911.c
1210 | #Microsoft IIS ASP Stack Overflow Exploit (MS06-034) /windows/local/2056.c
1211 | #MS Windows (Windows Kernel) Privilege Escalation Exploit (MS06-049) /windows/local/2412.c
1212 | #MS Windows GDI Local Privilege Escalation Exploit (MS07-017) /windows/local/3688.c
1213 | #MS Windows GDI Local Privilege Escalation Exploit (MS07-017) 2 /windows/local/3755.c
1214 | #Kodak Image Viewer TIF/TIFF Code Execution Exploit PoC (MS07-055) /windows/local/4584.c
1215 | #Microsoft Office .WPS File Stack Overflow Exploit (MS08-011) /windows/local/5107.c
1216 | #Microsoft Office Excel Code Execution Exploit (MS08-014) /windows/local/5287.txt
1217 | #Microsoft Office XP SP3 PPT File Buffer Overflow Exploit (ms08-016) /windows/local/5320.txt
1218 | #MS Windows GDI Image Parsing Stack Overflow Exploit (MS08-021) /windows/local/5442.cpp
1219 |
1220 | #MS Word Record Parsing Buffer Overflow (MS09-027) /windows/local/14693.py
1221 | #MS Excel Malformed FEATHEADER Record Exploit (MS09-067) /windows/local/14706.py
1222 | #MS Word Record Parsing Buffer Overflow MS09-027 (meta) /windows/local/17177.rb
1223 | #MS Internet Explorer Object Tag Exploit (MS03-020) /windows/remote/37.pl
1224 | #MS Windows Media Services Remote Exploit (MS03-022) /windows/remote/48.c
1225 | #Microsoft WordPerfect Document Converter Exploit (MS03-036) /windows/remote/92.c
1226 | #MS Windows (RPC DCOM) Scanner (MS03-039) /windows/remote/97.c
1227 | #MS Windows (RPC DCOM) Long Filename Overflow Exploit (MS03-026) /windows/remote/100.c
1228 | #MS Windows (RPC DCOM2) Remote Exploit (MS03-039) /windows/remote/103.c
1229 | #MS Windows (RPC2) Universal Exploit & DoS (RPC3) (MS03-039) /windows/remote/109.c
1230 | #MS Windows 2000/XP Workstation Service Overflow (MS03-049) /windows/remote/119.c
1231 | #MS Frontpage Server Extensions fp30reg.dll Exploit (MS03-051) /windows/remote/121.c
1232 | #MS Windows Workstation Service WKSSVC Remote Exploit (MS03-049) /windows/remote/123.c
1233 | #MS Windows XP Workstation Service Remote Exploit (MS03-049) /windows/remote/130.c
1234 | #MS Windows Messenger Service Remote Exploit FR (MS03-043) /windows/remote/135.c
1235 | #MS Internet Explorer URL Injection in History List (MS04-004) /windows/remote/151.txt
1236 | #MS Windows IIS 5.0 SSL Remote buffer overflow Exploit (MS04-011) /windows/remote/275.c
1237 | #MS Windows Lsasrv.dll RPC Remote Buffer Overflow Exploit (MS04-011) /windows/remote/293.c
1238 | #MS Windows XP/2K Lsasrv.dll Remote Universal Exploit (MS04-011) /windows/remote/295.c
1239 | #MS Windows JPEG GDI+ Overflow Administrator Exploit (MS04-028) /windows/remote/475.sh
1240 | #MS Windows JPEG GDI+ Overflow Download Shellcode Exploit (MS04-028) /windows/remote/478.c
1241 | #MS Windows JPEG GDI+ Remote Heap Overflow Exploit (MS04-028) /windows/remote/480.c
1242 | #MS Windows Metafile (.emf) Heap Overflow Exploit (MS04-032) /windows/remote/584.c
1243 | #MS Windows Compressed Zipped Folders Exploit (MS04-034) /windows/remote/640.c
1244 | #MS Windows NetDDE Remote Buffer Overflow Exploit (MS04-031) /windows/remote/734.c
1245 | #MS Internet Explorer .ANI files handling Universal Exploit (MS05-002) /windows/remote/765.c
1246 | #MS Internet Explorer .ANI files handling Downloader Exploit (MS05-002) /windows/remote/771.cpp
1247 | #MS Exchange Server Remote Code Execution Exploit (MS05-021) /windows/remote/947.pl
1248 | #MS Outlook Express NNTP Buffer Overflow Exploit (MS05-030) /windows/remote/1066.cpp
1249 | #MS Windows Message Queuing BoF Universal Exploit (MS05-017) (v.0.3) /windows/remote/1075.c
1250 | #MS Internet Explorer (blnmgr.dll) COM Object Remote Exploit (MS05-038) /windows/remote/1144.html
1251 | #MS Windows Plug-and-Play Service Remote Overflow (MS05-039) /windows/remote/1146.c
1252 | #MS Windows Plug-and-Play Service Remote Universal Exploit (MS05-039) /windows/remote/1149.c
1253 | #Microsoft Windows DTC Remote Exploit (PoC) (MS05-051) (updated) /windows/remote/1352.cpp
1254 | #Windows Media Player 7.1 <= 10 BMP Heap Overflow PoC (MS06-005) (2) /windows/remote/1502.py
1255 | #MS Windows Media Player 9 Plugin Overflow Exploit (MS06-006) (meta) /windows/remote/1504.pm
1256 | #MS Windows Media Player 10 Plugin Overflow Exploit (MS06-006) /windows/remote/1505.html
1257 | #MS Windows Color Management Module Overflow Exploit (MS05-036) (2) /windows/remote/1506.c
1258 | #MS Windows Media Player Plugin Overflow Exploit (MS06-006)(3) /windows/remote/1520.pl
1259 | #MS Windows RRAS Remote Stack Overflow Exploit (MS06-025) /windows/remote/1940.pm
1260 | #MS Windows RRAS RASMAN Registry Stack Overflow Exploit (MS06-025) /windows/remote/1965.pm
1261 | #MS Internet Explorer (MDAC) Remote Code Execution Exploit (MS06-014) /windows/remote/2052.sh
1262 | #MS Windows DHCP Client Broadcast Attack Exploit (MS06-036) /windows/remote/2054.txt
1263 | #MS Windows NetpIsRemote() Remote Overflow Exploit (MS06-040) /windows/remote/2162.pm
1264 | #Internet Explorer (MDAC) Remote Code Execution Exploit (MS06-014) (2) /windows/remote/2164.pm
1265 | #MS Windows CanonicalizePathName() Remote Exploit (MS06-040) /windows/remote/2223.c
1266 | #MS Windows NetpIsRemote() Remote Overflow Exploit (MS06-040) (2) /windows/remote/2265.c
1267 | #MS Windows NetpIsRemote() Remote Overflow Exploit (MS06-040) (2k3) /windows/remote/2355.pm
1268 | #MS Windows NetpManageIPCConnect Stack Overflow Exploit (MS06-070) /windows/remote/2789.cpp
1269 | #MS Windows Wkssvc NetrJoinDomain2 Stack Overflow Exploit (MS06-070) /windows/remote/2800.cpp
1270 | #MS Windows ASN.1 Remote Exploit (MS04-007) /windows/remote/3022.txt
1271 | #MS Internet Explorer VML Remote Buffer Overflow Exploit (MS07-004) /windows/remote/3137.html
1272 | #MS Internet Explorer VML Download and Execute Exploit (MS07-004) /windows/remote/3148.pl
1273 | #MS Internet Explorer Recordset Double Free Memory Exploit (MS07-009) /windows/remote/3577.html
1274 | #MS Windows (.ANI) GDI Remote Elevation of Privilege Exploit (MS07-017) /windows/remote/3804.txt
1275 | #MS Internet Explorer <= 7 Remote Arbitrary File Rewrite PoC (MS07-027) /windows/remote/3892.html
1276 | #Microsoft Internet Explorer TIF/TIFF Code Execution (MS07-055) /windows/remote/4616.pl
1277 | #MS Windows Message Queuing Service RPC BOF Exploit (MS07-065) /windows/remote/4745.cpp
1278 | #MS Windows 2000 AS SP4 Message Queue Exploit (MS07-065) /windows/remote/4760.txt
1279 | #Windows Media Encoder wmex.dll ActiveX BOF Exploit (MS08-053) /windows/remote/6454.html
1280 | #MS Windows GDI (EMR_COLORMATCHTOTARGETW) Exploit MS08-021 /windows/remote/6656.txt
1281 | #MS Windows Server Service Code Execution Exploit (MS08-067) (Univ) /windows/remote/6841.txt
1282 | #MS Windows Server Service Code Execution Exploit (MS08-067) /windows/remote/7104.c
1283 | #SmbRelay3 NTLM Replay Attack Tool/Exploit (MS08-068) /windows/remote/7125.txt
1284 | #MS Windows Server Service Code Execution Exploit (MS08-067) (2k/2k3) /windows/remote/7132.py
1285 | #Microsoft XML Core Services DTD Cross-Domain Scripting PoC MS08-069 /windows/remote/7196.html
1286 | #MS Internet Explorer 7 Memory Corruption Exploit (MS09-002) (xp sp2) /windows/remote/8079.html
1287 | #MS Internet Explorer 7 Memory Corruption Exploit (MS09-002) (py) /windows/remote/8080.py
1288 | #MS Internet Explorer 7 Memory Corruption PoC (MS09-002) (win2k3sp2) /windows/remote/8082.html
1289 | #MS Internet Explorer 7 Memory Corruption Exploit (MS09-002) (fast) /windows/remote/8152.py
1290 | #Microsoft SRV2.SYS SMB Negotiate ProcessID Function Table Dereference (MS09-050) /windows/remote/14674.txt
1291 | #Microsoft Services MS06-066 nwwks.dll /windows/remote/16369.rb
1292 | #Microsoft Services MS06-066 nwapi32.dll /windows/remote/16373.rb
1293 | #MS03-020 Internet Explorer Object Type /windows/remote/16581.rb
1294 | #MS03-046 Exchange 2000 XEXCH50 Heap Overflow /windows/remote/16820.rb
1295 |
1296 | # no ms number yet?
1297 | #MS??-???,http://www.exploit-db.com/exploits/30014/,P,??2914486
1298 | # bulletin, type, details
1299 | exploits = [
1300 |
1301 | ['MS16-135', ALERT.EXP, [ # CVE-2016-7255
1302 | "https://www.exploit-db.com/exploits/40745/ -- Microsoft Windows Kernel - win32k Denial of Service (MS16-135)",
1303 | "https://www.exploit-db.com/exploits/41015/ -- Microsoft Windows Kernel - 'win32k.sys' 'NtSetWindowLongPtr' Privilege Escalation (MS16-135) (2)",
1304 | "https://github.com/tinysec/public/tree/master/CVE-2016-7255"]],
1305 |
1306 | ['MS16-129', ALERT.EXP, [ # CVE 2016-7200, CVE-2016-7201
1307 | "https://www.exploit-db.com/exploits/40990/ -- Microsoft Edge (Windows 10) - 'chakra.dll' Info Leak / Type Confusion Remote Code Execution",
1308 | "https://github.com/theori-io/chakra-2016-11"]],
1309 |
1310 | ['MS16-098', ALERT.EXP, [
1311 | "https://www.exploit-db.com/exploits/41020/ -- Microsoft Windows 8.1 (x64) - RGNOBJ Integer Overflow (MS16-098)"]],
1312 |
1313 | ['MS16-075', ALERT.MSF, [
1314 | "https://github.com/foxglovesec/RottenPotato",
1315 | "https://github.com/Kevin-Robertson/Tater",
1316 | "https://bugs.chromium.org/p/project-zero/issues/detail?id=222 -- Windows: Local WebDAV NTLM Reflection Elevation of Privilege",
1317 | "https://foxglovesecurity.com/2016/01/16/hot-potato/ -- Hot Potato - Windows Privilege Escalation"]],
1318 |
1319 | ['MS16-074', ALERT.EXP, [ # CVE 2016-3216
1320 | "https://www.exploit-db.com/exploits/39990/ -- Windows - gdi32.dll Multiple DIB-Related EMF Record Handlers Heap-Based Out-of-Bounds Reads/Memory Disclosure (MS16-074), PoC",
1321 | "https://www.exploit-db.com/exploits/39991/ -- Windows Kernel - ATMFD.DLL NamedEscape 0x250C Pool Corruption (MS16-074), PoC"]], # CVE 2016-3220
1322 |
1323 | ['MS16-063', ALERT.EXP, [ # CVE 2016-0199
1324 | "https://www.exploit-db.com/exploits/39994/ -- Internet Explorer 11 - Garbage Collector Attribute Type Confusion (MS16-063), PoC"]],
1325 |
1326 | ['MS16-042', ALERT.EXP, [ # CVE 2016-0122
1327 | "https://www.exploit-db.com/exploits/39694/ -- Microsoft Office Excel Out-of-Bounds Read Remote Code Execution (MS16-042), PoC"]],
1328 |
1329 | ['MS16-059', ALERT.EXP, [ # CVE 2016-0185
1330 | "https://www.exploit-db.com/exploits/39805/ -- Microsoft Windows Media Center - .MCL File Processing Remote Code Execution (MS16-059), PoC"]],
1331 |
1332 | ['MS16-056', ALERT.EXP, [ # CVE-2015-1730
1333 | "https://www.exploit-db.com/exploits/40881/ -- Microsoft Internet Explorer - jscript9 JavaScriptStackWalker Memory Corruption (MS15-056)",
1334 | "http://blog.skylined.nl/20161206001.html -- MSIE jscript9 JavaScriptStackWalker memory corruption"]],
1335 |
1336 | ['MS16-032', ALERT.EXP, [ # CVE 2016-0099
1337 | "https://www.exploit-db.com/exploits/40107/ -- MS16-032 Secondary Logon Handle Privilege Escalation, MSF",
1338 | "https://www.exploit-db.com/exploits/39574/ -- Microsoft Windows 8.1/10 - Secondary Logon Standard Handles Missing Sanitization Privilege Escalation (MS16-032), PoC",
1339 | "https://www.exploit-db.com/exploits/39719/ -- Microsoft Windows 7-10 & Server 2008-2012 (x32/x64) - Local Privilege Escalation (MS16-032) (PowerShell), PoC",
1340 | "https://www.exploit-db.com/exploits/39809/ -- Microsoft Windows 7-10 & Server 2008-2012 (x32/x64) - Local Privilege Escalation (MS16-032) (C#)"]],
1341 |
1342 | ['MS16-016', ALERT.MSF, [ # CVE 2016-0051
1343 | "https://www.exploit-db.com/exploits/40085/ -- MS16-016 mrxdav.sys WebDav Local Privilege Escalation, MSF",
1344 | "https://www.exploit-db.com/exploits/39788/ -- Microsoft Windows 7 - WebDAV Privilege Escalation Exploit (MS16-016) (2), PoC",
1345 | "https://www.exploit-db.com/exploits/39432/ -- Microsoft Windows 7 SP1 x86 - WebDAV Privilege Escalation (MS16-016) (1), PoC"]],
1346 |
1347 | ['MS16-014', ALERT.EXP, [ # CVE 2016-0400
1348 | "Windows 7 SP1 x86 - Privilege Escalation (MS16-014), https://www.exploit-db.com/exploits/40039/, PoC"]],
1349 |
1350 | ['MS16-007', ALERT.EXP, [ # CVE 2016-0015, CVE 2016-0016
1351 | "https://www.exploit-db.com/exploits/39232/ -- Microsoft Windows devenum.dll!DeviceMoniker::Load() - Heap Corruption Buffer Underflow (MS16-007), PoC",
1352 | "https://www.exploit-db.com/exploits/39233/ -- Microsoft Office / COM Object DLL Planting with WMALFXGFXDSP.dll (MS-16-007), PoC"]],
1353 |
1354 | ['MS15-134', ALERT.EXP, [ # CVE 2015-6131
1355 | "https://www.exploit-db.com/exploits/38911/ -- Microsoft Windows Media Center Library Parsing RCE Vulnerability aka self-executing' MCL File, PoC",
1356 | "https://www.exploit-db.com/exploits/38912/ -- Microsoft Windows Media Center Link File Incorrectly Resolved Reference, PoC",
1357 | "https://www.exploit-db.com/exploits/38918/ -- Microsoft Office / COM Object - 'els.dll' DLL Planting (MS15-134)",
1358 | "https://code.google.com/p/google-security-research/issues/detail?id=514 -- Microsoft Office / COM Object DLL Planting with els.dll"]],
1359 |
1360 | ['MS15-132', ALERT.EXP, [ # CVE 2015-6132, CVE 2015-6128
1361 | "https://www.exploit-db.com/exploits/38968/ -- Microsoft Office / COM Object DLL Planting with comsvcs.dll Delay Load of mqrt.dll (MS15-132), PoC",
1362 | "https://www.exploit-db.com/exploits/38918/ -- Microsoft Office / COM Object els.dll DLL Planting (MS15-134), PoC"]],
1363 |
1364 | ['MS15-112', ALERT.EXP, [ # CVE 2015-6086
1365 | "https://www.exploit-db.com/exploits/39698/ -- Internet Explorer 9/10/11 - CDOMStringDataList::InitFromString Out-of-Bounds Read (MS15-112)"]],
1366 |
1367 | ['MS15-111', ALERT.EXP, [ # CVE 2015-2553
1368 | "https://www.exploit-db.com/exploits/38474/ -- Windows 10 Sandboxed Mount Reparse Point Creation Mitigation Bypass (MS15-111), PoC"]],
1369 |
1370 | ['MS15-102', ALERT.EXP, [ # CVE 2015-2524, CVE 2015-2525, CVE 2015-2528
1371 | "https://www.exploit-db.com/exploits/38202/ -- Windows CreateObjectTask SettingsSyncDiagnostics Privilege Escalation, PoC",
1372 | "https://www.exploit-db.com/exploits/38200/ -- Windows Task Scheduler DeleteExpiredTaskAfter File Deletion Privilege Escalation, PoC",
1373 | "https://www.exploit-db.com/exploits/38201/ -- Windows CreateObjectTask TileUserBroker Privilege Escalation, PoC"]],
1374 |
1375 | ['MS15-100', ALERT.MSF, [ # CVE 2015-2509
1376 | "https://www.exploit-db.com/exploits/38195/ -- MS15-100 Microsoft Windows Media Center MCL Vulnerability, MSF",
1377 | "https://www.exploit-db.com/exploits/38151/ -- Windows Media Center - Command Execution (MS15-100), PoC"]],
1378 |
1379 | ['MS15-097', ALERT.EXP, [ # CVE 2015-2508, CVE 2015-2527
1380 | "https://www.exploit-db.com/exploits/38198/ -- Windows 10 Build 10130 - User Mode Font Driver Thread Permissions Privilege Escalation, PoC",
1381 | "https://www.exploit-db.com/exploits/38199/ -- Windows NtUserGetClipboardAccessToken Token Leak, PoC"]],
1382 |
1383 | ['MS15-078', ALERT.MSF, [ # CVE 2015-2426, CVE 2015-2433
1384 | "https://www.exploit-db.com/exploits/38222/ -- MS15-078 Microsoft Windows Font Driver Buffer Overflow"]],
1385 |
1386 | ['MS15-052', ALERT.EXP, [ # CVE 2015-1674
1387 | "https://www.exploit-db.com/exploits/37052/ -- Windows - CNG.SYS Kernel Security Feature Bypass PoC (MS15-052), PoC"]],
1388 |
1389 | ['MS15-051', ALERT.MSF, [ # CVE 2015-1701
1390 | "https://github.com/hfiref0x/CVE-2015-1701, Win32k Elevation of Privilege Vulnerability, PoC",
1391 | "https://www.exploit-db.com/exploits/37367/ -- Windows ClientCopyImage Win32k Exploit, MSF"]],
1392 |
1393 | ['MS15-022', ALERT.EXP, [ # CVE 2015-0097
1394 | "https://www.exploit-db.com/exploits/37657/ -- Microsoft Word Local Machine Zone Remote Code Execution Vulnerability, PoC",
1395 | "https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/37657.zip"]],
1396 |
1397 | ['MS15-010', ALERT.EXP, [ # CVE 2015-0057
1398 | "https://www.exploit-db.com/exploits/39035/ -- Microsoft Windows 8.1 - win32k Local Privilege Escalation (MS15-010), PoC",
1399 | "https://www.exploit-db.com/exploits/37098/ -- Microsoft Windows - Local Privilege Escalation (MS15-010), PoC",
1400 | "https://www.exploit-db.com/exploits/39035/ -- Microsoft Windows win32k Local Privilege Escalation (MS15-010), PoC"]],
1401 |
1402 | ['MS15-001', ALERT.EXP, [ # CVE 2015-0002
1403 | "http://www.exploit-db.com/exploits/35661/ -- Windows 8.1 (32/64 bit) - Privilege Escalation (ahcache.sys/NtApphelpCacheControl), PoC"]],
1404 |
1405 | ['MS14-070', ALERT.EXP, [ # CVE 2014 4076
1406 | "http://www.exploit-db.com/exploits/35936/ -- Microsoft Windows Server 2003 SP2 - Privilege Escalation, PoC"]],
1407 |
1408 | ['MS14-068', ALERT.EXP, [ # CVE 2014-6324
1409 | "http://www.exploit-db.com/exploits/35474/ -- Windows Kerberos - Elevation of Privilege (MS14-068), PoC"]],
1410 |
1411 | ['MS14-064', ALERT.MSF, [ # CVE 2014-6332
1412 | "https://www.exploit-db.com/exploits/37800// -- Microsoft Windows HTA (HTML Application) - Remote Code Execution (MS14-064), PoC",
1413 | "http://www.exploit-db.com/exploits/35308/ -- Internet Explorer OLE Pre-IE11 - Automation Array Remote Code Execution / Powershell VirtualAlloc (MS14-064), PoC",
1414 | "http://www.exploit-db.com/exploits/35229/ -- Internet Explorer <= 11 - OLE Automation Array Remote Code Execution (#1), PoC",
1415 | "http://www.exploit-db.com/exploits/35230/ -- Internet Explorer < 11 - OLE Automation Array Remote Code Execution (MSF), MSF",
1416 | "http://www.exploit-db.com/exploits/35235/ -- MS14-064 Microsoft Windows OLE Package Manager Code Execution Through Python, MSF",
1417 | "http://www.exploit-db.com/exploits/35236/ -- MS14-064 Microsoft Windows OLE Package Manager Code Execution, MSF"]],
1418 |
1419 | ['MS14-062', ALERT.MSF, [ # CVE 2014-4971
1420 | "http://www.exploit-db.com/exploits/34112/ -- Microsoft Windows XP SP3 MQAC.sys - Arbitrary Write Privilege Escalation, PoC",
1421 | "http://www.exploit-db.com/exploits/34982/ -- Microsoft Bluetooth Personal Area Networking (BthPan.sys) Privilege Escalation"]],
1422 |
1423 | ['MS14-060', ALERT.MSF, [ # CVE 2014-4114
1424 | "http://www.exploit-db.com/exploits/35055/ -- Windows OLE - Remote Code Execution 'Sandworm' Exploit (MS14-060), PoC",
1425 | "http://www.exploit-db.com/exploits/35020/ -- MS14-060 Microsoft Windows OLE Package Manager Code Execution, MSF"]],
1426 |
1427 | ['MS14-058', ALERT.MSF, [ # CVE 2014-4113
1428 | "http://www.exploit-db.com/exploits/35101/ -- Windows TrackPopupMenu Win32k NULL Pointer Dereference, MSF"]],
1429 |
1430 | ['MS14-040', ALERT.EXP, [ # CVE 2014-1767
1431 | "https://www.exploit-db.com/exploits/39525/ -- Microsoft Windows 7 x64 - afd.sys Privilege Escalation (MS14-040), PoC",
1432 | "https://www.exploit-db.com/exploits/39446/ -- Microsoft Windows - afd.sys Dangling Pointer Privilege Escalation (MS14-040), PoC"]],
1433 |
1434 | ['MS14-035', ALERT.EXP],
1435 | ['MS14-029', ALERT.EXP, [
1436 | "http://www.exploit-db.com/exploits/34458/"]],
1437 |
1438 | ['MS14-026', ALERT.EXP, [ # CVE 2014-1806
1439 | "http://www.exploit-db.com/exploits/35280/, -- .NET Remoting Services Remote Command Execution, PoC"]],
1440 |
1441 | ['MS14-017', ALERT.MSF],
1442 | ['MS14-012', ALERT.MSF],
1443 | ['MS14-009', ALERT.MSF],
1444 | ['MS14-002', ALERT.EXP],
1445 | ['MS13-101', ALERT.EXP],
1446 | ['MS13-097', ALERT.MSF],
1447 | ['MS13-096', ALERT.MSF],
1448 | ['MS13-090', ALERT.MSF],
1449 | ['MS13-080', ALERT.MSF],
1450 | ['MS13-071', ALERT.MSF],
1451 | ['MS13-069', ALERT.MSF],
1452 | ['MS13-067', ALERT.EXP],
1453 | ['MS13-059', ALERT.MSF],
1454 | ['MS13-055', ALERT.MSF],
1455 | ['MS13-053', ALERT.MSF],
1456 | ['MS13-009', ALERT.MSF],
1457 | ['MS13-005', ALERT.MSF],
1458 | ['MS12-037', ALERT.EXP, [ # CVE 2012-1876
1459 | "http://www.exploit-db.com/exploits/35273/ -- Internet Explorer 8 - Fixed Col Span ID Full ASLR, DEP & EMET 5., PoC",
1460 | "http://www.exploit-db.com/exploits/34815/ -- Internet Explorer 8 - Fixed Col Span ID Full ASLR, DEP & EMET 5.0 Bypass (MS12-037), PoC"]],
1461 |
1462 | ['MS12-022', ALERT.MSF],
1463 | ['MS11-080', ALERT.MSF],
1464 | ['MS11-011', ALERT.EXP],
1465 | ['MS10-073', ALERT.MSF],
1466 | ['MS10-061', ALERT.MSF],
1467 | ['MS10-059', ALERT.EXP],
1468 | ['MS10-047', ALERT.EXP],
1469 | ['MS10-015', ALERT.MSF],
1470 | ['MS10-002', ALERT.MSF],
1471 | ['MS09-072', ALERT.MSF],
1472 | ['MS09-067', ALERT.MSF],
1473 | ['MS09-065', ALERT.MSF],
1474 | ['MS09-053', ALERT.MSF],
1475 | ['MS09-050', ALERT.MSF, [
1476 | "https://www.rapid7.com/db/modules/exploit/windows/smb/ms09_050_smb2_negotiate_func_index -- MS09-050 Microsoft SRV2.SYS SMB Negotiate ProcessID Function Table Dereference"]],
1477 |
1478 | ['MS09-050', ALERT.MSF],
1479 | ['MS09-043', ALERT.MSF],
1480 | ['MS09-020', ALERT.MSF],
1481 | ['MS09-004', ALERT.MSF],
1482 | ['MS09-002', ALERT.MSF],
1483 | ['MS09-001', ALERT.MSF],
1484 | ['MS08-078', ALERT.MSF],
1485 | ['MS08-070', ALERT.MSF],
1486 | ['MS08-067', ALERT.MSF],
1487 | ['MS08-067', ALERT.MSF],
1488 | ['MS08-053', ALERT.MSF],
1489 | ['MS08-041', ALERT.MSF],
1490 | ['MS08-025', ALERT.EXP],
1491 | ['MS07-065', ALERT.MSF],
1492 | ['MS07-065', ALERT.MSF],
1493 | ['MS07-064', ALERT.MSF],
1494 | ['MS07-029', ALERT.MSF],
1495 | ['MS07-029', ALERT.MSF],
1496 | ['MS07-017', ALERT.MSF],
1497 | ['MS06-071', ALERT.MSF],
1498 | ['MS06-070', ALERT.MSF],
1499 | ['MS06-070', ALERT.MSF],
1500 | ['MS06-067', ALERT.MSF],
1501 | ['MS06-066', ALERT.MSF],
1502 | ['MS06-066', ALERT.MSF],
1503 | ['MS06-063', ALERT.MSF],
1504 | ['MS06-057', ALERT.MSF],
1505 | ['MS06-055', ALERT.MSF],
1506 | ['MS06-049', ALERT.EXP],
1507 | ['MS06-040', ALERT.MSF],
1508 | ['MS06-040', ALERT.MSF],
1509 | ['MS06-035', ALERT.MSF],
1510 | ['MS06-025', ALERT.MSF],
1511 | ['MS06-025', ALERT.MSF],
1512 | ['MS06-019', ALERT.MSF],
1513 | ['MS06-013', ALERT.MSF],
1514 | ['MS06-001', ALERT.MSF],
1515 | ['MS05-054', ALERT.MSF],
1516 | ['MS05-047', ALERT.MSF],
1517 | ['MS05-039', ALERT.MSF],
1518 | ['MS05-039', ALERT.MSF],
1519 | ['MS05-030', ALERT.MSF],
1520 | ['MS05-017', ALERT.MSF],
1521 | ['MS05-017', ALERT.MSF],
1522 | ['MS04-045', ALERT.MSF],
1523 | ['MS04-031', ALERT.MSF],
1524 | ['MS04-031', ALERT.MSF],
1525 | ['MS04-011', ALERT.MSF],
1526 | ['MS04-011', ALERT.MSF],
1527 | ['MS04-007', ALERT.MSF],
1528 | ['MS04-007', ALERT.MSF],
1529 | ['MS03-051', ALERT.MSF],
1530 | ['MS03-049', ALERT.MSF],
1531 | ['MS03-049', ALERT.MSF],
1532 | ['MS03-046', ALERT.MSF],
1533 | ['MS03-026', ALERT.MSF],
1534 | ['MS03-026', ALERT.MSF],
1535 | ['MS03-022', ALERT.MSF],
1536 | ['MS03-020', ALERT.MSF],
1537 | ['MS03-007', ALERT.MSF],
1538 | ['MS02-065', ALERT.MSF],
1539 | ['MS02-063', ALERT.MSF],
1540 | ['MS02-056', ALERT.MSF],
1541 | ['MS02-039', ALERT.MSF],
1542 | ['MS02-018', ALERT.MSF],
1543 | ['MS01-033', ALERT.MSF],
1544 | ['MS01-026', ALERT.MSF],
1545 | ['MS01-023', ALERT.MSF],
1546 | ['MS00-094', ALERT.MSF]
1547 | ]
1548 |
1549 | # return the count of exploits
1550 | if msid == 0: return len(exploits)
1551 |
1552 | for exploit in exploits:
1553 | if msid == exploit[0]:
1554 | # need 3 values to unpack, in case there are resources
1555 | if len(exploit) == 2:
1556 | exploit.append(None)
1557 | return exploit
1558 |
1559 | # otherwise there are 3 values
1560 | return exploit
1561 |
1562 | return [False,False,False]
1563 |
1564 | # the update function
1565 | def update():
1566 |
1567 | # compute the filenames to be used
1568 | filenames = '%s-mssb' % datetime.datetime.now().strftime('%Y-%m-%d')
1569 | xlsFile = '%s.%s' % (filenames, 'xlsx') #MS now puts out XLSX files, not XLS
1570 | csvFile = '%s.%s' % (filenames, 'csv')
1571 |
1572 | # url request opener with user-agent
1573 | opener = urllib.request.build_opener()
1574 | opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36')]
1575 |
1576 | # grab the new data from ms and scrape the site
1577 | #try:
1578 | # response = opener.open(MSSB_URL)
1579 | #except urllib2.URLError, e:
1580 | # ALERT("error getting url %s" % MSSB_URL, ALERT.BAD)
1581 | # exit(1)
1582 | #
1583 | #ALERT("successfully requested base url")
1584 |
1585 | # 2016-02-10, ms changed link to http://download.microsoft.com/download/6/7/3/673E4349-1CA5-40B9-8879-095C72D5B49D/BulletinSearch.xlsx
1586 | #
1587 | # now parse the data, ensure we have an mssb link
1588 | # BulletinSearch_20131111_151603.xlsx (recommended) |
1589 | #html = response.read()
1590 | #m = re.findall('url=(.*BulletinSearch.*.xls[x]*)', html)
1591 | # m = re.findall('href="(.*BulletinSearch.*.xlsx)"', html) # old bulletin request url, 20140502
1592 |
1593 | # ensure we get the bulletin search
1594 | #if m and m[0]:
1595 | bulletinUrl = BULLETIN_URL
1596 | # ALERT("scraped ms download url")
1597 | # if the file was xlsx, add an x to the extension
1598 | # if "xlsx" in bulletinUrl: xlsFile += "x"
1599 | #else:
1600 | # ALERT("error finding the ms download url from previous response", ALERT.BAD)
1601 | # exit(1)
1602 |
1603 | # now download the mssb file, with a random sleep
1604 | try:
1605 | #sleep(randint(1,3))
1606 | response = opener.open(bulletinUrl)
1607 | except urllib.error.URLError as e:
1608 | ALERT("error getting ms sb url %s" % bulletinUrl, ALERT.BAD)
1609 | exit(1)
1610 |
1611 | bulletinData = response.read()
1612 |
1613 | ALERT("writing to file %s" % xlsFile, ALERT.GOOD)
1614 | f = open(xlsFile, 'wb')
1615 | f.write(bulletinData)
1616 | f.close
1617 |
1618 | # modified ALERT class for exploit and metasploit level logging
1619 | class ALERT(object):
1620 |
1621 | def __init__(self, message, level=0, ansi=True):
1622 |
1623 | # default to ansi alerting, if it's detected as windows platform then disable
1624 | if platform.system() == "Windows": ansi = False
1625 |
1626 | good = '[+]'
1627 | bad = '[-]'
1628 | normal = '[*]'
1629 |
1630 | msf = '[M]'
1631 | exploit = '[E]'
1632 |
1633 | if ansi == True:
1634 | if level == ALERT.GOOD: print("%s%s%s" % ('\033[1;32m',good,"\033[0;0m")),
1635 | elif level == ALERT.BAD: print("%s%s%s" % ('\033[1;31m',bad,"\033[0;0m")),
1636 | elif level == ALERT.MSF: print("%s%s%s" % ('\033[1;32m',msf,"\033[0;0m")),
1637 | elif level == ALERT.EXP: print("%s%s%s" % ('\033[1;32m',exploit,"\033[0;0m")),
1638 | else: print("%s%s%s" % ('\033[1;34m',normal,"\033[0;0m")),
1639 |
1640 | else:
1641 | if level == ALERT.GOOD: print('%s' % good),
1642 | elif level == ALERT.BAD: print('%s' % bad),
1643 | elif level == ALERT.MSF: print('%s' % msf),
1644 | elif level == ALERT.EXP: print('%s' % exploit),
1645 | else: print('%s' % normal),
1646 |
1647 | print(message)
1648 |
1649 | @staticmethod
1650 | @property
1651 | def BAD(self): return -1
1652 |
1653 | @staticmethod
1654 | @property
1655 | def NORMAL(self): return 0
1656 |
1657 | @staticmethod
1658 | @property
1659 | def GOOD(self): return 1
1660 |
1661 | @staticmethod
1662 | @property
1663 | def MSF(self): return 2
1664 |
1665 | @staticmethod
1666 | @property
1667 | def EXP(self): return 3
1668 |
1669 | # this helper function will merge a list of lists into one sorted set
1670 | def merge_list(li):
1671 | s = []
1672 | if li:
1673 | for l in li:
1674 | if isinstance(l, list): s = s + l
1675 | else: s.append(l)
1676 | return s
1677 |
1678 | if __name__ == '__main__':
1679 | main()
1680 |
1681 |
--------------------------------------------------------------------------------