Class: Ronin::Exploits::CLI::Commands::Run Private

Inherits:
ExploitCommand show all
Includes:
CommandKit::Printing::Indent, Core::CLI::Logging, Core::CLI::Options::Param, Payloads::CLI::EncoderMethods, Payloads::CLI::PayloadMethods, Support::CLI::Printing
Defined in:
lib/ronin/exploits/cli/commands/run.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Runs an exploit.

Usage

ronin-exploits run [options] {NAME | -f FILE}

Options

-f, --file FILE                  The exploit file to load
-p, --param NAME=VALUE           Sets a param
-D, --dry-run                    Builds the exploit but does not launch it
-T  --test                       Runs only the exploit test
    --payload-file FILE          Load the payload from the given Ruby file
    --read-payload FILE          Reads the payload string from the file
    --payload-string STRING      Uses the raw payload string instead
-P, --payload NAME               The payload to load and use
    --payload-param NAME=VALUE   Sets a param in the payload
    --encoder-file FILE          Load the payload encoder from the Ruby file
-E, --encoder NAME               Loads the payload encoder by name
    --encoder-param ENCODER.NAME=VALUE
                                 Sets a param of the ENCODER
-t, --target INDEX               Selects the target by index
-A x86|x86-64|amd64|ia64|ppc|ppc64|arm|armbe|arm64|arm64be|mips|mipsle|mips64|mips64le,
    --target-arch                Selects the target with the matching arch
-O linux|macos|windows|freebsd|openbsd|netbsd,
    --target-os                  Selects the target with the matching OS
    --target-os-version VERSION  Selects the target with the matching OS version
-S, --target-software NAME       Selects the target with the matching software name
-V, --target-version VERSION     Selects the target with the matching software version
-L, --save-loot DIR              Saves any found loot to the DIR
-d, --debug                      Enables debugging messages
    --irb                        Open an interactive Ruby shell inside the exploit
-h, --help                       Print help information

Arguments

[NAME]                           The exploit name to load

Instance Attribute Summary collapse

Attributes inherited from ExploitCommand

#exploit, #exploit_class

Instance Method Summary collapse

Methods inherited from ExploitCommand

#load_exploit, #load_exploit_from, #validate_exploit

Methods included from ExploitMethods

#load_exploit, #load_exploit_from, #validate_exploit

Constructor Details

#initialize(**kwargs) ⇒ Run

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initializes the ronin-exploits run command.

Parameters:

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments.



256
257
258
259
260
261
262
263
# File 'lib/ronin/exploits/cli/commands/run.rb', line 256

def initialize(**kwargs)
  super(**kwargs)

  @encoders_to_load  = []
  @encoder_params    = Hash.new { |hash,key| hash[key] = {} }
  @payload_params    = {}
  @target_kwargs     = {}
end

Instance Attribute Details

#encoder_paramsHash{String => Hash{String => String}} (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The encoder params.

Returns:

  • (Hash{String => Hash{String => String}})


238
239
240
# File 'lib/ronin/exploits/cli/commands/run.rb', line 238

def encoder_params
  @encoder_params
end

#encoders_to_loadArray<(Symbol, String)> (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Thte encoder names and paths to load.

Returns:

  • (Array<(Symbol, String)>)


233
234
235
# File 'lib/ronin/exploits/cli/commands/run.rb', line 233

def encoders_to_load
  @encoders_to_load
end

#payload_paramsHash{String => String} (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The payload params.

Returns:

  • (Hash{String => String})


243
244
245
# File 'lib/ronin/exploits/cli/commands/run.rb', line 243

def payload_params
  @payload_params
end

#target_kwargsHash{Symbol => Object} (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The keyword arguments to select a target with.

Returns:

  • (Hash{Symbol => Object})


248
249
250
# File 'lib/ronin/exploits/cli/commands/run.rb', line 248

def target_kwargs
  @target_kwargs
end

Instance Method Details

#initialize_encodersObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initializes the payload encoders specified by --encoder or --encoder-file.



316
317
318
319
320
# File 'lib/ronin/exploits/cli/commands/run.rb', line 316

def initialize_encoders
  @encoders = @encoder_classes.map do |encoder_class|
    encoder_class.new(params: @encoder_params[encoder_class.id])
  end
end

#initialize_exploitObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initializes the exploit.



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'lib/ronin/exploits/cli/commands/run.rb', line 359

def initialize_exploit
  kwargs = {params: @params}

  if @exploit_class.include?(Mixins::HasPayload)
    kwargs[:payload] = @payload
  end

  if @exploit_class.include?(Mixins::HasTargets)
    kwargs[:target] = if options[:target]
                        options[:target]
                      elsif !@target_kwargs.empty?
                        @target_kwargs
                      end
  end

  super(**kwargs)
end

#initialize_payloadObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initializes the payload specified by --payload, --payload-file, --read-payload, or --payload-string.



338
339
340
341
342
343
344
345
346
347
# File 'lib/ronin/exploits/cli/commands/run.rb', line 338

def initialize_payload
  @payload = if @payload_class
               super(@payload_class, params:   @payload_params,
                                     encoders: @encoders)
             elsif options[:read_payload]
               File.binread(options[:read_payload])
             elsif options[:payload_string]
               options[:payload_string]
             end
end

#load_encodersObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Loads the payload encoder classes specified by --encoder or --encoder-file.



301
302
303
304
305
306
307
308
309
310
# File 'lib/ronin/exploits/cli/commands/run.rb', line 301

def load_encoders
  @encoder_classes = @encoders_to_load.map do |(type,value)|
    case type
    when :name then load_encoder(value)
    when :file then load_encoder_from(value)
    else
      raise(NotImplementedError,"invalid encoder type: #{type.inspect}")
    end
  end
end

#load_payloadObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Loads the payload class specified by --payload or --payload-file.



326
327
328
329
330
331
332
# File 'lib/ronin/exploits/cli/commands/run.rb', line 326

def load_payload
  @payload_class = if options[:payload]
                     super(options[:payload])
                   elsif options[:payload_file]
                     load_payload_from(options[:payload_file])
                   end
end

#perform_cleanupObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Performs the cleanup stage of the exploit.



478
479
480
481
482
483
484
485
486
487
# File 'lib/ronin/exploits/cli/commands/run.rb', line 478

def perform_cleanup
  @exploit.perform_cleanup
rescue ExploitError => error
  print_error "failed to cleanup exploit #{@exploit.class_id}: #{error.message}"
  exit(1)
rescue => error
  print_exception(error)
  print_error "an unhandled exception occurred while cleaning up the exploit #{@exploit.class_id}"
  exit(-1)
end

#post_exploitationObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Performs the post-exploitation stage.



424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
# File 'lib/ronin/exploits/cli/commands/run.rb', line 424

def post_exploitation
  if @exploit_class.include?(Mixins::HasPayload) &&
     @exploit.payload.kind_of?(Ronin::Payloads::Payload) &&
     @exploit.payload.kind_of?(Ronin::Payloads::Mixins::PostEx)
    unless @exploit.payload.session
      print_error "payload (#{@exploit.payload.class_id}) did not create a post-exploitation session"

      perform_cleanup
      exit(1)
    end

    @exploit.payload.session.system.interact
  elsif @exploit_class.include?(Mixins::Loot)
    print_loot
    save_loot if options[:save_loot]
  end
end

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Prints any loot collected by the exploit.



445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
# File 'lib/ronin/exploits/cli/commands/run.rb', line 445

def print_loot
  unless @exploit.loot.empty?
    log_info "Exploit found the following loot:"

    indent do
      @exploit.loot.each do |file|
        puts
        puts "#{file.path}:"
        puts

        indent do
          file.to_s.each_line do |line|
            puts line
          end
        end
        puts
      end
    end
  else
    log_error "Exploit did not find any loot :("
  end
end

#run(name = nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Runs the ronin-exploits run command.

Parameters:

  • name (String, nil) (defaults to: nil)

    The optional exploit name to load.



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/ronin/exploits/cli/commands/run.rb', line 271

def run(name=nil)
  super(name)

  load_encoders
  load_payload
  initialize_encoders
  initialize_payload
  validate_payload
  initialize_exploit
  validate_exploit

  if options[:test]
    run_test
  else
    run_exploit

    if options[:irb]
      start_shell
    else
      post_exploitation
    end

    perform_cleanup
  end
end

#run_exploitObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Runs the exploit.



380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/ronin/exploits/cli/commands/run.rb', line 380

def run_exploit
  log_info "Running exploit #{@exploit.class_id} ..."

  begin
    @exploit.exploit(dry_run: options[:dry_run])
  rescue ExploitError => error
    print_error "failed to run exploit #{@exploit.class_id}: #{error.message}"
    exit(1)
  rescue => error
    print_exception(error)
    print_error "an unhandled exception occurred while running the exploit #{@exploit.class_id}"
    exit(-1)
  end
end

#run_testObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Run the exploit's test method, and print the result.



398
399
400
401
402
403
404
405
406
407
408
409
# File 'lib/ronin/exploits/cli/commands/run.rb', line 398

def run_test
  case (result = @exploit.perform_test)
  when TestResult::Vulnerable
    print_positive "Vulnerable: #{result}"
  when TestResult::NotVulnerable
    print_negative "NotVulnerable: #{result}"
  when TestResult::Unknown
    print_warning "Unknown: #{result}"
  else
    print_error "Unexpected result: #{result.inspect}"
  end
end

#save_lootObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Saves the collected loot to the --save-loot directory.



471
472
473
# File 'lib/ronin/exploits/cli/commands/run.rb', line 471

def save_loot
  @exploit.loot.save(options.fetch(:save_loot))
end

#start_shellObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Starts an interactive ruby shell within the exploit object.



414
415
416
417
418
419
# File 'lib/ronin/exploits/cli/commands/run.rb', line 414

def start_shell
  log_info "Exploit #{@exploit.class_id} launched!"
  log_info "Starting interactive Ruby shell ..."

  RubyShell.start(name: @exploit_class.name, context: @exploit)
end

#validate_payloadObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Validates the payload.



352
353
354
# File 'lib/ronin/exploits/cli/commands/run.rb', line 352

def validate_payload
  super(@payload) if @payload
end