diff --git a/documentation/variables.txt b/documentation/variables.txt new file mode 100644 index 0000000000..281b9e9285 --- /dev/null +++ b/documentation/variables.txt @@ -0,0 +1,4 @@ +framework global: + +DisableAutoSubscribe + Disables the auto-subscription of modules to event provider interfaces. diff --git a/lib/msf/core/event_dispatcher.rb b/lib/msf/core/event_dispatcher.rb index 77ecb18f7c..e96846ae0b 100644 --- a/lib/msf/core/event_dispatcher.rb +++ b/lib/msf/core/event_dispatcher.rb @@ -197,10 +197,10 @@ class EventDispatcher # Called when an exploit succeeds. This notifies the registered exploit # event subscribers. # - def on_exploit_success(exploit) + def on_exploit_success(exploit, session = nil) subscribers_rwlock.synchronize_read { exploit_event_subscribers.each { |subscriber| - subscriber.on_exploit_success(exploit) + subscriber.on_exploit_success(exploit, session) } } end diff --git a/lib/msf/core/exploit.rb b/lib/msf/core/exploit.rb index 09cfea460e..fb24192236 100644 --- a/lib/msf/core/exploit.rb +++ b/lib/msf/core/exploit.rb @@ -4,24 +4,25 @@ module Msf ### # -# ExploitEvents -# ------------- +# ExploitEvent +# ------------ # # Event notifications that affect exploits. # ### -module ExploitEvents +module ExploitEvent # # This method is called whenever an exploit succeeds. # - def on_exploit_success(exploit) + def self.on_exploit_success(exploit, session) end # - # This method is called whenever an exploit fails. + # Calls the class method. # - def on_exploit_failure(exploit, reason) + def on_exploit_success(exploit, session) + self.class.on_exploit_success(exploit, session) end end diff --git a/lib/msf/core/exploit_driver.rb b/lib/msf/core/exploit_driver.rb index ea8d2f4ef0..8bf2272327 100644 --- a/lib/msf/core/exploit_driver.rb +++ b/lib/msf/core/exploit_driver.rb @@ -136,6 +136,9 @@ class ExploitDriver session.set_via( 'Exploit' => exploit.refname, 'Payload' => payload.refname) + + # Call the exploit success handler + framework.events.on_exploit_success(exploit, session) end return session diff --git a/lib/msf/core/module_manager.rb b/lib/msf/core/module_manager.rb index f61a513de2..c11fb165d8 100644 --- a/lib/msf/core/module_manager.rb +++ b/lib/msf/core/module_manager.rb @@ -172,6 +172,10 @@ protected self[name] = dup end + # Automatically subscribe a wrapper around this module to the necessary + # event providers based on whatever events it wishes to receive. + auto_subscribe_module(dup) + # Notify the framework that a module was loaded framework.events.on_module_load(name, dup) @@ -187,6 +191,50 @@ protected mod_ranked = nil end + # + # This method automatically subscribes a module to whatever event providers + # it wishes to monitor. This can be used to allow modules to automatically + # execute or perform other tasks when certain events occur. For instance, + # when a new host is detected, other recon modules may wish to run such + # that they can collect more information about the host that was detected. + # + def auto_subscribe_module(mod) + # If auto-subscribe has been disabled + if (framework.datastore['DisableAutoSubscribe'] and + framework.datastore['DisableAutoSubscribe'] =~ /^(y|1|t)/) + return + end + + # If auto-subscription is enabled (which it is by default), figure out + # if it subscribes to any particular interfaces. + + # + # Recon event subscriber check + # + [ + Msf::ReconEvent::HostSubscriber, + Msf::ReconEvent::ServiceSubscriber, + ].each { |iface| + if (mod.include?(iface)) + framework.events.add_recon_subscriber(mod) + end + } + + # + # Exploit event subscriber check + # + if (mod.include?(ExploitEvent)) + framework.events.add_exploit_subscriber(mod) + end + + # + # Session event subscriber check + # + if (mod.include?(SessionEvent)) + framework.events.add_session_subscriber(mod) + end + end + attr_writer :module_type attr_accessor :mod_arch_hash, :mod_platform_hash attr_accessor :mod_sorted, :mod_ranked @@ -206,7 +254,6 @@ end # # TODO: # -# - add reload support # - add unload support # ### diff --git a/lib/msf/core/recon.rb b/lib/msf/core/recon.rb index 9fa2a4fe17..765dbe7c9e 100644 --- a/lib/msf/core/recon.rb +++ b/lib/msf/core/recon.rb @@ -34,7 +34,7 @@ module ReconEvent # This routine is called when a change is made to a host, such as it being # added, modified, or removed. # - def on_host_changed(context, host, change_type) + def self.on_host_changed(context, host, change_type) case change_type when EntityChangeType::Add on_new_host(context, host) @@ -45,30 +45,65 @@ module ReconEvent end end + # + # Calls the class method. + # + def on_host_changed(context, host, change_type) + self.class.on_host_changed(context, host, change_type) + end + # # This routine is called whenever a new host is found. # + def self.on_new_host(context, host) + end + + # + # Calls the class methods. + # def on_new_host(context, host) + self.class.on_new_host(context, host) end # # This routine is called whenever a change is made to an existing # host. # + def self.on_updated_host(context, host) + end + + # + # Calls the class method. + # def on_updated_host(context, host) + self.class.on_updated_host(context, host) end # # Called when a host is considered to be dead after having # previously been valid. # + def self.on_dead_host(context, host) + end + + # + # Calls the class method. + # def on_dead_host(context, host) + self.class.on_dead_host(context, host) end # # This routine is called whenever a host attribute is found. # + def self.on_new_host_attribute(context, host, attribute) + end + + # + # Calls the class method. + # def on_new_host_attribute(context, host, attribute) + self.class.on_new_host_attribute(context, host, attribute) end end @@ -88,7 +123,7 @@ module ReconEvent # This routine is called when a change is made to a service, such as it being # added, modified, or removed. # - def on_service_changed(context, host, service, change_type) + def self.on_service_changed(context, host, service, change_type) case change_type when EntityChangeType::Add on_new_service(context, host, service) @@ -99,30 +134,65 @@ module ReconEvent end end + # + # Calls the class method. + # + def on_service_changed(context, host, service, change_type) + self.class.on_service_changed(context, host, service, change_type) + end + # # This routine is called whenever a new service is found. # + def self.on_new_service(context, host, service) + end + + # + # Calls the class method. + # def on_new_service(context, host, service) + self.class.on_new_service(context, host, service) end # # This routine is called whenever a change is made to an existing # service. # + def self.on_updated_service(context, host, service) + end + + # + # Calls the class method. + # def on_updated_service(context, host, service) + self.class.on_updated_service(context, host, service) end # # Called when a service is considered to be dead after having # previously been valid. # + def self.on_dead_service(context, host, service) + end + + # + # Calls the class method. + # def on_dead_service(context, host, service) + self.class.on_dead_service(context, host, service) end # # This routine is called whenever a service attribute is found. # - def on_new_service_attribute(context, host, service, attribute) + def self.on_new_service_attribute(context, host, service, attribute) + end + + # + # Calls the class method. + # + def on_new_service_attribute(context, host, service) + self.class.on_new_service_attribute(context, host, service) end end diff --git a/lib/msf/core/session.rb b/lib/msf/core/session.rb index d272a3887e..6e3f3de939 100644 --- a/lib/msf/core/session.rb +++ b/lib/msf/core/session.rb @@ -4,21 +4,30 @@ module Msf ### # -# SessionEvents -# ------------- +# SessionEvent +# ------------ # # Event notifications that affect sessions. # ### -module SessionEvents +module SessionEvent # Called when a session is opened def on_session_open(session) end + + # Called when a session is opened + def self.on_session_open(session) + end # Called when a session is closed def on_session_close(session) end + + # Called when a session is closed + def self.on_session_close(session) + end + end diff --git a/lib/msf/core/session_manager.rb.ut.rb b/lib/msf/core/session_manager.rb.ut.rb index 317b6e6cb8..a7d1fd67bd 100644 --- a/lib/msf/core/session_manager.rb.ut.rb +++ b/lib/msf/core/session_manager.rb.ut.rb @@ -9,8 +9,8 @@ module Msf class SessionManager::UnitTest < Test::Unit::TestCase -class UtSessionEvents - include SessionEvents +class UtSessionEvent + include SessionEvent def on_session_open(session) self.open_session = session @@ -54,7 +54,7 @@ end def test_notify framework = Framework.new manager = SessionManager.new(framework) - handler = UtSessionEvents.new + handler = UtSessionEvent.new session = Class.new session.extend(Session) diff --git a/lib/msf/ui/console/framework_event_manager.rb b/lib/msf/ui/console/framework_event_manager.rb index 0ac6c19036..09ea56923d 100644 --- a/lib/msf/ui/console/framework_event_manager.rb +++ b/lib/msf/ui/console/framework_event_manager.rb @@ -12,7 +12,7 @@ module Console ### module FrameworkEventManager - include Msf::SessionEvents + include Msf::SessionEvent # # Subscribes to the framework as a subscriber of various events.