From d9f0a10737d487b11a5f57b9a2fbdfa13148d238 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 08:06:31 -0700 Subject: [PATCH 01/14] Add new example template for scanning UDP services --- .../auxiliary/scanner/udp_scanner_template.rb | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 modules/auxiliary/scanner/udp_scanner_template.rb diff --git a/modules/auxiliary/scanner/udp_scanner_template.rb b/modules/auxiliary/scanner/udp_scanner_template.rb new file mode 100644 index 0000000000..2a0f3b8e76 --- /dev/null +++ b/modules/auxiliary/scanner/udp_scanner_template.rb @@ -0,0 +1,88 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::UDPScanner + + def initialize + super( + 'Name' => 'UDP Scanner Example', + 'Description' => %q( + This module does stuff + ), + 'Author' => 'Joe Contributor ', + 'References' => + [ + ['URL', 'https://example.com/~jcontributor'] + ], + 'DisclosureDate' => 'Mar 15 2014', + 'License' => MSF_LICENSE + ) + register_options( + [ + Opt::RPORT(12345) + ], self.class) + + register_advanced_options( + [ + OptBool.new('SPECIAL', [true, 'Try this special thing', false]) + ], self.class) + end + + # Called for each IP in the batch + def scan_host(ip) + if datastore['SPECIAL'] + scanner_send("Please and thank you, #{ip}!", ip, rport) + else + scanner_send(@probe, ip, datastore['RPORT']) + end + end + + # Called for each response packet + def scanner_process(data, src_host, src_port) + @results[src_host] ||= [] + @results[src_host] << data.inspect + end + + # Called before the scan block + def scanner_prescan(batch) + @results = {} + @probe = "abracadabra!" + end + + # Called after the scan block + def scanner_postscan(batch) + @results.each_pair do |host, responses| + + # consider confirming that any of the responses are actually + # valid responses for this service before reporing it or + # examining the responses for signs of a vulnerability + report_service( + host: host, + proto:'udp', + port: rport, + name: 'example' + ) + + if responses.any? { |response| response =~ /[a-z0-9]{5}/i } + print_good("#{peer} - Vulnerable to something!") + report_vuln( + host: k, + port: rport, + proto: 'udp', + name: 'something!', + refs: references + ) + else + vprint_status("#{peer} - Not vulnerable to something") + end + end + end +end From 77cd6dbc8be4adc1e93c9538c160e8e14fe9df5a Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 09:20:14 -0700 Subject: [PATCH 02/14] Usability improvements to UDPScanner * Add RPORT as a regular option, define rport * Add CPORT as an advanced option, define cport * Change CHOST to an advanced option * Use a more sane THREADS value since hosts are scanned in batches --- lib/msf/core/auxiliary/udp_scanner.rb | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/msf/core/auxiliary/udp_scanner.rb b/lib/msf/core/auxiliary/udp_scanner.rb index a7d654a362..5e75c7c0cb 100644 --- a/lib/msf/core/auxiliary/udp_scanner.rb +++ b/lib/msf/core/auxiliary/udp_scanner.rb @@ -20,21 +20,23 @@ module Auxiliary::UDPScanner register_options( [ - Opt::CHOST, - OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]), + Opt::RPORT, + OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]) + OptInt.new('THREADS', [true, "The number of concurrent threads", 10]) ], self.class) register_advanced_options( [ + Opt::CHOST, + Opt::CPORT, OptInt.new('ScannerRecvInterval', [true, 'The maximum numbers of sends before entering the processing loop', 30]), OptInt.new('ScannerMaxResends', [true, 'The maximum times to resend a packet when out of buffers', 10]), OptInt.new('ScannerRecvQueueLimit', [true, 'The maximum queue size before breaking out of the processing loop', 100]), - OptInt.new('ScannerRecvWindow', [true, 'The number of seconds to wait post-scan to catch leftover replies', 15]), + OptInt.new('ScannerRecvWindow', [true, 'The number of seconds to wait post-scan to catch leftover replies', 15]) ], self.class) end - # Define our batch size def run_batch_size datastore['BATCHSIZE'].to_i @@ -44,6 +46,7 @@ module Auxiliary::UDPScanner def run_batch(batch) @udp_sock = Rex::Socket::Udp.create({ 'LocalHost' => datastore['CHOST'] || nil, + 'LocalPort' => datastore['CPORT'] || 0, 'Context' => { 'Msf' => framework, 'MsfExploit' => self } }) add_socket(@udp_sock) @@ -155,6 +158,14 @@ module Auxiliary::UDPScanner queue.length end + def cport + datastore['CPORT'] + end + + def rport + datastore['RPORT'] + end + # # The including module override these methods # From f66c43475b52e350c1517ac87982ef94c9d1c602 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 09:39:21 -0700 Subject: [PATCH 03/14] More sane % printing for aux scanner --- lib/msf/core/auxiliary/scanner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/core/auxiliary/scanner.rb b/lib/msf/core/auxiliary/scanner.rb index fade61b0ea..5ac3c5fd01 100644 --- a/lib/msf/core/auxiliary/scanner.rb +++ b/lib/msf/core/auxiliary/scanner.rb @@ -244,7 +244,7 @@ def scanner_show_progress if(pct >= (@range_percent + @show_percent)) @range_percent = @range_percent + @show_percent tdlen = @range_count.to_s.length - print_status("Scanned #{"%.#{tdlen}d" % @range_done} of #{@range_count} hosts (#{"%.3d" % pct.to_i}% complete)") + print_status("Scanned #{"%.#{tdlen}d" % @range_done} of #{@range_count} hosts (#{"%.3g" % pct}% complete)") end end From f16720bb55b7e8048e00104eb0d5c8fc6d72196b Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 09:39:34 -0700 Subject: [PATCH 04/14] Trailing , --- lib/msf/core/auxiliary/udp_scanner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/core/auxiliary/udp_scanner.rb b/lib/msf/core/auxiliary/udp_scanner.rb index 5e75c7c0cb..b2d6d13efd 100644 --- a/lib/msf/core/auxiliary/udp_scanner.rb +++ b/lib/msf/core/auxiliary/udp_scanner.rb @@ -21,7 +21,7 @@ module Auxiliary::UDPScanner register_options( [ Opt::RPORT, - OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]) + OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]), OptInt.new('THREADS', [true, "The number of concurrent threads", 10]) ], self.class) From 94d4388af9609295efb63a96491bf5cf1c5367ba Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 09:53:10 -0700 Subject: [PATCH 05/14] Improvements to example UDPScanner --- modules/auxiliary/scanner/udp_scanner_template.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/auxiliary/scanner/udp_scanner_template.rb b/modules/auxiliary/scanner/udp_scanner_template.rb index 2a0f3b8e76..a68c454869 100644 --- a/modules/auxiliary/scanner/udp_scanner_template.rb +++ b/modules/auxiliary/scanner/udp_scanner_template.rb @@ -8,7 +8,6 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Report - include Msf::Exploit::Remote::Udp include Msf::Auxiliary::UDPScanner def initialize @@ -25,11 +24,14 @@ class Metasploit3 < Msf::Auxiliary 'DisclosureDate' => 'Mar 15 2014', 'License' => MSF_LICENSE ) + register_options( [ + # TODO: change to the port you need to scan Opt::RPORT(12345) ], self.class) + # TODO: add any advanced, special options here, otherwise remove register_advanced_options( [ OptBool.new('SPECIAL', [true, 'Try this special thing', false]) @@ -39,10 +41,9 @@ class Metasploit3 < Msf::Auxiliary # Called for each IP in the batch def scan_host(ip) if datastore['SPECIAL'] - scanner_send("Please and thank you, #{ip}!", ip, rport) - else - scanner_send(@probe, ip, datastore['RPORT']) + @probe = "Please and thank you, #{ip}!" end + scanner_send(@probe, ip, datastore['RPORT']) end # Called for each response packet @@ -60,6 +61,7 @@ class Metasploit3 < Msf::Auxiliary # Called after the scan block def scanner_postscan(batch) @results.each_pair do |host, responses| + peer = "#{host}:#{rport}" # consider confirming that any of the responses are actually # valid responses for this service before reporing it or @@ -74,7 +76,7 @@ class Metasploit3 < Msf::Auxiliary if responses.any? { |response| response =~ /[a-z0-9]{5}/i } print_good("#{peer} - Vulnerable to something!") report_vuln( - host: k, + host: host, port: rport, proto: 'udp', name: 'something!', From 1f6658639f4b31289a7145bb06b4bca261d1ad01 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 10:25:01 -0700 Subject: [PATCH 06/14] More sane % printing for aux scanner --- lib/msf/core/auxiliary/scanner.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/msf/core/auxiliary/scanner.rb b/lib/msf/core/auxiliary/scanner.rb index 5ac3c5fd01..d428daa6a1 100644 --- a/lib/msf/core/auxiliary/scanner.rb +++ b/lib/msf/core/auxiliary/scanner.rb @@ -241,10 +241,10 @@ end def scanner_show_progress pct = scanner_progress - if(pct >= (@range_percent + @show_percent)) + if pct >= (@range_percent + @show_percent) @range_percent = @range_percent + @show_percent tdlen = @range_count.to_s.length - print_status("Scanned #{"%.#{tdlen}d" % @range_done} of #{@range_count} hosts (#{"%.3g" % pct}% complete)") + print_status(sprintf("Scanned %#{tdlen}d of %d hosts (%d%% complete)", @range_done, @range_count, pct)) end end From ff0b52cffb53fa8ac1595e3f078de618e9b67a5b Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 10:31:31 -0700 Subject: [PATCH 07/14] Example per-batch vprint, a useful default --- modules/auxiliary/scanner/udp_scanner_template.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/auxiliary/scanner/udp_scanner_template.rb b/modules/auxiliary/scanner/udp_scanner_template.rb index a68c454869..bb469159e0 100644 --- a/modules/auxiliary/scanner/udp_scanner_template.rb +++ b/modules/auxiliary/scanner/udp_scanner_template.rb @@ -54,6 +54,7 @@ class Metasploit3 < Msf::Auxiliary # Called before the scan block def scanner_prescan(batch) + vprint_status("Sending probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)") @results = {} @probe = "abracadabra!" end From c921611821c7320e34df91dc96768a0a303e4d2f Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 12:02:21 -0700 Subject: [PATCH 08/14] Move default probe and result store to UDPScanner, since most need it --- lib/msf/core/auxiliary/udp_scanner.rb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/msf/core/auxiliary/udp_scanner.rb b/lib/msf/core/auxiliary/udp_scanner.rb index b2d6d13efd..fbf70c3544 100644 --- a/lib/msf/core/auxiliary/udp_scanner.rb +++ b/lib/msf/core/auxiliary/udp_scanner.rb @@ -8,13 +8,17 @@ module Msf # ### module Auxiliary::UDPScanner - include Auxiliary::Scanner + # A hash of results of a given batch run, keyed by host + attr_accessor :results + + # A probe to be sent to each host + attr_accessor :probe + # # Initializes an instance of an auxiliary module that scans UDP # - def initialize(info = {}) super @@ -167,11 +171,12 @@ module Auxiliary::UDPScanner end # - # The including module override these methods + # The including module may override some of these methods # - # Called for each IP in the batch + # Called for each IP in the batch. This will send all necessary probes. def scan_host(ip) + scanner_send(@probe, ip, datastore['RPORT']) end # Called for each response packet @@ -180,11 +185,12 @@ module Auxiliary::UDPScanner # Called before the scan block def scanner_prescan(batch) + vprint_status("Sending probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)") + @results = {} end # Called after the scan block def scanner_postscan(batch) end - end end From b99e71dcddbb89ad03c97e923bdd25d9403c58b9 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 12:14:04 -0700 Subject: [PATCH 09/14] Example UDPScanner style cleanup, move most to UDPScanner --- .../auxiliary/scanner/udp_scanner_template.rb | 79 +++++++++++++------ 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/modules/auxiliary/scanner/udp_scanner_template.rb b/modules/auxiliary/scanner/udp_scanner_template.rb index bb469159e0..a880e1b96b 100644 --- a/modules/auxiliary/scanner/udp_scanner_template.rb +++ b/modules/auxiliary/scanner/udp_scanner_template.rb @@ -6,15 +6,18 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary - include Msf::Auxiliary::Report include Msf::Auxiliary::UDPScanner def initialize super( + # TODO: fill in all of this 'Name' => 'UDP Scanner Example', 'Description' => %q( - This module does stuff + This module is an example of how to send probes to UDP services + en-masse, analyze any responses, and then report on any discovered + hosts, services, vulnerabilities or otherwise noteworthy things. + Simply address any of the TODOs. ), 'Author' => 'Joe Contributor ', 'References' => @@ -38,53 +41,77 @@ class Metasploit3 < Msf::Auxiliary ], self.class) end - # Called for each IP in the batch + def setup + super + # TODO: do any sort of preliminary sanity checking, like perhaps validating some options + # in the datastore, etc. + + # TODO: build the appropriate probe here + @probe = 'abracadabra!' + end + + # TODO: this is called before the scan block for each batch of hosts. Do any + # per-batch setup here, otherwise remove it. + def scanner_prescan(batch) + super + end + + # TODO: this is called for each IP in the batch. This will send all of the + # necessary probes. If something different must be done for each IP, do it + # here, otherwise remove it. def scan_host(ip) - if datastore['SPECIAL'] - @probe = "Please and thank you, #{ip}!" - end - scanner_send(@probe, ip, datastore['RPORT']) + super end # Called for each response packet - def scanner_process(data, src_host, src_port) + def scanner_process(response, src_host, _src_port) + # TODO: inspect each response, perhaps confirming that it is a valid + # response for the service/protocol in question and/or analyzing it more + # closely. In this case, we simply check to see that it is of reasonable + # size and storing a result for this host iff so. Note that src_port may + # not actually be the same as the original RPORT for some services if they + # respond back from different ports + return unless response.size >= 42 @results[src_host] ||= [] - @results[src_host] << data.inspect - end - # Called before the scan block - def scanner_prescan(batch) - vprint_status("Sending probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)") - @results = {} - @probe = "abracadabra!" + # TODO: store something about this response, perhaps the response itself, + # some metadata obtained by analyzing it, the proof that it is vulnerable + # to something, etc. In this example, we simply look for any response + # with a sequence of 5 useful ASCII characters and, iff found, we store + # that sequence + /(?[\x20-\x7E]{5})/ =~ response && @results[src_host] << relevant end # Called after the scan block - def scanner_postscan(batch) - @results.each_pair do |host, responses| + def scanner_postscan(_batch) + @results.each_pair do |host, relevant_responses| peer = "#{host}:#{rport}" - # consider confirming that any of the responses are actually - # valid responses for this service before reporing it or - # examining the responses for signs of a vulnerability + # report on the host + report_host(host: host) + + # report on the service, since it responded report_service( host: host, - proto:'udp', + proto: 'udp', port: rport, - name: 'example' + name: 'example', + # show at most 4 relevant responses + info: relevant_responses[0, 4].join(',') ) - if responses.any? { |response| response =~ /[a-z0-9]{5}/i } - print_good("#{peer} - Vulnerable to something!") + if relevant_responses.empty? + vprint_status("#{peer} Not vulnerable to something") + else + print_good("#{peer} Vulnerable to something!") report_vuln( host: host, port: rport, proto: 'udp', name: 'something!', + info: "Got #{relevant_responses.size} response(s)", refs: references ) - else - vprint_status("#{peer} - Not vulnerable to something") end end end From f5ee2d794811f6250edb6b47c653a64f5e0c37c5 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 12:15:32 -0700 Subject: [PATCH 10/14] Update .rubocop.yml to use correct Metrics namespace --- .rubocop.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index c9ba4d1bb3..d84e328c09 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -8,7 +8,7 @@ # inherit_from: .rubocop_todo.yml -Style/ClassLength: +Metrics/ClassLength: Description: 'Most Metasploit modules are quite large. This is ok.' Enabled: true Exclude: @@ -25,14 +25,14 @@ Style/Encoding: Description: 'We prefer binary to UTF-8.' EnforcedStyle: 'when_needed' -Style/LineLength: +Metrics/LineLength: Description: >- Metasploit modules often pattern match against very long strings when identifying targets. Enabled: true Max: 180 -Style/MethodLength: +Metrics/MethodLength: Enabled: true Description: >- While the style guide suggests 10 lines, exploit definitions From 83475bb92962b5df8a4c387aec482c4809c56295 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 12:19:17 -0700 Subject: [PATCH 11/14] Disable UnneededPercentQ in Rubocop --- .rubocop.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index d84e328c09..95aeb51d59 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -44,6 +44,11 @@ Metrics/MethodLength: Style/Encoding: Enabled: false +# %q() is super useful for long strings split over multiple lines and +# is very common in module constructors for things like descriptions +Style/UnneededPercentQ: + Enabled: false + Style/NumericLiterals: Enabled: false Description: 'This often hurts readability for exploit-ish code.' From 121ebdfef607d467b38f37affb15153039442f8c Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 31 Oct 2014 13:17:50 -0700 Subject: [PATCH 12/14] update_info --- .../auxiliary/scanner/udp_scanner_template.rb | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/modules/auxiliary/scanner/udp_scanner_template.rb b/modules/auxiliary/scanner/udp_scanner_template.rb index a880e1b96b..07eedc1385 100644 --- a/modules/auxiliary/scanner/udp_scanner_template.rb +++ b/modules/auxiliary/scanner/udp_scanner_template.rb @@ -9,23 +9,26 @@ class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Auxiliary::UDPScanner - def initialize + def initialize(info = {}) super( - # TODO: fill in all of this - 'Name' => 'UDP Scanner Example', - 'Description' => %q( - This module is an example of how to send probes to UDP services - en-masse, analyze any responses, and then report on any discovered - hosts, services, vulnerabilities or otherwise noteworthy things. - Simply address any of the TODOs. - ), - 'Author' => 'Joe Contributor ', - 'References' => - [ - ['URL', 'https://example.com/~jcontributor'] - ], - 'DisclosureDate' => 'Mar 15 2014', - 'License' => MSF_LICENSE + update_info( + info, + # TODO: fill in all of this + 'Name' => 'UDP Scanner Example', + 'Description' => %q( + This module is an example of how to send probes to UDP services + en-masse, analyze any responses, and then report on any discovered + hosts, services, vulnerabilities or otherwise noteworthy things. + Simply address any of the TODOs. + ), + 'Author' => 'Joe Contributor ', + 'References' => + [ + ['URL', 'https://example.com/~jcontributor'] + ], + 'DisclosureDate' => 'Mar 15 2014', + 'License' => MSF_LICENSE + ) ) register_options( From 05dd3fa4ba48ab74c612cf977ca9c985d19bb580 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Mon, 3 Nov 2014 08:26:11 -0800 Subject: [PATCH 13/14] rport, not datastore['RPORT'] --- lib/msf/core/auxiliary/udp_scanner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/core/auxiliary/udp_scanner.rb b/lib/msf/core/auxiliary/udp_scanner.rb index fbf70c3544..5a749e3ac6 100644 --- a/lib/msf/core/auxiliary/udp_scanner.rb +++ b/lib/msf/core/auxiliary/udp_scanner.rb @@ -176,7 +176,7 @@ module Auxiliary::UDPScanner # Called for each IP in the batch. This will send all necessary probes. def scan_host(ip) - scanner_send(@probe, ip, datastore['RPORT']) + scanner_send(@probe, ip, rport) end # Called for each response packet From 8f197d49184a0e220ad85524d7ebf7db136a3c58 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Mon, 3 Nov 2014 08:41:51 -0800 Subject: [PATCH 14/14] Move to build_probe --- lib/msf/core/auxiliary/udp_scanner.rb | 9 +++++---- modules/auxiliary/scanner/udp_scanner_template.rb | 6 ++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/msf/core/auxiliary/udp_scanner.rb b/lib/msf/core/auxiliary/udp_scanner.rb index 5a749e3ac6..27950bf9e7 100644 --- a/lib/msf/core/auxiliary/udp_scanner.rb +++ b/lib/msf/core/auxiliary/udp_scanner.rb @@ -13,9 +13,6 @@ module Auxiliary::UDPScanner # A hash of results of a given batch run, keyed by host attr_accessor :results - # A probe to be sent to each host - attr_accessor :probe - # # Initializes an instance of an auxiliary module that scans UDP # @@ -174,9 +171,13 @@ module Auxiliary::UDPScanner # The including module may override some of these methods # + # Builds and returns the probe to be sent + def build_probe + end + # Called for each IP in the batch. This will send all necessary probes. def scan_host(ip) - scanner_send(@probe, ip, rport) + scanner_send(build_probe, ip, rport) end # Called for each response packet diff --git a/modules/auxiliary/scanner/udp_scanner_template.rb b/modules/auxiliary/scanner/udp_scanner_template.rb index 07eedc1385..065e5f351b 100644 --- a/modules/auxiliary/scanner/udp_scanner_template.rb +++ b/modules/auxiliary/scanner/udp_scanner_template.rb @@ -48,9 +48,11 @@ class Metasploit3 < Msf::Auxiliary super # TODO: do any sort of preliminary sanity checking, like perhaps validating some options # in the datastore, etc. + end - # TODO: build the appropriate probe here - @probe = 'abracadabra!' + # TODO: construct the appropriate probe here. + def build_probe + @probe ||= 'abracadabra!' end # TODO: this is called before the scan block for each batch of hosts. Do any