Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#6100 : --pad-nops option for msfvenom #10872

Merged
merged 5 commits into from Nov 21, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 27 additions & 4 deletions lib/msf/core/payload_generator.rb
Expand Up @@ -9,7 +9,10 @@ class PayloadGeneratorError < StandardError
class EncoderSpaceViolation < PayloadGeneratorError
end

class PayloadSpaceViolation < PayloadGeneratorError
class PadSizeViolation < PayloadGeneratorError
end

class PayloadSpaceViolation < PayloadGeneratorError
end

class IncompatibleArch < PayloadGeneratorError
Expand Down Expand Up @@ -59,6 +62,9 @@ class PayloadGenerator
# @!attribute nops
# @return [Integer] The size in bytes of NOP sled to prepend the payload with
attr_accessor :nops
# @!attribute padsize
# @return [Integer] The size in bytes of final payload to achieve by filling with NOP sled
attr_accessor :padsize
# @!attribute payload
# @return [String] The refname of the payload to generate
attr_accessor :payload
Expand Down Expand Up @@ -124,6 +130,7 @@ def initialize(opts={})
@iterations = opts.fetch(:iterations, 1)
@keep = opts.fetch(:keep, false)
@nops = opts.fetch(:nops, 0)
@padsize = opts.fetch(:padsize, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor whitespace issue here, I can fix that. Just be sure to use spaces instead of tabs in the future

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, sorry about this. I'll be more careful in the future.

@payload = opts.fetch(:payload, '')
@platform = opts.fetch(:platform, '')
@space = opts.fetch(:space, 1.gigabyte)
Expand Down Expand Up @@ -364,6 +371,9 @@ def generate_payload
encoded_payload = encode_payload(raw_payload)
end
encoded_payload = prepend_nops(encoded_payload)
if(@padsize > 0)
Copy link
Member

@busterb busterb Nov 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same thing here. surprised msftidy didn't complain.

encoded_payload = pad_size(encoded_payload, padsize - encoded_payload.length)
end
cli_print "Payload size: #{encoded_payload.length} bytes"
gen_payload = format_payload(encoded_payload)
end
Expand All @@ -381,7 +391,6 @@ def generate_payload
end
end


# This method generates the raw form of the payload as generated by the payload module itself.
# @raise [Msf::IncompatiblePlatform] if no platform was selected for a stdin payload
# @raise [Msf::IncompatibleArch] if no arch was selected for a stdin payload
Expand Down Expand Up @@ -477,15 +486,29 @@ def prepend_nops(shellcode)
nop = framework.nops.create(name)
raw = nop.generate_sled(nops, {'BadChars' => badchars, 'SaveRegisters' => [ 'esp', 'ebp', 'esi', 'edi' ] })
if raw
cli_print "Successfully added NOP sled from #{name}"
cli_print "Successfully added NOP sled of size #{raw.length} from #{name}"
return raw + shellcode
end
end
end
else
shellcode
end
end

# This method prepends a NOP sled onto the encoded payload with a size
# based on a subtraction of the payload size from the padsize value
# given to the generator.
# @param shellcode [String] The shellcode to prepend the NOPs to
# @param sub_nops [Integer] Value derived from a subtraction of the encoded payload length from the padsize.
def pad_size(shellcode, sub_nops)
if @padsize < shellcode.length
raise PadSizeViolation, "pad-size value #{@padsize} is less than payload size."
else
@nops = sub_nops
end
return prepend_nops(shellcode)
end

# This method runs a specified encoder, for a number of defined iterations against the shellcode.
# @param encoder_module [Msf::Encoder] The Encoder to run against the shellcode
# @param shellcode [String] The shellcode to be encoded
Expand Down
9 changes: 9 additions & 0 deletions msfvenom
Expand Up @@ -134,6 +134,10 @@ def parse_args(args)
opts[:nops] = n.to_i
end

opt.on('--pad-size <length>', Integer, 'Given [length] total payload size, automatically prepend a nopsled of size ([length] minus payload buffer size)') do |p|
opts[:padsize] = p.to_i
end

opt.on('-s', '--space <length>', Integer, 'The maximum size of the resulting payload') do |s|
opts[:space] = s
end
Expand Down Expand Up @@ -209,6 +213,10 @@ def parse_args(args)
end
end

if !opts[:padsize].nil? && !opts[:nops].nil? # --pad-size does the subtraction for the user already
raise UsageError, "Option --pad-size and -n cannot be used together\n"
end

opts[:datastore] = datastore

opts
Expand Down Expand Up @@ -371,6 +379,7 @@ end

begin
generator_opts = parse_args(ARGV)

rescue HelpError => e
$stderr.puts e.message
exit(1)
Expand Down