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