Add more supported formats to exe generation
- Already supported, just added calls to the the right methods in the .to_executable_fmt method: - Linux armle, mipsle, and mipsbe - Mac arm, ppc - makes the two (!?) copies of block_api for windows match more closely with the source used elsewhere. This is still needs to be refactored to get rid of the duplication. - Get rid of some of the logic in msfvenom duplicated from Util::EXEbug/bundler_fix
parent
0d78a04af3
commit
1466609c86
|
@ -137,7 +137,6 @@ require 'digest/sha1'
|
|||
nil
|
||||
end
|
||||
|
||||
|
||||
def self.to_win32pe(framework, code, opts={})
|
||||
|
||||
# For backward compatability, this is roughly equivalent to 'exe-small' fmt
|
||||
|
@ -400,7 +399,6 @@ require 'digest/sha1'
|
|||
return exe
|
||||
end
|
||||
|
||||
|
||||
def self.to_win32pe_old(framework, code, opts={})
|
||||
|
||||
payload = code.dup
|
||||
|
@ -466,7 +464,6 @@ require 'digest/sha1'
|
|||
return pe
|
||||
end
|
||||
|
||||
|
||||
def self.to_win64pe(framework, code, opts={})
|
||||
|
||||
# Allow the user to specify their own EXE template
|
||||
|
@ -1427,7 +1424,6 @@ End Sub
|
|||
return self.to_war(jspraw, opts)
|
||||
end
|
||||
|
||||
|
||||
# Creates a .NET DLL which loads data into memory
|
||||
# at a specified location with read/execute permissions
|
||||
# - the data will be loaded at: base+0x2065
|
||||
|
@ -1513,11 +1509,10 @@ End Sub
|
|||
api_call:
|
||||
pushad ; We preserve all the registers for the caller, bar EAX and ECX.
|
||||
mov ebp, esp ; Create a new stack frame
|
||||
xor eax, eax ; Zero EDX
|
||||
mov eax, [fs:eax+48] ; Get a pointer to the PEB
|
||||
mov eax, [eax+12] ; Get PEB->Ldr
|
||||
mov eax, [eax+20] ; Get the first module from the InMemoryOrder module list
|
||||
mov edx, eax
|
||||
xor edx, edx ; Zero EDX
|
||||
mov edx, [fs:edx+48] ; Get a pointer to the PEB
|
||||
mov edx, [edx+12] ; Get PEB->Ldr
|
||||
mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list
|
||||
next_mod: ;
|
||||
mov esi, [edx+40] ; Get pointer to modules name (unicode string)
|
||||
movzx ecx, word [edx+38] ; Set ECX to the length we want to check
|
||||
|
@ -1531,8 +1526,13 @@ End Sub
|
|||
not_lowercase: ;
|
||||
ror edi, 13 ; Rotate right our hash value
|
||||
add edi, eax ; Add the next byte of the name
|
||||
;loop loop_modname ; Loop until we have read enough
|
||||
; The random jmps added below will occasionally make this offset
|
||||
; greater than will fit in a byte, so we have to use a regular jnz
|
||||
; instruction which can take a full 32-bits to accomodate the
|
||||
; bigger offset
|
||||
dec ecx
|
||||
jnz loop_modname ; Loop untill we have read enough
|
||||
jnz loop_modname ; Loop until we have read enough
|
||||
; We now have the module hash computed
|
||||
push edx ; Save the current position in the module list for later
|
||||
push edi ; Save the current module hash for later
|
||||
|
@ -1550,7 +1550,7 @@ End Sub
|
|||
add ebx, edx ; Add the modules base address
|
||||
; Computing the module hash + function hash
|
||||
get_next_func: ;
|
||||
test ecx, ecx ; (Changed from JECXZ to work around METASM)
|
||||
test ecx, ecx ; Changed from jecxz to accomodate the larger offset produced by random jmps below
|
||||
jz get_next_mod ; When we reach the start of the EAT (we search backwards), process the next module
|
||||
dec ecx ; Decrement the function name counter
|
||||
mov esi, [ebx+ecx*4] ; Get rva of next module name
|
||||
|
@ -1593,7 +1593,7 @@ End Sub
|
|||
pop edi ; Pop off the current (now the previous) modules hash
|
||||
pop edx ; Restore our position in the module list
|
||||
mov edx, [edx] ; Get the next module
|
||||
jmp next_mod ; Process this module
|
||||
jmp next_mod ; Process this module
|
||||
^
|
||||
|
||||
stub_exit = %Q^
|
||||
|
@ -1626,7 +1626,7 @@ End Sub
|
|||
pop ebp ; Pop off the address of 'api_call' for calling later.
|
||||
|
||||
allocate_size:
|
||||
mov esi,PAYLOAD_SIZE
|
||||
mov esi, #{code.length}
|
||||
|
||||
allocate:
|
||||
push byte 0x40 ; PAGE_EXECUTE_READWRITE
|
||||
|
@ -1659,10 +1659,9 @@ End Sub
|
|||
get_payload:
|
||||
call got_payload
|
||||
payload:
|
||||
; Append an arbitary payload here
|
||||
; Append an arbitrary payload here
|
||||
^
|
||||
|
||||
|
||||
stub_alloc.gsub!('short', '')
|
||||
stub_alloc.gsub!('byte', '')
|
||||
|
||||
|
@ -1693,10 +1692,8 @@ End Sub
|
|||
wrapper << stub_final
|
||||
|
||||
enc = Metasm::Shellcode.assemble(Metasm::Ia32.new, wrapper).encoded
|
||||
off = enc.offset_of_reloc('PAYLOAD_SIZE')
|
||||
res = enc.data + code
|
||||
|
||||
res[off,4] = [code.length].pack('V')
|
||||
res
|
||||
end
|
||||
|
||||
|
@ -1735,12 +1732,11 @@ End Sub
|
|||
not_lowercase: ;
|
||||
ror edi, 13 ; Rotate right our hash value
|
||||
add edi, eax ; Add the next byte of the name
|
||||
dec ecx
|
||||
jnz loop_modname ; Loop untill we have read enough
|
||||
loop loop_modname ; Loop until we have read enough
|
||||
; We now have the module hash computed
|
||||
push edx ; Save the current position in the module list for later
|
||||
push edi ; Save the current module hash for later
|
||||
; Proceed to itterate the export address table,
|
||||
; Proceed to iterate the export address table,
|
||||
mov edx, [edx+16] ; Get this modules base address
|
||||
mov eax, [edx+60] ; Get PE header
|
||||
add eax, edx ; Add the modules base address
|
||||
|
@ -1796,7 +1792,7 @@ End Sub
|
|||
pop edi ; Pop off the current (now the previous) modules hash
|
||||
pop edx ; Restore our position in the module list
|
||||
mov edx, [edx] ; Get the next module
|
||||
jmp next_mod ; Process this module
|
||||
jmp next_mod ; Process this module
|
||||
^
|
||||
|
||||
stub_exit = %Q^
|
||||
|
@ -1830,7 +1826,7 @@ End Sub
|
|||
pop ebp ; Pop off the address of 'api_call' for calling later.
|
||||
|
||||
allocate_size:
|
||||
mov esi,PAYLOAD_SIZE
|
||||
mov esi,#{code.length}
|
||||
|
||||
allocate:
|
||||
push byte 0x40 ; PAGE_EXECUTE_READWRITE
|
||||
|
@ -1876,7 +1872,7 @@ End Sub
|
|||
get_payload:
|
||||
call got_payload
|
||||
payload:
|
||||
; Append an arbitary payload here
|
||||
; Append an arbitrary payload here
|
||||
^
|
||||
|
||||
|
||||
|
@ -1918,11 +1914,9 @@ End Sub
|
|||
wrapper << stub_final
|
||||
|
||||
enc = Metasm::Shellcode.assemble(Metasm::Ia32.new, wrapper).encoded
|
||||
off = enc.offset_of_reloc('PAYLOAD_SIZE')
|
||||
soff = enc.data.index("\xe9\xff\xff\xff\xff") + 1
|
||||
res = enc.data + code
|
||||
|
||||
res[off,4] = [code.length].pack('V')
|
||||
if which_offset == 'start'
|
||||
res[soff,4] = [block_offset - (soff + 4)].pack('V')
|
||||
elsif which_offset == 'end'
|
||||
|
@ -1935,15 +1929,35 @@ End Sub
|
|||
|
||||
|
||||
#
|
||||
# This routine is shared between msfencode, rpc, and payload modules (use <payload>)
|
||||
# Generate an executable of a given format suitable for running on the
|
||||
# architecture/platform pair.
|
||||
#
|
||||
# It will return nil if it wasn't able to generate any output.
|
||||
# This routine is shared between msfencode, rpc, and payload modules (use
|
||||
# <payload>)
|
||||
#
|
||||
# @param framework [Framework]
|
||||
# @param arch [String] Architecture for the target format; one of the ARCH_*
|
||||
# constants
|
||||
# @param plat [#index] platform
|
||||
# @param code [String] The shellcode for the resulting executable to run
|
||||
# @param fmt [String] One of the executable formats as defined in
|
||||
# {.to_executable_fmt_formats}
|
||||
# @param exeopts [Hash] Passed directly to the approrpriate method for
|
||||
# generating an executable for the given +arch+/+plat+ pair.
|
||||
# @return [String] An executable appropriate for the given
|
||||
# architecture/platform pair.
|
||||
# @return [nil] If the format is unrecognized or the arch and plat don't
|
||||
# make sense together.
|
||||
def self.to_executable_fmt(framework, arch, plat, code, fmt, exeopts)
|
||||
|
||||
output = nil
|
||||
|
||||
case fmt
|
||||
when 'asp'
|
||||
output = Msf::Util::EXE.to_win32pe_asp(framework, code, exeopts)
|
||||
|
||||
when 'aspx'
|
||||
output = Msf::Util::EXE.to_win32pe_aspx(framework, code, exeopts)
|
||||
|
||||
when 'dll'
|
||||
if (not arch or (arch.index(ARCH_X86)))
|
||||
output = Msf::Util::EXE.to_win32pe_dll(framework, code, exeopts)
|
||||
|
@ -1978,29 +1992,32 @@ End Sub
|
|||
|
||||
when 'elf'
|
||||
if (not plat or (plat.index(Msf::Module::Platform::Linux)))
|
||||
if (not arch or (arch.index(ARCH_X86)))
|
||||
output = Msf::Util::EXE.to_linux_x86_elf(framework, code, exeopts)
|
||||
elsif (arch and (arch.index( ARCH_X86_64 ) or arch.index( ARCH_X64 )))
|
||||
output = Msf::Util::EXE.to_linux_x64_elf(framework, code, exeopts)
|
||||
end
|
||||
output = case arch
|
||||
when ARCH_X86,nil then Msf::Util::EXE.to_linux_x86_elf(framework, code, exeopts)
|
||||
when ARCH_X86_64 then Msf::Util::EXE.to_linux_x64_elf(framework, code, exeopts)
|
||||
when ARCH_X64 then Msf::Util::EXE.to_linux_x64_elf(framework, code, exeopts)
|
||||
when ARCH_ARMLE then Msf::Util::EXE.to_linux_armle_elf(framework, code, exeopts)
|
||||
when ARCH_MIPSBE then Msf::Util::EXE.to_linux_mipsbe_elf(framework, code, exeopts)
|
||||
when ARCH_MIPSLE then Msf::Util::EXE.to_linux_mipsle_elf(framework, code, exeopts)
|
||||
end
|
||||
elsif(plat and (plat.index(Msf::Module::Platform::BSD)))
|
||||
if (not arch or (arch.index(ARCH_X86)))
|
||||
output = Msf::Util::EXE.to_bsd_x86_elf(framework, code, exeopts)
|
||||
end
|
||||
output = case arch
|
||||
when ARCH_X86,nil then Msf::Util::EXE.to_bsd_x86_elf(framework, code, exeopts)
|
||||
end
|
||||
elsif(plat and (plat.index(Msf::Module::Platform::Solaris)))
|
||||
if (not arch or (arch.index(ARCH_X86)))
|
||||
output = Msf::Util::EXE.to_solaris_x86_elf(framework, code, exeopts)
|
||||
end
|
||||
output = case arch
|
||||
when ARCH_X86,nil then Msf::Util::EXE.to_solaris_x86_elf(framework, code, exeopts)
|
||||
end
|
||||
end
|
||||
|
||||
when 'macho'
|
||||
if (not arch or (arch.index(ARCH_X86)))
|
||||
output = Msf::Util::EXE.to_osx_x86_macho(framework, code, exeopts)
|
||||
end
|
||||
|
||||
if (arch and (arch.index(ARCH_X86_64) or arch.index(ARCH_X64)))
|
||||
output = Msf::Util::EXE.to_osx_x64_macho(framework, code, exeopts)
|
||||
end
|
||||
output = case arch
|
||||
when ARCH_X86,nil then Msf::Util::EXE.to_osx_x86_macho(framework, code, exeopts)
|
||||
when ARCH_X86_64 then Msf::Util::EXE.to_osx_x64_macho(framework, code, exeopts)
|
||||
when ARCH_X64 then Msf::Util::EXE.to_osx_x64_macho(framework, code, exeopts)
|
||||
when ARCH_ARMLE then Msf::Util::EXE.to_osx_arm_macho(framework, code, exeopts)
|
||||
when ARCH_PPC then Msf::Util::EXE.to_osx_ppc_macho(framework, code, exeopts)
|
||||
end
|
||||
|
||||
when 'vba'
|
||||
output = Msf::Util::EXE.to_vba(framework, code, exeopts)
|
||||
|
@ -2015,12 +2032,6 @@ End Sub
|
|||
when 'loop-vbs'
|
||||
output = Msf::Util::EXE.to_win32pe_vbs(framework, code, exeopts.merge({ :persist => true }))
|
||||
|
||||
when 'asp'
|
||||
output = Msf::Util::EXE.to_win32pe_asp(framework, code, exeopts)
|
||||
|
||||
when 'aspx'
|
||||
output = Msf::Util::EXE.to_win32pe_aspx(framework, code, exeopts)
|
||||
|
||||
when 'war'
|
||||
arch ||= [ ARCH_X86 ]
|
||||
tmp_plat = plat.platforms if plat
|
||||
|
@ -2040,7 +2051,10 @@ End Sub
|
|||
end
|
||||
|
||||
def self.to_executable_fmt_formats
|
||||
['dll','exe','exe-small','exe-only','elf','macho','vba','vba-exe','vbs','loop-vbs','asp','aspx','war','psh','psh-net']
|
||||
[
|
||||
'dll','exe','exe-small','exe-only','elf','macho','vba','vba-exe',
|
||||
'vbs','loop-vbs','asp','aspx','war','psh','psh-net'
|
||||
]
|
||||
end
|
||||
|
||||
#
|
||||
|
|
128
msfvenom
128
msfvenom
|
@ -1,9 +1,6 @@
|
|||
#!/usr/bin/env ruby
|
||||
# -*- coding: binary -*-
|
||||
#
|
||||
# $Id: msfvenom 14909 2012-03-10 06:50:03Z rapid7 $
|
||||
# $Revision: 14909 $
|
||||
#
|
||||
|
||||
msfbase = __FILE__
|
||||
while File.symlink?(msfbase)
|
||||
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
|
||||
|
@ -426,107 +423,54 @@ end
|
|||
|
||||
$stdout.binmode
|
||||
|
||||
if opts[:format] !~/^(ruby|rb|perl|pl|bash|sh|c|csharp|js|dll|elf)$/i
|
||||
exe = Msf::Util::EXE.to_executable_fmt($framework, opts[:arch], opts[:platform], payload_raw, opts[:format], exeopts)
|
||||
end
|
||||
case opts[:format].downcase
|
||||
# Special-case this to check endianness
|
||||
when "js_be"
|
||||
|
||||
case opts[:format]
|
||||
when /^(ruby|rb|perl|pl|bash|sh|c|csharp|js_le|raw|py)$/i
|
||||
$stdout.write Msf::Simple::Buffer.transform(payload_raw, opts[:format])
|
||||
when /^asp$/
|
||||
asp = Msf::Util::EXE.to_win32pe_asp($framework, payload_raw, exeopts)
|
||||
$stdout.puts asp
|
||||
when /^aspx$/
|
||||
aspx = Msf::Util::EXE.to_win32pe_aspx($framework, payload_raw, exeopts)
|
||||
$stdout.puts aspx
|
||||
when /^js_be$/i
|
||||
if Rex::Arch.endian(payload.arch) != ENDIAN_BIG
|
||||
print_error("Big endian format selected for a non big endian payload")
|
||||
exit
|
||||
end
|
||||
$stdout.puts Msf::Simple::Buffer.transform(payload_raw, opts[:format])
|
||||
when /^java$/i
|
||||
if(!exe and payload.platform.platforms.index(Msf::Module::Platform::Java))
|
||||
exe = payload.generate_jar.pack
|
||||
end
|
||||
$stdout.write Msf::Simple::Buffer.transform(payload_raw, opts[:format])
|
||||
|
||||
if exe
|
||||
$stdout.write exe
|
||||
else
|
||||
print_error("Could not generate payload format")
|
||||
end
|
||||
when /^elf$/i
|
||||
if (opts[:platform].index(Msf::Module::Platform::Linux))
|
||||
elf = case opts[:arch]
|
||||
when /^x64$/; Msf::Util::EXE.to_linux_x64_elf($framework, payload_raw, exeopts)
|
||||
when /^x86$/; Msf::Util::EXE.to_linux_x86_elf($framework, payload_raw, exeopts)
|
||||
when /^arm$/; Msf::Util::EXE.to_linux_armle_elf($framework, payload_raw, exeopts)
|
||||
end
|
||||
elsif(opts[:platform].index(Msf::Module::Platform::BSD))
|
||||
elf = case opts[:arch]
|
||||
when /^x86$/; Msf::Util::EXE.to_bsd_x86_elf($framework, payload_raw, exeopts)
|
||||
end
|
||||
elsif(opts[:platform].index(Msf::Module::Platform::Solaris))
|
||||
elf = case opts[:arch]
|
||||
when /^x86$/; Msf::Util::EXE.to_solaris_x86_elf($framework, payload_raw, exeopts)
|
||||
end
|
||||
end
|
||||
if elf.nil?
|
||||
print_error("This format does not support that architecture")
|
||||
exit
|
||||
end
|
||||
$stdout.write elf
|
||||
when /^macho$/i
|
||||
bin = case opts[:arch]
|
||||
when /^x64$/; Msf::Util::EXE.to_osx_x64_macho($framework, payload_raw, exeopts)
|
||||
when /^x86$/; Msf::Util::EXE.to_osx_x86_macho($framework, payload_raw, exeopts)
|
||||
when /^arm$/; Msf::Util::EXE.to_osx_arm_macho($framework, payload_raw, exeopts)
|
||||
when /^ppc$/; Msf::Util::EXE.to_osx_ppc_macho($framework, payload_raw, exeopts)
|
||||
end
|
||||
if bin.nil?
|
||||
print_error("This format does not support that architecture")
|
||||
exit
|
||||
end
|
||||
$stdout.write bin
|
||||
when /^dll$/i
|
||||
dll = case opts[:arch]
|
||||
when /^x86$/; Msf::Util::EXE.to_win32pe_dll($framework, payload_raw)
|
||||
when /^(x64|x86_64)$/; Msf::Util::EXE.to_win64pe_dll($framework, payload_raw)
|
||||
end
|
||||
if dll.nil?
|
||||
print_error("This format does not support that architecture")
|
||||
exit
|
||||
end
|
||||
|
||||
$stdout.write dll
|
||||
when /^exe$/i
|
||||
$stdout.write exe
|
||||
when /^exe-small$/i
|
||||
when /^vba$/i
|
||||
vba = Msf::Util::EXE.to_vba($framework, payload_raw)
|
||||
$stdout.puts vba
|
||||
when /^vba-exe$/i
|
||||
exe = Msf::Util::EXE.to_win32pe($framework, payload_raw)
|
||||
vba = Msf::Util::EXE.to_exe_vba(exe)
|
||||
$stdout.puts vba
|
||||
when /^vbs$/i
|
||||
exe = Msf::Util::EXE.to_win32pe($framework, payload_raw)
|
||||
vbs = Msf::Util::EXE.to_exe_vbs(exe)
|
||||
$stdout.puts vbs
|
||||
when /^war$/i
|
||||
# Special-case this so we can build a war directly from the payload if
|
||||
# possible
|
||||
when "war"
|
||||
exe = Msf::Util::EXE.to_executable_fmt($framework, opts[:arch], opts[:platform], payload_raw, opts[:format], exeopts)
|
||||
if (!exe and payload.platform.platforms.index(Msf::Module::Platform::Java))
|
||||
exe = payload.generate_war.pack
|
||||
else
|
||||
exe = Msf::Util::EXE.to_jsp_war(exe)
|
||||
end
|
||||
$stdout.write exe
|
||||
when /^psh$/i
|
||||
psh = Msf::Util::EXE.to_win32pe_psh($framework, payload_raw, exeopts)
|
||||
$stdout.write psh
|
||||
when /^psh-net$/i
|
||||
psh = Msf::Util::EXE.to_win32pe_psh_net($framework, payload_raw, exeopts)
|
||||
$stdout.write psh
|
||||
|
||||
# Same as war, special-case this so we can build a jar directly from the
|
||||
# payload if possible
|
||||
when "java"
|
||||
exe = Msf::Util::EXE.to_executable_fmt($framework, opts[:arch], opts[:platform], payload_raw, opts[:format], exeopts)
|
||||
if(!exe and payload.platform.platforms.index(Msf::Module::Platform::Java))
|
||||
exe = payload.generate_jar.pack
|
||||
end
|
||||
if exe
|
||||
$stdout.write exe
|
||||
else
|
||||
print_error("Could not generate payload format")
|
||||
end
|
||||
|
||||
when *Msf::Simple::Buffer.transform_formats
|
||||
$stdout.write Msf::Simple::Buffer.transform(payload_raw, opts[:format])
|
||||
|
||||
when *Msf::Util::EXE.to_executable_fmt_formats
|
||||
exe = Msf::Util::EXE.to_executable_fmt($framework, opts[:arch], opts[:platform], payload_raw, opts[:format], exeopts)
|
||||
if exe.nil?
|
||||
print_error("This format does not support that platform/architecture")
|
||||
exit
|
||||
end
|
||||
$stdout.write exe
|
||||
|
||||
else
|
||||
print_error("Unsupported format")
|
||||
exit
|
||||
end
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue