CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/tools/exploit/msu_finder.rb
Views: 1904
1
#!/usr/bin/env ruby
2
3
##
4
# This module requires Metasploit: https://metasploit.com/download
5
# Current source: https://github.com/rapid7/metasploit-framework
6
##
7
begin
8
require 'patch_finder/core/helper'
9
require 'patch_finder/msu'
10
require 'optparse'
11
12
class PatchFinderBin
13
14
include PatchFinder::Helper
15
16
attr_reader :args
17
18
def get_parsed_options
19
options = {}
20
21
parser = OptionParser.new do |opt|
22
opt.separator ''
23
opt.separator 'Specific options:'
24
25
opt.on('-q', '--query <keyword>', 'Find advisories including this keyword') do |v|
26
options[:keyword] = v
27
end
28
29
opt.on('-s', '--search-engine <engine>', '(Optional) The type of search engine to use (Technet or Google). Default: Technet') do |v|
30
case v.to_s
31
when /^google$/i
32
options[:search_engine] = :google
33
when /^technet$/i
34
options[:search_engine] = :technet
35
else
36
fail OptionParser::InvalidOption, "Invalid search engine: #{v}"
37
end
38
end
39
40
opt.on('-r', '--regex <string>', '(Optional) Specify what type of links you want') do |v|
41
options[:regex] = v
42
end
43
44
opt.on('--apikey <key>', '(Optional) Google API key.') do |v|
45
options[:google_api_key] = v
46
end
47
48
opt.on('--cx <id>', '(Optional) Google search engine ID.') do |v|
49
options[:google_search_engine_id] = v
50
end
51
52
opt.on('-d', '--dir <string>', '(Optional) The directory to save the patches') do |v|
53
unless File.directory?(v)
54
fail OptionParser::InvalidOption, "Directory not found: #{v}"
55
end
56
57
options[:destdir] = v
58
end
59
60
opt.on_tail('-h', '--help', 'Show this message') do
61
$stderr.puts opt
62
exit
63
end
64
end
65
66
parser.parse!
67
68
if options.empty?
69
fail OptionParser::MissingArgument, 'No options set, try -h for usage'
70
elsif options[:keyword].nil? || options[:keyword].empty?
71
fail OptionParser::MissingArgument, '-q is required'
72
end
73
74
unless options[:search_engine]
75
options[:search_engine] = :technet
76
end
77
78
if options[:search_engine] == :google
79
if options[:google_api_key].nil? || options[:google_search_engine_id].empty?
80
fail OptionParser::MissingArgument, 'No API key set for Google'
81
elsif options[:google_search_engine_id].nil? || options[:google_search_engine_id].empty?
82
fail OptionParser::MissingArgument, 'No search engine ID set for Google'
83
end
84
end
85
86
options
87
end
88
89
def initialize
90
@args = get_parsed_options
91
rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
92
print_error(e.message)
93
exit
94
end
95
96
def main
97
cli = PatchFinder::MSU.new(verbose: true)
98
links = cli.find_msu_download_links(args)
99
if args[:destdir]
100
print_status("Download links found: #{links.length}")
101
print_status('Downloading files, please wait...')
102
download_files(links, args[:destdir])
103
else
104
print_status('Download links found:')
105
print_line(links * "\n")
106
end
107
end
108
end
109
110
if __FILE__ == $PROGRAM_NAME
111
bin = PatchFinderBin.new
112
bin.main
113
end
114
rescue SignalException => e
115
puts("Aborted! #{e}")
116
end
117
118