Class: Msf::ExploitDriver
- Inherits:
-
Object
- Object
- Msf::ExploitDriver
- Defined in:
- lib/msf/core/exploit_driver.rb
Overview
This class drives the exploitation process from start to finish for a given exploit module instance. It’s responsible for payload generation, encoding, and padding as well as initialization handlers and finally launching the exploit.
Instance Attribute Summary collapse
-
#exploit ⇒ Object
:nodoc:.
-
#force_wait_for_session ⇒ Object
:nodoc:.
-
#job_id ⇒ Object
The identifier of the job this exploit is launched as, if it’s run as a job.
-
#keep_handler ⇒ Object
:nodoc:.
-
#payload ⇒ Object
:nodoc:.
-
#semaphore ⇒ Object
To synchronize threads cleaning up the exploit and the handler.
-
#session ⇒ Object
:nodoc:.
-
#use_job ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#compatible_payload?(payload) ⇒ Boolean
Checks to see if the supplied payload is compatible with the current exploit.
-
#initialize(framework) ⇒ ExploitDriver
constructor
Initializes the exploit driver using the supplied framework instance.
-
#job_cleanup_proc(ctx) ⇒ Object
protected
Clean up the exploit and the handler after the job completes.
-
#job_run_proc(ctx) ⇒ Object
protected
Job run proc, sets up the exploit and kicks it off.
-
#run ⇒ Object
Kicks off an exploitation attempt and performs the following four major operations:.
-
#target_idx ⇒ Object
This method returns the currently selected target index.
-
#target_idx=(target_idx) ⇒ Object
Specification of the exploit target index.
-
#validate ⇒ Object
Makes sure everything’s in tip-top condition prior to launching the exploit.
Constructor Details
#initialize(framework) ⇒ ExploitDriver
Initializes the exploit driver using the supplied framework instance.
18 19 20 21 22 23 24 25 26 |
# File 'lib/msf/core/exploit_driver.rb', line 18 def initialize(framework) self.payload = nil self.exploit = nil self.use_job = false self.job_id = nil self.force_wait_for_session = false self.keep_handler = false self.semaphore = Mutex.new end |
Instance Attribute Details
#exploit ⇒ Object
:nodoc:
191 192 193 |
# File 'lib/msf/core/exploit_driver.rb', line 191 def exploit @exploit end |
#force_wait_for_session ⇒ Object
:nodoc:
199 200 201 |
# File 'lib/msf/core/exploit_driver.rb', line 199 def force_wait_for_session @force_wait_for_session end |
#job_id ⇒ Object
The identifier of the job this exploit is launched as, if it’s run as a job.
198 199 200 |
# File 'lib/msf/core/exploit_driver.rb', line 198 def job_id @job_id end |
#keep_handler ⇒ Object
:nodoc:
201 202 203 |
# File 'lib/msf/core/exploit_driver.rb', line 201 def keep_handler @keep_handler end |
#payload ⇒ Object
:nodoc:
192 193 194 |
# File 'lib/msf/core/exploit_driver.rb', line 192 def payload @payload end |
#semaphore ⇒ Object
To synchronize threads cleaning up the exploit and the handler
204 205 206 |
# File 'lib/msf/core/exploit_driver.rb', line 204 def semaphore @semaphore end |
#session ⇒ Object
:nodoc:
200 201 202 |
# File 'lib/msf/core/exploit_driver.rb', line 200 def session @session end |
#use_job ⇒ Object
:nodoc:
193 194 195 |
# File 'lib/msf/core/exploit_driver.rb', line 193 def use_job @use_job end |
Instance Method Details
#compatible_payload?(payload) ⇒ Boolean
Checks to see if the supplied payload is compatible with the current exploit. Assumes that target_idx is valid.
54 55 56 |
# File 'lib/msf/core/exploit_driver.rb', line 54 def compatible_payload?(payload) !exploit.compatible_payloads.find { |refname, _| refname == payload.refname }.nil? end |
#job_cleanup_proc(ctx) ⇒ Object (protected)
Clean up the exploit and the handler after the job completes.
267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/msf/core/exploit_driver.rb', line 267 def job_cleanup_proc(ctx) exploit, payload = ctx # Ensure that, no matter what, clean up of the handler occurs semaphore.synchronize { payload.stop_handler } exploit.framework.events.on_module_complete(exploit) # Allow the exploit to cleanup after itself, that messy bugger. semaphore.synchronize { exploit.cleanup } end |
#job_run_proc(ctx) ⇒ Object (protected)
Job run proc, sets up the exploit and kicks it off.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/msf/core/exploit_driver.rb', line 211 def job_run_proc(ctx) begin exploit, payload = ctx # Default session wait time.. delay = payload.wfs_delay + exploit.wfs_delay delay = nil if exploit.passive? # Set the exploit up the bomb exploit.setup exploit.framework.events.on_module_run(exploit) # Launch the exploit exploit.exploit rescue ::Exception => e if [::RuntimeError, ::Interrupt].include?(e.class) # Wait for session, but don't wait long. delay = 0.01 end fail_reason = exploit.handle_exception(e) end # Start bind handlers after exploit completion payload.start_handler if exploit.handler_bind? # Wait the payload to acquire a session if this isn't a passive-style # exploit. return if not delay if (force_wait_for_session == true) or (exploit.passive? == false and exploit.handler_enabled?) begin self.session = payload.wait_for_session(delay) rescue ::Interrupt # Don't let interrupt pass upward end end return self.session if self.session if exploit.fail_reason == Msf::Exploit::Failure::None exploit.fail_reason = Msf::Exploit::Failure::PayloadFailed exploit.fail_detail = "No session created" exploit.report_failure end if fail_reason && fail_reason == Msf::Exploit::Failure::UserInterrupt raise ::Interrupt end end |
#run ⇒ Object
Kicks off an exploitation attempt and performs the following four major operations:
- Generates the payload
- Initializes & monitors the handler
- Launches the exploit
- Cleans up the handler
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/msf/core/exploit_driver.rb', line 124 def run # First thing's first -- validate the state. Make sure all requirement # parameters are set, including those that are derived from the # datastore. validate() # After validation has occurred, it's time to set some values on the # exploit instance and begin preparing the payload exploit.datastore['TARGET'] = target_idx # Default the session to nil self.session = nil # Explicitly clear the module's job_id in case it was set in a previous # run exploit.job_id = nil # If we are being instructed to run as a job then let's create that job # like a good person. if (use_job or exploit.passive?) # Since references to the exploit and payload will hang around for # awhile in the job, make sure we copy them so further changes to # the datastore don't alter settings in existing jobs e = exploit.replicant p = payload.replicant # Assign the correct exploit instance to the payload p.assoc_exploit = e # Generate the encoded version of the supplied payload for the # newly copied exploit module instance e.generate_payload(p) ctx = [ e, p ] e.job_id = e.framework.jobs.start_bg_job( "Exploit: #{e.refname}", ctx, Proc.new { |ctx_| job_run_proc(ctx_) }, Proc.new { |ctx_| job_cleanup_proc(ctx_) } ) self.job_id = e.job_id else # Generate the encoded version of the supplied payload on the # exploit module instance exploit.generate_payload(payload) # No need to copy since we aren't creating a job. We wait until # they're finished running to do anything else with them, so # nothing should be able to modify their datastore or other # settings until after they're done. ctx = [ exploit, payload ] begin job_run_proc(ctx) rescue ::Interrupt job_cleanup_proc(ctx) raise $! ensure # For multi exploit targets. # Keep the payload handler until last target or interrupt job_cleanup_proc(ctx) unless keep_handler end end return session end |
#target_idx ⇒ Object
This method returns the currently selected target index.
46 47 48 |
# File 'lib/msf/core/exploit_driver.rb', line 46 def target_idx @target_idx end |
#target_idx=(target_idx) ⇒ Object
Specification of the exploit target index.
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/msf/core/exploit_driver.rb', line 31 def target_idx=(target_idx) if (target_idx) # Make sure the target index is valid if (target_idx >= exploit.targets.length) raise Rex::ArgumentError, "Invalid target index.", caller end end # Set the active target @target_idx = target_idx end |
#validate ⇒ Object
Makes sure everything’s in tip-top condition prior to launching the exploit. For things that aren’t good to go, an exception is thrown.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/msf/core/exploit_driver.rb', line 68 def validate # First, validate that a target has been selected if (target_idx == nil) raise MissingTargetError, "A payload cannot be selected until a target is specified.", caller end # Next, validate that a payload has been selected if (payload == nil) raise MissingPayloadError, "A payload has not been selected.", caller end # Make sure the payload is compatible after all unless compatible_payload?(payload) raise IncompatiblePayloadError.new(payload.refname), "#{payload.refname} is not a compatible payload.", caller end unless exploit.respond_to?(:allow_no_cleanup) && exploit.allow_no_cleanup # Being able to cleanup requires a session to be created from a handler, and for that # session to be able to be able to clean up files can_cleanup = payload.handler_klass != Msf::Handler::None && payload&.session&.can_cleanup_files if exploit.needs_cleanup && !can_cleanup raise IncompatiblePayloadError.new(payload.refname), "#{payload.refname} cannot cleanup files created during exploit. To run anyway, set AllowNoCleanup to true" end if exploit.needs_cleanup && !exploit.handler_enabled? raise ValidationError.new('Cannot cleanup files created during exploit if payload handler is disabled. To run anyway, set AllowNoCleanup to true') end end # Associate the payload instance with the exploit payload.assoc_exploit = exploit # Finally, validate options on the exploit module to ensure that things # are ready to operate as they should. exploit..validate(exploit.datastore) # Validate the payload's options. The payload's datastore is # most likely shared against the exploit's datastore, but in case it # isn't. payload..validate(payload.datastore) return true end |