Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
beefproject
GitHub Repository: beefproject/beef
Path: blob/master/extensions/admin_ui/media/javascript/ui/panel/tabs/ZombieTabRTC.js
1155 views
1
//
2
// Copyright (c) 2006-2025 Wade Alcorn - [email protected]
3
// Browser Exploitation Framework (BeEF) - https://beefproject.com
4
// See the file 'doc/COPYING' for copying permission
5
//
6
7
/*
8
* The RTC tab panel for the selected zombie browser.
9
* Loaded in /ui/panel/index.html
10
*/
11
ZombieTab_Rtc = function(zombie) {
12
var zombie_id = beefwui.get_hb_id(zombie.session);
13
14
// The status bar.
15
var commands_statusbar = new Beef_StatusBar('webrtc-bbar-zombie-'+zombie.session);
16
// RESTful API token
17
var token = beefwui.get_rest_token();
18
19
/*
20
* The panel that displays all identified network services grouped by host
21
********************************************/
22
var rtc_events_panel_store = new Ext.ux.data.PagingJsonStore({
23
storeId: 'rtc-events-store-zombie-'+zombie.session,
24
proxy: new Ext.data.HttpProxy({
25
url: '/api/webrtc/events/'+zombie_id+'?token='+token,
26
method: 'GET'
27
}),
28
remoteSort: false,
29
autoDestroy: true,
30
autoLoad: false,
31
root: 'events',
32
fields: ['id', 'hb_id', 'target_id', 'status', 'created_at', 'updated_at'],
33
sortInfo: {field: 'id', direction: 'ASC'}
34
});
35
36
var req_pagesize = 50;
37
38
var rtc_events_panel_bbar = new Ext.PagingToolbar({
39
pageSize: req_pagesize,
40
store: rtc_events_panel_store,
41
displayInfo: true,
42
displayMsg: 'Displaying RTC events {0} - {1} of {2}',
43
emptyMsg: 'No events to display'
44
});
45
46
var rtc_events_panel_grid = new Ext.grid.GridPanel({
47
id: 'rtc-events-grid-zombie-'+zombie.session,
48
store: rtc_events_panel_store,
49
bbar: rtc_events_panel_bbar,
50
border: false,
51
loadMask: {msg:'Loading events...'},
52
53
viewConfig: {
54
forceFit: true
55
},
56
57
view: new Ext.grid.GridView({
58
forceFit: true,
59
emptyText: "No events",
60
enableRowBody:true
61
}),
62
63
columns: [
64
{header: 'Id', width: 5, sortable: true, dataIndex: 'id', hidden:true},
65
{header: 'From', width: 10, sortable: true, dataIndex: 'hb_id', hidden:true},
66
{header: 'Peer', width: 10, sortable: true, dataIndex: 'target_id', renderer: function(value){
67
if (value === zombie_id) {
68
return $jEncoder.encoder.encodeForHTML(value) + " (selected)";
69
} else {
70
// 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) + ")";
71
return $jEncoder.encoder.encodeForHTML(value) + " (" + beefwui.get_info_from_id(value)['ip'] + ")";
72
}
73
}},
74
{header: 'Status', width: 20, sortable: true, dataIndex: 'status', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}},
75
{header: 'Created At', width: 10, sortable: true, dataIndex: 'created_at', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}},
76
{header: 'Updated At', width: 10, sortable: true, dataIndex: 'updated_at', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}}
77
],
78
79
listeners: {
80
contextmenu: function(e, element, options) {
81
e.preventDefault();
82
},
83
containercontextmenu: function(view, e) {
84
e.preventDefault();
85
},
86
rowcontextmenu: function(grid, rowIndex, e) {
87
e.preventDefault();
88
grid.getSelectionModel().selectRow(rowIndex);
89
if (!!grid.rowCtxMenu) {
90
grid.rowCtxMenu.destroy();
91
}
92
var record = grid.selModel.getSelected();
93
if (record.json.status==="Connected") {
94
grid.rowCtxMenu = new Ext.menu.Menu({
95
items: [
96
{
97
text: "Command Peer to Stealth",
98
handler: function() {
99
if (zombie_id === record.json.hb_id) {
100
var from = record.json.hb_id;
101
var to = record.json.target_id;
102
} else {
103
var from = record.json.target_id;
104
var to = record.json.hb_id;
105
}
106
commands_statusbar.update_sending("Sending stealth command");
107
var url = "/api/webrtc/msg?token=" + beefwui.get_rest_token();
108
Ext.Ajax.request({
109
url: url,
110
method: 'POST',
111
headers: {'Content-Type': 'application/json; charset=UTF-8'},
112
jsonData: {
113
'from': from,
114
'to': to,
115
'message': "!gostealth"
116
},
117
success: function(data){
118
commands_statusbar.update_sent("Stealth command sent successfully");
119
},
120
error: function(){
121
commands_statusbar.update_fail("Error sending stealth command");
122
}
123
});
124
}
125
},{
126
text: "Execute Command Module via RTC",
127
handler: function() {
128
var url = "/api/webrtc/cmdexec?token=" + beefwui.get_rest_token();
129
var cmd_id = prompt("Enter command module ID:");
130
if (!cmd_id || cmd_id == "" || isNaN(cmd_id)) {
131
commands_statusbar.update_fail('Invalid command module ID');
132
return;
133
}
134
var cmd_opts = prompt("Parameters:");
135
if (cmd_opts == "") {
136
cmd_opts = "[]";
137
}
138
try {
139
cmd_opts = JSON.parse(cmd_opts);
140
} catch (e) {
141
commands_statusbar.update_fail("Invalid JSON")
142
return;
143
}
144
if (zombie_id === record.json.hb_id) {
145
var from = record.json.hb_id;
146
var to = record.json.target_id;
147
} else {
148
var from = record.json.target_id;
149
var to = record.json.hb_id;
150
}
151
commands_statusbar.update_sending("Sending command [id: " + cmd_id + "]");
152
Ext.Ajax.request({
153
url: url,
154
method: 'POST',
155
headers: {'Content-Type': 'application/json; charset=UTF-8'},
156
jsonData: {
157
'from': from,
158
'to': to,
159
'cmdid': cmd_id,
160
'options': cmd_opts
161
},
162
success: function(data){
163
commands_statusbar.update_sent("Command [id: " + cmd_id + "] sent successfully");
164
},
165
error: function(){
166
commands_statusbar.update_fail("Error executing module [id: " + cmd_id + "]");
167
}
168
});
169
}
170
}
171
]
172
});
173
grid.rowCtxMenu.showAt(e.getXY());
174
} else if (record.json.status==="Stealthed!!") {
175
grid.rowCtxMenu = new Ext.menu.Menu({
176
items: [
177
{
178
text: "Command Peer to un-stealth",
179
handler: function() {
180
if (zombie_id === record.json.hb_id) {
181
commands_statusbar.update_sending("Sending un-stealth command");
182
var url = "/api/webrtc/msg?token=" + beefwui.get_rest_token();
183
Ext.Ajax.request({
184
url: url,
185
method: 'POST',
186
headers: {'Content-Type': 'application/json; charset=UTF-8'},
187
jsonData: {
188
'from': record.json.hb_id,
189
'to': record.json.target_id,
190
'message': "!endstealth"
191
},
192
success: function(data){
193
commands_statusbar.update_sent("Un-stealth command sent successfully");
194
},
195
error: function(){
196
commands_statusbar.update_fail("Error sending un-stealth command");
197
}
198
});
199
}
200
}
201
},{
202
text: "Execute Command Module via RTC",
203
handler: function() {
204
var url = "/api/webrtc/cmdexec?token=" + beefwui.get_rest_token();
205
var cmd_id = prompt("Enter command module ID:");
206
if (!cmd_id || cmd_id == "" || isNaN(cmd_id)) {
207
commands_statusbar.update_fail('Invalid command module ID');
208
return;
209
}
210
var cmd_opts = prompt("Parameters:");
211
if (cmd_opts == "") {
212
cmd_opts = "[]";
213
}
214
try {
215
cmd_opts = JSON.parse(cmd_opts);
216
} catch (e) {
217
commands_statusbar.update_fail("Invalid JSON")
218
return;
219
}
220
commands_statusbar.update_sending("Sending command [id: " + cmd_id + "]")
221
Ext.Ajax.request({
222
url: url,
223
method: 'POST',
224
headers: {'Content-Type': 'application/json; charset=UTF-8'},
225
jsonData: {
226
'from': record.json.hb_id,
227
'to': record.json.target_id,
228
'cmdid': cmd_id,
229
'options': cmd_opts
230
},
231
success: function(data){
232
commands_statusbar.update_sent("Command [id: " + cmd_id + "] sent successfully");
233
},
234
error: function(){
235
commands_statusbar.update_fail("Error executing module [id: " + cmd_id + "]");
236
}
237
});
238
}
239
}
240
]
241
});
242
grid.rowCtxMenu.showAt(e.getXY());
243
}
244
},
245
afterrender: function(datagrid) {
246
datagrid.store.reload({params: {nonce: Ext.get("nonce").dom.value}});
247
}
248
}
249
250
});
251
252
var rtc_events_panel = new Ext.Panel({
253
id: 'rtc-events-host-panel-zombie-'+zombie.session,
254
title: 'Peers',
255
items:[rtc_events_panel_grid],
256
layout: 'fit',
257
listeners: {
258
activate: function(hosts_panel) {
259
rtc_events_panel.items.items[0].store.reload({ params: {nonce: Ext.get ("nonce").dom.value} });
260
}
261
}
262
});
263
264
/*
265
* The panel that displays all command modules executed via RTC
266
********************************************/
267
var rtc_moduleevents_panel_store = new Ext.ux.data.PagingJsonStore({
268
storeId: 'rtc-moduleevents-store-zombie-'+zombie.session,
269
proxy: new Ext.data.HttpProxy({
270
url: '/api/webrtc/cmdevents/'+zombie_id+'?token='+token,
271
method: 'GET'
272
}),
273
remoteSort: false,
274
autoDestroy: true,
275
autoLoad: false,
276
root: 'events',
277
fields: ['id', 'hb_id', 'target_id', 'status', 'created_at', 'updated_at', 'mod'],
278
sortInfo: {field: 'id', direction: 'ASC'}
279
});
280
281
var rtc_moduleevents_panel_bbar = new Ext.PagingToolbar({
282
pageSize: req_pagesize,
283
store: rtc_moduleevents_panel_store,
284
displayInfo: true,
285
displayMsg: 'Displaying RTC command events {0} - {1} of {2}',
286
emptyMsg: 'No events to display'
287
});
288
289
var rtc_moduleevents_panel_grid = new Ext.grid.GridPanel({
290
id: 'rtc-moduleevents-grid-zombie-'+zombie.session,
291
store: rtc_moduleevents_panel_store,
292
bbar: rtc_moduleevents_panel_bbar,
293
border: false,
294
loadMask: {msg:'Loading events...'},
295
296
viewConfig: {
297
forceFit: true
298
},
299
300
view: new Ext.grid.GridView({
301
forceFit: true,
302
emptyText: "No events",
303
enableRowBody:true
304
}),
305
306
columns: [
307
{header: 'Id', width: 5, sortable: true, dataIndex: 'id', hidden:true},
308
{header: 'From', width: 10, sortable: true, dataIndex: 'hb_id', hidden:true},
309
{header: 'Peer', width: 10, sortable: true, dataIndex: 'target_id', renderer: function(value){
310
if (value === zombie_id) {
311
return $jEncoder.encoder.encodeForHTML(value) + " (selected)";
312
} else {
313
return $jEncoder.encoder.encodeForHTML(value) + " (" + beefwui.get_info_from_id(value)['ip'] + ")";
314
}
315
}},
316
{header: 'Module', width: 10, sortable: true, dataIndex: 'mod', renderer: function(value){
317
return $jEncoder.encoder.encodeForHTML(value);
318
}},
319
{header: 'Status', width: 20, sortable: true, dataIndex: 'status', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}},
320
{header: 'Created At', width: 10, sortable: true, dataIndex: 'created_at', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}},
321
{header: 'Updated At', width: 10, sortable: true, dataIndex: 'updated_at', renderer: function(value){return $jEncoder.encoder.encodeForHTML(value)}}
322
]
323
});
324
325
var rtc_moduleevents_panel = new Ext.Panel({
326
id: 'rtc-moduleevents-host-panel-zombie-'+zombie.session,
327
title: 'Command module results',
328
items:[rtc_moduleevents_panel_grid],
329
layout: 'fit',
330
listeners: {
331
activate: function(hosts_panel) {
332
rtc_moduleevents_panel.items.items[0].store.reload({ params: {nonce: Ext.get ("nonce").dom.value} });
333
}
334
}
335
});
336
/*
337
* The Network tab constructor
338
********************************************/
339
ZombieTab_Rtc.superclass.constructor.call(this, {
340
id: 'zombie-rtc-tab-zombie-'+zombie.session,
341
title: 'WebRTC',
342
activeTab: 0,
343
viewConfig: {
344
forceFit: true,
345
stripRows: true,
346
type: 'fit'
347
},
348
items: [rtc_events_panel,rtc_moduleevents_panel],
349
bbar: commands_statusbar,
350
listeners: {
351
}
352
});
353
354
};
355
356
Ext.extend(ZombieTab_Rtc, Ext.TabPanel, {});
357
358