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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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

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.

[View source]

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

def post_exploitation
  if @exploit.kind_of?(Mixins::HasPayload) &&
     @exploit.payload.kind_of?(Ronin::Payloads::Payload) &&
     @exploit.payload.kind_of?(Ronin::Payloads::Mixins::PostEx)
    session = @exploit.payload.session

    unless session
      print_error "payload (#{@exploit.payload.class_id}) did not create a post-exploitation session"

      perform_cleanup
      exit(1)
    end

    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.

[View source]

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

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

473
474
475
# File 'lib/ronin/exploits/cli/commands/run.rb', line 473

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.

[View source]

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.

[View source]

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

def validate_payload
  super(@payload) if @payload
end