Class: Ronin::Exploits::Exploit

Inherits:
Object
  • Object
show all
Includes:
Cacheable, Model::HasDescription, Model::HasLicense, Model::HasName, Model::HasVersion, Parameters, Controls::Behaviors, Verifiers, Payloads::HasPayload, UI::Output::Helpers
Defined in:
lib/ronin/exploits/exploit.rb

Direct Known Subclasses

Local, Remote

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Verifiers

#verify_arch!, #verify_os!, #verify_product!, #verify_restricted!, #verify_target!

Methods included from Controls::Behaviors

#control, #control_helper, #control_model, #load_original!

Methods included from Payloads::HasPayload

#payload, #use_payload!, #use_payload_class, #use_payload_from!

Constructor Details

#initialize(attributes = {}) { ... } ⇒ Exploit

Creates a new Exploit object.

Parameters:

  • attributes (Hash) (defaults to: {})

    Additional attributes used to initialize the exploit’s model attributes and parameters.

Yields:

  • If a block is given, it will be evaluated in the newly created Exploit object.



129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/ronin/exploits/exploit.rb', line 129

def initialize(attributes={},&block)
  super(attributes)

  initialize_params(attributes)

  @target = nil
  @built = false
  @deployed = false

  @restricted_chars = Chars::CharSet.new
  @encoders = []

  instance_eval(&block) if block
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *arguments, &block) ⇒ Object (protected)

Relays method calls to the payload, if the payload is a kind of Ronin::Payloads::Payload.

Since:

  • 0.3.0



781
782
783
784
785
786
787
# File 'lib/ronin/exploits/exploit.rb', line 781

def method_missing(name,*arguments,&block)
  if @payload.kind_of?(Ronin::Payloads::Payload)
    return @payload.send(name,*arguments,&block)
  end

  super(name,*arguments,&block)
end

Instance Attribute Details

#encoded_payloadObject (readonly)

The encoded payload



116
117
118
# File 'lib/ronin/exploits/exploit.rb', line 116

def encoded_payload
  @encoded_payload
end

#encodersObject (readonly)

Encoders to run on the payload



110
111
112
# File 'lib/ronin/exploits/exploit.rb', line 110

def encoders
  @encoders
end

#raw_payloadObject

The raw unencoded payload



113
114
115
# File 'lib/ronin/exploits/exploit.rb', line 113

def raw_payload
  @raw_payload
end

#restricted_charsObject (readonly)

Characters to restrict



107
108
109
# File 'lib/ronin/exploits/exploit.rb', line 107

def restricted_chars
  @restricted_chars
end

#targetTarget

Returns The current target to use in exploitation.

Returns:

  • (Target)

    The current target to use in exploitation.



395
396
397
# File 'lib/ronin/exploits/exploit.rb', line 395

def target
  @target ||= self.targets.first
end

Class Method Details

.targeting_arch(name) ⇒ Array<Exploit>

Finds all exploits which target a given architecture.

Parameters:

  • name (String, Symbol)

    The name of the architecture.

Returns:

  • (Array<Exploit>)

    The exploits targeting the architecture.



179
180
181
# File 'lib/ronin/exploits/exploit.rb', line 179

def self.targeting_arch(name)
  all(self.targets.arch.name => name.to_s)
end

.targeting_os(name) ⇒ Array<Exploit>

Finds all exploits which target a given OS.

Parameters:

  • name (String, Symbol)

    The name of the OS.

Returns:

  • (Array<Exploit>)

    The exploits targeting the OS.



192
193
194
# File 'lib/ronin/exploits/exploit.rb', line 192

def self.targeting_os(name)
  all(self.targets.os.name => name.to_s)
end

.targeting_product(name) ⇒ Array<Exploit>

Finds all exploits which target a given product.

Parameters:

  • name (String, Symbol)

    The name of the product.

Returns:

  • (Array<Exploit>)

    The exploits targeting the product.



205
206
207
# File 'lib/ronin/exploits/exploit.rb', line 205

def self.targeting_product(name)
  all(self.targets.product.name => "%#{name}%")
end

.written_by(name) ⇒ Array<Exploit>

Finds all exploits written by a specific author.

Parameters:

  • name (String)

    The name of the author.

Returns:

  • (Array<Exploit>)

    The exploits written by the author.



153
154
155
# File 'lib/ronin/exploits/exploit.rb', line 153

def self.written_by(name)
  all(self.authors.name.like => "%#{name}%")
end

.written_for(name) ⇒ Array<Exploit>

Finds all exploits written for a specific organization.

Parameters:

  • name (String)

    The name of the organization.

Returns:

  • (Array<Exploit>)

    The exploits written for the organization.



166
167
168
# File 'lib/ronin/exploits/exploit.rb', line 166

def self.written_for(name)
  all(self.authors.organization.like => "%#{name}%")
end

Instance Method Details

#archArch

Returns The current targeted architecture.

Returns:

  • (Arch)

    The current targeted architecture.



403
404
405
# File 'lib/ronin/exploits/exploit.rb', line 403

def arch
  target.arch if target
end

#author(attributes = {}) {|author| ... } ⇒ Object

Adds a new author to the exploit.

Examples:

author :name => 'Anonymous',
       :email => '[email protected]',
       :organization => 'Anonymous LLC'

Parameters:

  • attributes (Hash) (defaults to: {})

    Additional attributes to create the ExploitAuthor object with.

Yields:

  • (author)

    If a block is given, it will be passed the newly created author object.

Yield Parameters:

  • author (ExploitAuthor)

    The author object tied to the exploit.



227
228
229
# File 'lib/ronin/exploits/exploit.rb', line 227

def author(attributes={},&block)
  self.authors << ExploitAuthor.new(attributes,&block)
end

#behaviorsArray<Symbol>

Lists the behaviors controlled by the exploit and the payload, if one is being used.

Returns:

  • (Array<Symbol>)

    The combined behaviors controlled by the exploit.



323
324
325
326
327
328
329
330
331
# File 'lib/ronin/exploits/exploit.rb', line 323

def behaviors
  total_behaviors = super

  if @payload
    total_behaviors = (total_behaviors + @payload.behaviors).uniq
  end

  return total_behaviors
end

#build!(options = {}, &block) ⇒ Object

Builds the exploit and checks for restricted characters or patterns.

Parameters:

  • options (Hash) (defaults to: {})

    Additional options to also use as parameters.



533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
# File 'lib/ronin/exploits/exploit.rb', line 533

def build!(options={},&block)
  self.params = options

  print_debug "Exploit parameters: #{self.params.inspect}"

  @built = false

  build_payload!(options)
  encode_payload!

  print_info "Building exploit ..."

  build
  
  print_info "Exploit built!"

  @built = true

  if block
    if block.arity == 1
      block.call(self)
    else
      block.call()
    end
  end

  return self
end

#build_payload!(options = {}) ⇒ String

Builds the current payload, saving the result to the @raw_payload instance variable.

Parameters:

  • options (Hash) (defaults to: {})

    Additional options to build the paylod with.

Returns:

  • (String)

    The built payload.

See Also:

  • Payload#build!

Since:

  • 0.3.0



481
482
483
484
485
486
487
488
489
490
491
492
# File 'lib/ronin/exploits/exploit.rb', line 481

def build_payload!(options={})
  if @payload
    @raw_payload = ''

    @payload.build!(options)
    @raw_payload = @payload.raw_payload
  else
    @raw_payload ||= ''
  end

  return @raw_payload
end

#built?Boolean

Returns Specifies whether the exploit is built.

Returns:

  • (Boolean)

    Specifies whether the exploit is built.



523
524
525
# File 'lib/ronin/exploits/exploit.rb', line 523

def built?
  @built == true
end

#deploy! {|exploit| ... } ⇒ Exploit

Verifies then deploys the exploit. If a payload has been set, the payload will also be deployed.

Yields:

  • (exploit)

    If a block is given, it will be passed the deployed exploit.

Yield Parameters:

  • exploit (Exploit)

    The deployed exploit.

Returns:

  • (Exploit)

    The deployed exploit.

Raises:

  • (ExploitNotBuilt)

    The exploit has not been built, and cannot be deployed.



609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
# File 'lib/ronin/exploits/exploit.rb', line 609

def deploy!(&block)
  verify!

  print_info "Deploying exploit ..."
  @deployed = false

  deploy()

  print_info "Exploit deployed!"
  @deployed = true

  @payload.deploy!() if @payload

  if block
    if block.arity == 1
      block.call(self)
    else
      block.call()
    end
  end

  return self
end

#deployed?Boolean

Returns Specifies whether the exploit has previously been deployed.

Returns:

  • (Boolean)

    Specifies whether the exploit has previously been deployed.



589
590
591
# File 'lib/ronin/exploits/exploit.rb', line 589

def deployed?
  @deployed == true
end

#encode_payload(encoder = nil) {|payload| ... } ⇒ Array

Adds a new encoder to the list of encoders to use for encoding the payload.

Examples:

exploit.encode_payload(some_encoder)
exploit.encode_payload do |payload|
  # ...
end

Parameters:

  • encoder (#encode) (defaults to: nil)

    The payload encoder object to use. Must provide an encode method.

Yields:

  • (payload)

    If a block is given, and an encoder object is not, the block will be used to encode the payload.

Yield Parameters:

  • payload (String)

    The payload to be encoded.

Returns:

  • (Array)

    The new list of encoders to use to encode the payload.

Raises:

  • (RuntimeError)

    The payload encoder object does not provide an encode method.

  • (ArgumentError)

    Either a payload encoder object or a block can be given.



302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/ronin/exploits/exploit.rb', line 302

def encode_payload(encoder=nil,&block)
  if encoder
    unless encoder.respond_to?(:encode)
      raise(RuntimeError,"The payload encoder must provide an encode method",caller)
    end

    @encoders << encoder
  elsif (encoder.nil? && block)
    @encoders << block
  else
    raise(ArgumentError,"either a payload encoder or a block can be given",caller)
  end
end

#encode_payload!String

Encodes the current payload and saves the result in the @encoded_payload instance variable.

Returns:

  • (String)

    The encoded payload.



501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# File 'lib/ronin/exploits/exploit.rb', line 501

def encode_payload!
  @encoded_payload = @raw_payload.to_s

  @encoders.each do |encoder|
    print_debug "Encoding payload: #{@encoded_payload.dump}"

    new_payload = if encoder.respond_to?(:encode)
                    encoder.encode(@encoded_payload)
                  elsif encoder.respond_to?(:call)
                    encoder.call(@encoded_payload)
                  end

    @encoded_payload = (new_payload || @encoded_payload).to_s
  end

  return @encoded_payload
end

#exploit!(options = {}) {|exploit| ... } ⇒ Exploit

Builds, verified and then deploys the exploit.

Parameters:

  • options (Hash) (defaults to: {})

    Additional options to build the exploit with.

Options Hash (options):

  • :dry_run (Boolean) — default: false

    Specifies whether to do a dry-run of the exploit, where the exploit will be built, verified but not deployed.

Yield Parameters:

  • exploit (Exploit)

    The deployed exploit.

Returns:

  • (Exploit)

    The deployed exploit.

  • (Exploit)

    The deployed exploit.

Since:

  • 0.3.0



654
655
656
657
658
659
660
661
662
# File 'lib/ronin/exploits/exploit.rb', line 654

def exploit!(options={},&block)
  build!(options)

  unless options[:dry_run]
    deploy!(&block)
  end

  return self
end

#inspectString

Inspects the contents of the exploit.

Returns:

  • (String)

    The inspected exploit.



686
687
688
689
690
691
# File 'lib/ronin/exploits/exploit.rb', line 686

def inspect
  str = "#{self.class}: #{self}"
  str << " #{self.params.inspect}" unless self.params.empty?

  return "#<#{str}>"
end

#osOS

Returns The current targeted OS.

Returns:

  • (OS)

    The current targeted OS.



411
412
413
# File 'lib/ronin/exploits/exploit.rb', line 411

def os
  target.os if target
end

#payload=(new_payload) ⇒ Payload

Associates a payload with the exploit, and the exploit with the payload.

Parameters:

  • new_payload (Payload)

    The new payload to associate with the exploit.

Returns:

  • (Payload)

    The new payload.

Since:

  • 0.3.0



435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
# File 'lib/ronin/exploits/exploit.rb', line 435

def payload=(new_payload)
  if (@payload && new_payload.nil?)
    @payload.exploit = nil
  end

  super(new_payload)

  if @payload
    print_info "Using payload: #{new_payload}"

    @payload.exploit = self
  end

  return @payload
end

#productProduct

Returns The current targeted product.

Returns:

  • (Product)

    The current targeted product.



419
420
421
# File 'lib/ronin/exploits/exploit.rb', line 419

def product
  target.product if target
end

#restrict(*chars) ⇒ Array<String>

Adds new characters to the list of restricted characters.

Examples:

restrict 0x00, "\n"
# => #<Chars::CharSet: {"\0", "\n"}>

Parameters:

  • chars (Array<String>)

    The character to restrict.

Returns:

  • (Array<String>)

    The new list of restricted characters.



266
267
268
# File 'lib/ronin/exploits/exploit.rb', line 266

def restrict(*chars)
  @restricted_chars += chars
end

#targeted_archsArray<Arch>

Returns The targeted architectures.

Returns:

  • (Array<Arch>)

    The targeted architectures.



337
338
339
# File 'lib/ronin/exploits/exploit.rb', line 337

def targeted_archs
  self.targets.map { |target| target.arch }.compact
end

#targeted_osesArray<OS>

Returns The targeted OSes.

Returns:

  • (Array<OS>)

    The targeted OSes.



345
346
347
# File 'lib/ronin/exploits/exploit.rb', line 345

def targeted_oses
  self.targets.map { |target| target.os }.compact
end

#targeted_productsArray<Product>

Returns The targeted Products.

Returns:

  • (Array<Product>)

    The targeted Products.



353
354
355
# File 'lib/ronin/exploits/exploit.rb', line 353

def targeted_products
  self.targets.map { |target| target.product }.compact
end

#targeting(attributes = {}) {|target| ... } ⇒ Object

Adds a new target to the exploit.

Examples:

targeting do |target|
  target.arch :i686
  target.os :name => 'Linux'
end

Parameters:

  • attributes (Hash) (defaults to: {})

    Additional attributes to create the target with.

Yields:

  • (target)

    If a block is given, it will be passed the newly created target.

Yield Parameters:

  • target (Target)

    The newly created target.



249
250
251
# File 'lib/ronin/exploits/exploit.rb', line 249

def targeting(attributes={},&block)
  self.targets << Target.new(attributes,&block)
end

#to_sString

Converts the exploit to a String.

Returns:

  • (String)

    The name and version of the exploit.



670
671
672
673
674
675
676
677
678
# File 'lib/ronin/exploits/exploit.rb', line 670

def to_s
  if (self.name && self.version)
    "#{self.name} #{self.version}"
  elsif self.name
    self.name
  elsif self.version
    self.version
  end
end

#use_target!(index_or_query = 0) {|target| ... } ⇒ Object

Selects a target to use in exploitation.

Examples:

use_target!(2)
use_target!(Target.arch.name => 'i686')
use_target! { |target| target.arch == Arch.i686 }

Parameters:

  • index_or_query (Integer, Hash) (defaults to: 0)

    The index within #targets or a query to select the target.

Yields:

  • (target)

    If a block is given, it will be used to select the desired target from #targets.

Yield Parameters:

  • target (Target)

    The potential target to review.

Since:

  • 0.3.0



381
382
383
384
385
386
387
388
389
# File 'lib/ronin/exploits/exploit.rb', line 381

def use_target!(index_or_query=0,&block)
  @target = if block
              self.targets.find(&block)
            elsif index_or_query.kind_of?(Hash)
              self.targets.first(index_or_query)
            elsif index_or_query.kind_of?(Integer)
              self.targets[index_or_query]
            end
end

#verify!true

Verifies the exploit is built, properly configured, built and ready deployment.

Returns:

  • (true)

    The exploit is built and ready for deployment.

Raises:

  • (ExploitNotBuilt)

    The exploit has not been built, and cannot be deployed.



572
573
574
575
576
577
578
579
580
581
582
583
# File 'lib/ronin/exploits/exploit.rb', line 572

def verify!
  unless built?
    raise(ExploitNotBuilt,"cannot deploy an unbuilt exploit",caller)
  end

  print_info "Verifying exploit ..."

  verify

  print_info "Exploit verified!"
  return true
end