From a4a0a3ab2361deb7005d03216401ba7443d51c1b Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Tue, 25 Aug 2020 16:51:47 -0400 Subject: [PATCH 1/3] Allow scanner modules to skip hosts on fail_with --- lib/msf/core/auxiliary/scanner.rb | 12 ++++++++---- modules/auxiliary/scanner/http/jupyter_login.rb | 10 +++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/msf/core/auxiliary/scanner.rb b/lib/msf/core/auxiliary/scanner.rb index b83f1e779fbd..a156b4de804b 100644 --- a/lib/msf/core/auxiliary/scanner.rb +++ b/lib/msf/core/auxiliary/scanner.rb @@ -119,6 +119,8 @@ def run if datastore['CHOST'] @scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable" end + rescue Msf::Auxiliary::Failed => e + print_error("#{nmod.respond_to?(:peer) ? nmod.peer : tip} - #{e}") rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error, ::EOFError rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError raise $! @@ -198,10 +200,12 @@ def run mybatch = bat.dup begin nmod.run_batch(mybatch) - rescue ::Rex::BindFailed - if datastore['CHOST'] - @scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable" - end + rescue ::Rex::BindFailed + if datastore['CHOST'] + @scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable" + end + rescue Msf::Auxiliary::Failed => e + print_error("#{e}") rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError raise $! diff --git a/modules/auxiliary/scanner/http/jupyter_login.rb b/modules/auxiliary/scanner/http/jupyter_login.rb index d329e1d3ddd2..e72b0ffb0d29 100644 --- a/modules/auxiliary/scanner/http/jupyter_login.rb +++ b/modules/auxiliary/scanner/http/jupyter_login.rb @@ -48,7 +48,7 @@ def requires_password?(_ip) destination = res.headers['Location'].split('?', 2)[0] return true if destination.end_with?(normalize_uri(target_uri.path, 'login')) - fail_with(Failure::UnexpectedReply, "#{peer} - The server responded with a redirect that did not match a known fingerprint") + fail_with(Failure::UnexpectedReply, "The server responded with a redirect that did not match a known fingerprint") end def run_host(ip) @@ -56,11 +56,11 @@ def run_host(ip) 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'api') }) + fail_with(Failure::Unreachable, 'Failed to fetch the Jupyter API version') if res.nil? + version = res&.get_json_document&.dig('version') - if version.nil? - vprint_error "#{peer} - The server does not appear to be running Jupyter (failed to fetch the API version)" - return - end + fail_with(Failure::UnexpectedReply, 'Failed to fetch the Jupyter API version') if version.nil? + vprint_status "#{peer} - The server responded that it is running Jupyter version: #{version}" unless requires_password?(ip) From d1baf9677e3af141bffa67a50e5358edf7adfc5f Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Tue, 25 Aug 2020 17:43:07 -0400 Subject: [PATCH 2/3] Use nmod.vprint_error to handle `peer` correctly --- 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 a156b4de804b..877538ac399e 100644 --- a/lib/msf/core/auxiliary/scanner.rb +++ b/lib/msf/core/auxiliary/scanner.rb @@ -120,7 +120,7 @@ def run @scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable" end rescue Msf::Auxiliary::Failed => e - print_error("#{nmod.respond_to?(:peer) ? nmod.peer : tip} - #{e}") + nmod.vprint_error("#{e}") rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error, ::EOFError rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError raise $! From 855aa3c5210ecf99899fae1e478664f84dbb29fd Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Wed, 26 Aug 2020 09:10:01 -0400 Subject: [PATCH 3/3] Override fail_with in auxiliary/scanner to add an abort kwarg --- lib/msf/core/auxiliary.rb | 4 ++-- lib/msf/core/auxiliary/scanner.rb | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/msf/core/auxiliary.rb b/lib/msf/core/auxiliary.rb index 625bf4579a2e..7fd71783a765 100644 --- a/lib/msf/core/auxiliary.rb +++ b/lib/msf/core/auxiliary.rb @@ -13,14 +13,14 @@ module Msf ### class Auxiliary < Msf::Module - require 'msf/core/auxiliary/mixins' - class Complete < RuntimeError end class Failed < RuntimeError end + require 'msf/core/auxiliary/mixins' + include HasActions # diff --git a/lib/msf/core/auxiliary/scanner.rb b/lib/msf/core/auxiliary/scanner.rb index 877538ac399e..2a401b92daec 100644 --- a/lib/msf/core/auxiliary/scanner.rb +++ b/lib/msf/core/auxiliary/scanner.rb @@ -1,4 +1,5 @@ # -*- coding: binary -*- + module Msf ### @@ -9,6 +10,8 @@ module Msf module Auxiliary::Scanner +class AttemptFailed < Msf::Auxiliary::Failed +end # # Initializes an instance of a recon auxiliary module @@ -119,7 +122,7 @@ def run if datastore['CHOST'] @scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable" end - rescue Msf::Auxiliary::Failed => e + rescue Msf::Auxiliary::Scanner::AttemptFailed => e nmod.vprint_error("#{e}") rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error, ::EOFError rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError @@ -204,7 +207,7 @@ def run if datastore['CHOST'] @scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable" end - rescue Msf::Auxiliary::Failed => e + rescue Msf::Auxiliary::Scanner::AttemptFailed => e print_error("#{e}") rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError @@ -335,6 +338,16 @@ def add_delay_jitter(_delay, _jitter) end end +def fail_with(reason, msg = nil, abort: false) + if abort + # raising Failed will case the run to be aborted + raise Msf::Auxiliary::Failed, "#{reason.to_s}: #{msg}" + else + # raising AttemptFailed will cause the run_host / run_batch to be aborted + raise Msf::Auxiliary::Scanner::AttemptFailed, "#{reason.to_s}: #{msg}" + end +end + end end