Skip to content

Commit 71eab7a

Browse files
author
HD Moore
committed
Implements msfvenom --smallest, still some blockers
1 parent a82168d commit 71eab7a

File tree

2 files changed

+43
-15
lines changed

2 files changed

+43
-15
lines changed

lib/msf/core/payload_generator.rb

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class PayloadGenerator
6161
# @!attribute platform
6262
# @return [String] The platform to build the payload for
6363
attr_accessor :platform
64+
# @!attribute smallest
65+
# @return [Boolean] Whether or not to find the smallest possible output
66+
attr_accessor :smallest
6467
# @!attribute space
6568
# @return [Fixnum] The maximum size in bytes of the payload
6669
attr_accessor :space
@@ -95,6 +98,7 @@ class PayloadGenerator
9598
# @option opts [Hash] :datastore (see #datastore)
9699
# @option opts [Msf::Framework] :framework (see #framework)
97100
# @option opts [Boolean] :cli (see #cli)
101+
# @option opts [Boolean] :smallest (see #smallest)
98102
# @raise [KeyError] if framework is not provided in the options hash
99103
def initialize(opts={})
100104
@add_code = opts.fetch(:add_code, '')
@@ -113,12 +117,20 @@ def initialize(opts={})
113117
@stdin = opts.fetch(:stdin, nil)
114118
@template = opts.fetch(:template, '')
115119
@var_name = opts.fetch(:var_name, 'buf')
120+
@smallest = opts.fetch(:smallest, false)
116121
@encoder_space = opts.fetch(:encoder_space, @space)
117122

118123
@framework = opts.fetch(:framework)
119124

120125
raise ArgumentError, "Invalid Payload Selected" unless payload_is_valid?
121126
raise ArgumentError, "Invalid Format Selected" unless format_is_valid?
127+
128+
# In smallest mode, override the payload @space & @encoder_space settings
129+
if @smallest
130+
@space = 0
131+
@encoder_space = 1.gigabyte
132+
end
133+
122134
end
123135

124136
# This method takes the shellcode generated so far and adds shellcode from
@@ -199,24 +211,36 @@ def encode_payload(shellcode)
199211
encoder_list = get_encoders
200212
if encoder_list.empty?
201213
cli_print "No encoder or badchars specified, outputting raw payload"
202-
shellcode
203-
else
204-
cli_print "Found #{encoder_list.count} compatible encoders"
205-
encoder_list.each do |encoder_mod|
206-
cli_print "Attempting to encode payload with #{iterations} iterations of #{encoder_mod.refname}"
207-
begin
208-
encoder_mod.available_space = @encoder_space
209-
return run_encoder(encoder_mod, shellcode.dup)
210-
rescue ::Msf::EncoderSpaceViolation => e
211-
cli_print "#{encoder_mod.refname} failed with #{e.message}"
212-
next
213-
rescue ::Msf::EncodingError => e
214-
cli_print "#{encoder_mod.refname} failed with #{e.message}"
215-
next
216-
end
214+
return shellcode
215+
end
216+
217+
results = {}
218+
219+
cli_print "Found #{encoder_list.count} compatible encoders"
220+
encoder_list.each do |encoder_mod|
221+
cli_print "Attempting to encode payload with #{iterations} iterations of #{encoder_mod.refname}"
222+
begin
223+
encoder_mod.available_space = @encoder_space unless @smallest
224+
results[encoder_mod.refname] = run_encoder(encoder_mod, shellcode.dup)
225+
break unless @smallest
226+
rescue ::Msf::EncoderSpaceViolation => e
227+
cli_print "#{encoder_mod.refname} failed with #{e.message}"
228+
next
229+
rescue ::Msf::EncodingError => e
230+
cli_print "#{encoder_mod.refname} failed with #{e.message}"
231+
next
217232
end
233+
end
234+
235+
if results.keys.length == 0
218236
raise ::Msf::EncodingError, "No Encoder Succeeded"
219237
end
238+
239+
# Return the shortest encoding of the payload
240+
chosen_encoder = results.keys.sort{|a,b| results[a].length <=> results[b].length}.first
241+
cli_print "#{chosen_encoder} chosen with final size #{results[chosen_encoder].length}"
242+
243+
results[chosen_encoder]
220244
end
221245

222246
# This returns a hash for the exe format generation of payloads

msfvenom

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ require 'msf/core/payload_generator'
133133
opts[:var_name] = x
134134
end
135135

136+
opt.on('--smallest', 'Generate the smallest possible payload') do
137+
opts[:smallest] = true
138+
end
139+
136140
opt.on_tail('-h', '--help', 'Show this message') do
137141
raise UsageError, "#{opt}"
138142
end

0 commit comments

Comments
 (0)