Moving RBeEF to trunk

git-svn-id: https://beef.googlecode.com/svn/trunk@503 b87d56ec-f9c0-11de-8c8a-61c5e9addfc9
This commit is contained in:
scotty.b.brown
2010-11-11 09:16:11 +00:00
parent 8d073f8738
commit ffa735caff
346 changed files with 84143 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
Ext.onReady(function() {
var bd = Ext.getBody();
// xntrik 9/7/10 this is the functionality to try and submit the form
submitAuthForm = function() {
login_form.getForm().submit({
waitMsg: 'Logging in ...',
success: function() {
window.location.href = '/ui/panel'
},
failure: function() {
Ext.MessageBox.alert('Message', 'Error with username or password')
}
});
}
var login_form = new Ext.FormPanel({
url: 'authentication/login',
formId: 'login_form',
labelWidth: 125,
frame: true,
title: 'Authentication',
bodyStyle:'padding:5px 5px 0',
width: 350,
defaults: {
width: 175,
inputType: 'password'
},
defaultType: 'textfield',
items: [{
fieldLabel: 'Username',
name: 'username-cfrm',
inputType: 'textfield',
id: 'user',
listeners: { // xntrik 9/7/10 added this listener so form submits on enter
specialkey: function(field,e) {
if (e.getKey() == e.ENTER) {
submitAuthForm();
}
}
}
},{
fieldLabel: 'Password',
name: 'password-cfrm',
inputType: 'password',
id: 'pass',
listeners: { // xntrik 9/7/10 added this listener so form submits on enter
specialkey: function(field,e) {
if (e.getKey() == e.ENTER) {
submitAuthForm();
}
}
}
}],
buttons: [{
text: 'Login',
handler: function() { // xntrik 9/7/10 removed the logic here, placed
//in function above and added here
submitAuthForm();
}
}]
});
login_form.render('centered');
document.getElementById('user').focus(); //xntrik 27/7/10 - this doesn't throw warnings now
});

View File

@@ -0,0 +1,53 @@
AboutWindow = function() {
about = " \
<p> \
BeEF, the Browser Exploitation Framework is a professional security \
tool provided for lawful research and testing purposes. It allows \
the experienced penetration tester or system administrator additional \
attack vectors when assessing the posture of a target. The user of \
BeEF will control which browser will launch which module and at \
which target.\
<p><br> \
BeEF hooks one or more web browsers as beachheads for the launching \
of directed modules in real-time. Each browser is likely to be \
within a different security context. This provides additional vectors \
that can be exploited by security professionals. \
<p><br> \
<b>Authors:</b><br> \
- Wade Alcorn (Founder, Architect)<br> \
- Benjamin Mosse (Main developer) \
</p> \
";
var button = Ext.get('open-about-menu');
var about_open = false;
button.on('click', function(){
if(!about_open) {
var content = new Ext.Panel({
region: 'center',
padding: '3 3 3 3',
html: about
});
var win = new Ext.Window({
title: 'About BeEF',
closable:true,
width:600,
height:250,
plain:true,
layout: 'border',
shadow: true,
items: [content]
});
win.on('close', function() {
about_open = false;
});
win.show(this);
about_open = true;
}
})
};

View File

@@ -0,0 +1,75 @@
DataGrid = function(url, page, base) {
this.page = page;
this.url = url;
this.base = typeof(base) != 'undefined' ? base : {};
this.store = new Ext.data.JsonStore({
root: 'logs',
autoDestroy: true,
url: this.url,
storeId: 'myStore',
baseParams: this.base,
autoLoad: {params:{start:0, limit:this.page, sort:"date", dir:"DESC"}},
idProperty: 'id',
fields: ['id','type','event','date'],
totalProperty: 'count',
remoteSort: true,
sortInfo: {field: "date", direction: "DESC"}
});
this.bbar = new Ext.PagingToolbar({
pageSize: this.page,
store: this.store,
displayInfo: true,
displayMsg: 'Displaying logs {0} - {1} of {2}',
emptyMsg: 'No logs to display'
});
this.columns = [{
id: 'log-id',
header: 'Id',
hidden: true,
dataIndex: 'id',
sortable: false
}, {
id: 'log-type',
header: "Type",
dataIndex: 'type',
sortable: true,
width: 60,
renderer: function(value, metaData, record, rowIndex, colIndex, store) {
return "<b>" + value + "</b>";
}
}, {
id: 'log-event',
header: "Event",
dataIndex: 'event',
sortable:true,
width: 420,
renderer: this.formatTitle
}, {
id: 'log-date',
header: "Date",
dataIndex: 'date',
width: 80,
renderer: this.formatDate,
sortable:true
}];
DataGrid.superclass.constructor.call(this, {
region: 'center',
id: 'topic-grid',
loadMask: {msg:'Loading Feed...'},
sm: new Ext.grid.RowSelectionModel({
singleSelect:true
}),
viewConfig: {
forceFit:true
}
});
};
Ext.extend(DataGrid, Ext.grid.GridPanel, {});

View File

@@ -0,0 +1,20 @@
DoLogout = function() {
var button = Ext.get('do-logout-menu');
after_logout = function() {
// will redirect the UA to the login
window.location.href = '/ui/panel'
}
button.on('click', function(){
Ext.Ajax.request({
url: '/ui/authentication/logout',
method: 'POST',
params: 'nonce=' + Ext.get("nonce").dom.value,
success: after_logout,
failure: after_logout
});
})
};

View File

@@ -0,0 +1,66 @@
MainPanel = function(){
this.preview = new Ext.Panel({
id: 'preview',
region: 'south',
cls:'preview',
autoScroll: true,
listeners: PanelViewer.LinkInterceptor,
tbar: [{
id:'tab',
text: 'View in New Tab',
iconCls: 'new-tab',
disabled:true,
handler : this.openTab,
scope: this
}],
clear: function(){
this.body.update('');
var items = this.topToolbar.items;
items.get('tab').disable();
items.get('win').disable();
}
});
this.grid = new DataGrid('/ui/logs/all.json',25);
this.grid.border = false;
this.welcome_tab = new WelcomeTab;
MainPanel.superclass.constructor.call(this, {
id:'main-tabs',
activeTab:0,
region:'center',
margins:'0 5 5 0',
resizeTabs:true,
tabWidth:150,
minTabWidth: 120,
enableTabScroll: true,
plugins: new Ext.ux.TabCloseMenu(),
items: [{
id:'welcome-view',
title:'Getting Started',
layout:'border',
hideMode:'offsets',
closable:true,
plain:true,
shadow:true,
items:[
this.welcome_tab
]},{
id:'logs-view',
layout:'border',
title:'Logs',
hideMode:'offsets',
items:[
this.grid
]
}]
});
};
Ext.extend(MainPanel, Ext.TabPanel);
Ext.reg('appmainpanel', MainPanel);

View File

@@ -0,0 +1,74 @@
/*
* The Beef_StatusBar class provides the functionality of the status bar
* at the bottom of each tab in the UI
*
* @param: {String} unique string for setting the status bar id.
*
*/
Beef_StatusBar = function(unique_id) {
var update_fail_wait = 2000; // delay before showing ready status
var update_sent_wait = 1000; // delay before showing ready status
Beef_StatusBar.superclass.constructor.call(this, {
id: 'commands-bbar-zombie-' + unique_id,
// defaults to use when the status is cleared:
defaultText: 'Ready',
defaultIconCls: 'x-status-valid',
// values to set initially:
text: 'Ready',
iconCls: 'x-status-valid',
// update status bar to ready
update_ready: function(str) {
var display_str = str || "Ready";
this.setStatus({
text: display_str,
iconCls: 'x-status-valid'
});
},
// update status bar to fail
update_fail: function(str){
var display_str = str || "Error!";
this.setStatus({
text: display_str,
iconCls: 'x-status-error',
clear: {
wait: update_fail_wait,
anim: true,
useDefaults: true
}
});
},
// update status bar to sending
update_sending: function(str) {
var display_str = str || "Sending...";
this.showBusy(display_str);
},
// update status bar to sent
update_sent: function(str) {
var display_str = str || "Sent";
this.setStatus({
text: display_str,
iconCls: 'x-status-valid',
clear: {
wait: update_sent_wait,
anim: true,
useDefaults: true
}
});
}
});
};
Ext.extend(Beef_StatusBar, Ext.ux.StatusBar, {} );

View File

@@ -0,0 +1,27 @@
PanelViewer = {};
var mainPanel, zombiesPanel;
Ext.onReady(function() {
Ext.QuickTips.init();
zombiesPanel = new ZombiesPanel();
mainPanel = new MainPanel();
var viewport = new Ext.Viewport({
layout:'border',
items:[
new Ext.BoxComponent({
region:'north',
el: 'header',
height: 32
}),
zombiesPanel,
mainPanel
]
});
new DoLogout();
new AboutWindow();
new ZombiesMgr(zombiesPanel);
});

View File

@@ -0,0 +1,26 @@
WelcomeTab = function() {
welcome = " \
<div style='font:13px tahoma,arial,helvetica,sans-serif'> \
<p><img src='/ui/public/images/icons/beef.gif' />&nbsp; <span style='font:bold 15px tahoma,arial,helvetica,sans-serif'>BeEF - The Browser Exploitation Framework</span></p><br /> \
<p>Welcome to BeEF!</p><br /> \
<p>Before being able to fully explore the framework you will have to 'hook' a browser. To begin with you can point a browser towards the demo page <a href='/demos/basic.html' target='_blank'>here</a>.</p><br /> \
<p>After a browser is hooked into the framework they will appear in the 'Hooked Browsers' panel on the left. Hooked browsers will appear in either an online or offline state, depending on how recently they have polled the framework. To interact with a hooked browser simply click it, a new tab will appear.</p><br /> \
<p>Each hooked browser tab has a number of sub-tabs, described below:</p> \
<p><ul><li><span style='font:bold 13px tahoma,arial,helvetica,sans-serif'>Main:</span> Display information about the hooked browser after you've run some command modules</li> \
<li><span style='font:bold 13px tahoma,arial,helvetica,sans-serif'>Logs:</span> Displays recent log entries related to this particular hooked browser.</li> \
<li><span style='font:bold 13px tahoma,arial,helvetica,sans-serif'>Commands:</span> This tab is where modules can be executed against the hooked browser. This is where most of the BeEF functionality resides.</li> \
<li><span style='font:bold 13px tahoma,arial,helvetica,sans-serif'>Requester:</span> The Requester tab is a special module that allows you to submit arbitrary HTTP requests on behalf of the hooked browser.</li></ul></p><br /> \
<p>For more information visit: <a href='http://code.google.com/p/beef/'>http://code.google.com/p/beef/</a></p><br />\
</div> \
";
WelcomeTab.superclass.constructor.call(this, {
region:'center',
padding:'10 10 10 10',
html: welcome,
border: false
});
};
Ext.extend(WelcomeTab,Ext.Panel, {});

View File

@@ -0,0 +1,31 @@
ZombieTab = function(zombie) {
main_tab = new ZombieTab_MainTab(zombie);
log_tab = new ZombieTab_LogTab(zombie);
commands_tab = new ZombieTab_Commands(zombie);
requester_tab = new ZombieTab_Requester(zombie);
//-------------------------------------------
ZombieTab.superclass.constructor.call(this, {
id: zombie.session,
activeTab: 0,
loadMask: {msg:'Loading browser...'},
title: zombie.ip,
autoScroll: true,
closable: true,
viewConfig: {
forceFit: true,
type: 'fit'
},
items:[main_tab, log_tab, commands_tab, requester_tab]
});
};
Ext.extend(ZombieTab, Ext.TabPanel, {
listeners: {
close: function(panel) {
panel.destroy();
}
}
});

View File

@@ -0,0 +1,82 @@
var ZombiesMgr = function(zombies) {
var selectedZombie = null;
var addZombie = function(zombie){
selectedZombie = zombie;
}
var delZombie = function(zombie){
if (selectedZombie.session == zombie.session) {
selectedZombie = null;
}
return null;
}
var getZombie = function(){
return selectedZombie;
}
// this is a helper class to create a zombie object from a JSON hash index
var zombieFactory = function(index, zombie_array){
text = zombie_array[index]["ip"]
text = "<img src='/ui/public/images/icons/"+escape(zombie_array[index]["os_icon"])+"' style='padding-top:3px;' width='13px' height='13px'/> "+text
var new_zombie = {
'id' : index,
'ip' : zombie_array[index]["ip"],
'session' : zombie_array[index]["session"],
'text': text,
'icon': '/ui/public/images/icons/'+escape(zombie_array[index]["browser_icon"]),
'domain' : zombie_array[index]["domain"]
};
return new_zombie;
}
var updateZombies = function(){
Ext.Ajax.request({
url: '/ui/zombies/select/offline/simple.json',
success: function(response) {
var offline_zombies = Ext.util.JSON.decode(response.responseText);
zombies.compareAndRemove(offline_zombies, false);
for(var i in offline_zombies) {
var zombie = zombieFactory(i, offline_zombies);
zombies.addZombie(zombie, false);
}
}
});
Ext.Ajax.request({
url: '/ui/zombies/select/online/simple.json',
success: function(response){
var online_zombies = Ext.util.JSON.decode(response.responseText);
zombies.compareAndRemove(online_zombies, true);
for(var i in online_zombies) {
var zombie = zombieFactory(i, online_zombies);
zombies.addZombie(zombie, true);
}
if(zombies.online_zombies.childNodes.length > 0) {
zombies.online_zombies.expand(true);
}
if(zombies.offline_zombies.childNodes.length > 0) {
zombies.offline_zombies.expand(true);
}
}
});
}
Ext.TaskMgr.start({
run: updateZombies,
interval: 8000
});
}

View File

@@ -0,0 +1,119 @@
/*
* The zombie panel located on the left hand side of the interface.
*/
ZombiesPanel = function() {
ZombiesPanel.superclass.constructor.call(this, {
id:'zombie-tree',
region:'west',
title:'Hooked Browsers',
split:true,
width: 225,
minSize: 175,
maxSize: 400,
collapsible: true,
margins:'0 0 5 5',
cmargins:'0 5 5 5',
rootVisible:false,
lines:false,
autoScroll:true,
root: new Ext.tree.TreeNode('My Zombies'),
collapseFirst:false
});
this.online_zombies = this.root.appendChild(
new Ext.tree.TreeNode({
text:'Online Browsers',
cls:'online-zombies-node',
expanded:true
})
);
this.offline_zombies = this.root.appendChild(
new Ext.tree.TreeNode({
text:'Offline Browsers',
cls:'offline-zombies-node',
expanded:false
})
);
};
/*
* The Tree panel that contains the zombie list.
*/
Ext.extend(ZombiesPanel, Ext.tree.TreePanel, {
listeners: {
click: function(node, e) {
if(!node.leaf) return;
if(!mainPanel.get(node.attributes.session)) {
mainPanel.add(new ZombieTab(node.attributes));
}
mainPanel.activate(node.attributes.session);
}
},
selectZombie: function(url){
this.getNodeById(url).select();
},
addZombie : function(attrs, online){
if(online) {
var z_id = 'zombie-online-' + attrs.session;
} else {
var z_id = 'zombie-offline-' + attrs.session;
}
var exists = this.getNodeById(z_id);
if(exists){
return;
}
Ext.apply(attrs, {
iconCls: 'feed-icon',
leaf:true,
id: z_id
});
var node = new Ext.tree.TreeNode(attrs);
if(online) {
Ext.apply(attrs, {cls: 'zombie-online'});
this.online_zombies.appendChild(node);
} else {
Ext.apply(attrs, {cls: 'zombie-offline'});
this.offline_zombies.appendChild(node);
}
return node;
},
removeAll : function(){
this.online_zombies.removeAll();
this.offline_zombies.removeAll();
},
compareAndRemove : function(zombies, online) {
for(var i in zombies) {
if(online) {
var z = 'zombie-offline-' + zombies[i].session;;
} else {
var z = 'zombie-online-' + zombies[i].session;;
}
var exists = this.getNodeById(z);
if(exists) {
if(!online) {
this.online_zombies.removeChild(exists);
} else {
this.offline_zombies.removeChild(exists);
}
}
}
}
});

View File

@@ -0,0 +1,324 @@
var zombie_execute_button_text = 'Execute'
var zombie_reexecute_button_text = 'Re-execute'
var re_execute_command_title = 'Re-execute command'
/**
* Generates fields for the form used to send command modules.
*
* @param: {Object} the form to generate the field in.
* @param: {String/Object} the field name or it's definition as an object.
* @param: {String} the value that field should have.
* @param: {Boolean} set to true if you want the field to be disabled.
* @param: {Object} the targeted Zombie.
* @param: {Object} the status bar.
*/
function genExploitFormControl(form, input, value, disabled, zombie, sb) {
var input_name;
var input_type = 'TextField';
if(typeof input == 'string') {
input_name = input;
var field = new Ext.form.TextField({
id: 'form-zombie-'+zombie.session+'-field-'+input_name,
fieldLabel: input_name,
name: 'txt_'+input_name,
width: 175,
allowBlank:false
});
if(value) field.setValue(value);
if(disabled) field.setDisabled(true);
form.add(field);
}
else if(typeof input == 'object') {
var field = null, input_def;
if(typeof input[0] == 'object') input = input[0];
if (!input['name']) return;
if (!input['ui_label']) input['ui_label'] = input['name'];
if (!input['type']) input['type'] = 'textfield';
if (!input['value']) input['value'] = '';
input_id = 'form-zombie-'+zombie.session+'-field-'+input['name'];
input_def = {id: input_id, name: 'txt_'+input['name'], fieldLabel: input['ui_label'], allowBlank:false, value: input['value']};
switch(input['type'].toLowerCase()) {
case 'textarea':
field = new Ext.form.TextArea(input_def);
break;
case 'hidden':
field = new Ext.form.Hidden(input_def);
break;
default:
field = new Ext.form.TextField(input_def);
break;
}
for(definition in input) {
if(input[definition] && (typeof input[definition] == 'string') && (definition != 'type')
&& (definition != 'name')) {
field[definition] = input[definition];
}
}
if(value) field.setValue(value);
if(disabled) field.setDisabled(true);
form.add(field);
} else {
return;
}
};
/**
* Generate a panel for an command module that already has been executed.
*
* @param: {Object} the Panel in the UI to generate the form into.
* @param: {Integer} the command id to generate the panel for.
* @param: {Object} the targeted Zombie.
* @param: {Object} the status bar.
*/
function genExisingExploitPanel(panel, command_id, zombie, sb) {
if(typeof panel != 'object') {
Ext.beef.msg('Bad!', 'Incorrect panel chosen.');
return;
}
sb.showBusy(); // status bar update
panel.removeAll();
Ext.Ajax.request({
url:'/ui/modules/select/command.json?command_id='+command_id,
loadMask: true,
success: function(resp) {
var xhr = Ext.decode(resp.responseText);
if(!xhr || !xhr.definition) {
Ext.beef.msg('Error!', 'We could not retrieve the definition of that command module...');
return;
}
if(xhr.command_module_name == 'some specific command module') {
//HERE we will develop specific panels for the command modules that require it.
return;
}
var form = new Ext.form.FormPanel({
url: '/ui/modules/commandmodule/reexecute',
id: 'form-command-module-zombie-'+zombie.session,
border: false,
labelWidth: 75,
defaultType: 'textfield',
title: re_execute_command_title,
bodyStyle: 'padding: 5px;',
items: [new Ext.form.Hidden({name: 'command_id', value: command_id})],
buttons:[{
text: zombie_reexecute_button_text,
handler: function() {
var form = Ext.getCmp('form-command-module-zombie-'+zombie.session);
if(!form || !form.getForm().isValid()) return;
sb.update_sending('Sending commands to ' + zombie.ip + '...'); // status bar update
var command_module_form = form.getForm(); // form to be submitted when execute button is pressed on an command module tab
command_module_form.submit({
params: { // insert the nonce with the form
nonce: Ext.get ("nonce").dom.value
},
success: function() {
sb.update_sent("Commands sent to zombie " + zombie.ip); // status bar update
},
failure: function() {
sb.update_fail("Error!"); // status bar update
}
});
}
}]
});
Ext.each(xhr.definition.Data, function(input) {
var value;
if(typeof input == 'string') {
value = xhr.data[input];
}
if(typeof input == 'object' && typeof input[0] == 'object') {
value = xhr.data[input[0]['name']]
}
genExploitFormControl(form, input, value, false, zombie, sb);
});
var grid_store = new Ext.data.JsonStore({
url: '/ui/modules/select/command_results.json?command_id='+command_id,
storeId: 'command-results-store-zombie-'+zombie.session,
root: 'results',
remoteSort: false,
autoDestroy: true,
fields: [
{name: 'date', type: 'date', dateFormat: 'timestamp'},
{name: 'data'}
]
});
Ext.TaskMgr.start({
run: function(task) {
var grid = Ext.getCmp('command-results-grid-zombie-'+zombie.session);
//here we have to check for the existance of the grid before reloading
//because we do not want to reload the store if the tab has been closed.
if(grid_store && grid) {
grid_store.reload();
}
},
interval: 4000
});
var grid = new Ext.grid.GridPanel({
id: 'command-results-grid-zombie-'+zombie.session,
store: grid_store,
border: false,
hideHeaders: true,
title: 'Command results',
viewConfig: {
forceFit:true
},
columns:[new Ext.grid.RowNumberer({width: 20}), {
dataIndex: 'date',
sortable: false,
renderer: function(value, p, record) {
html = String.format("<div style='color:#385F95;text-align:right;'>{0}</div>", value);
html += '<p>';
for(index in record.data.data) {
result = record.data.data[index];
index = index.toString().replace('_', ' ');
html += String.format('<b>{0}</b>: {1}<br>', index, result);
}
html += '</p>';
return html;
}
}]
});
grid.store.load();
var accordion = new Ext.Panel({
id: 'command-results-accordion-zombie-'+zombie.session,
layout:'accordion',
border: false,
items: [grid, form]
});
panel.add(accordion);
panel.doLayout();
sb.update_ready(); // status bar update
}
});
};
/**
* Generate a panel for an command module.
*
* @param: {Object} the Panel in the UI to generate the form into.
* @param: {String} the path to the command module file in the framework.
* @param: {String} the name of the command module.
* @param: {Object} the targeted Zombie.
* @param: {Object} the status bar.
*/
function genNewExploitPanel(panel, command_module_id, command_module_name, zombie, sb) {
if(typeof panel != 'object') {
Ext.beef.msg('Bad!', 'Incorrect panel chosen.');
return;
}
var xgrid = Ext.getCmp('command-module-grid-zombie-'+zombie.session);
var sb = Ext.getCmp('commands-bbar-zombie-'+zombie.session);
if(command_module_name == 'some special command module') {
//HERE we will develop specific panels for the command modules that require it.
} else {
Ext.Ajax.request({
loadMask: true,
url: '/ui/modules/select/commandmodule.json?command_module_id='+command_module_id,
success: function(resp) {
var module = Ext.decode(resp.responseText);
if(!module) {
Ext.beef.msg('Error!', 'We could not retrieve the definition of that command_module...');
return;
}
module = module.command_modules[1];
panel.removeAll();
var form = new Ext.form.FormPanel({
url: '/ui/modules/commandmodule/new',
id: 'form-command-module-zombie-'+zombie.session,
border: false,
labelWidth: 75,
defaultType: 'textfield',
title: module.Name,
bodyStyle: 'padding: 5px;',
items: [
new Ext.form.Hidden({name: 'zombie_session', value: zombie.session}),
new Ext.form.Hidden({name: 'command_module_id', value: command_module_id}),
new Ext.form.DisplayField({
name: 'command_module_description',
fieldLabel: 'Description',
fieldClass: 'command-module-panel-description',
value: module.Description
})
],
buttons:[{
text: zombie_execute_button_text,
handler: function() {
var form = Ext.getCmp('form-command-module-zombie-'+zombie.session), command_module_params = new Array();
if(!form || !form.getForm().isValid()) return;
sb.update_sending('Sending commands to ' + zombie.ip + '...'); // status bar update
var command_module_form = form.getForm(); // form to be submitted when execute button is pressed on an command module tab
command_module_form.submit({
params: { // insert the nonce with the form
nonce: Ext.get ("nonce").dom.value
},
success: function() {
xgrid.i = 0;
xgrid.store.reload({ //reload the command module grid
params: { // insert the nonce with the request to reload the grid
nonce: Ext.get ("nonce").dom.value
}
});
sb.update_sent("Commands sent to zombie " + zombie.ip); // status bar update
},
failure: function() {
sb.update_fail("Error!"); // status bar update
}
});
}
}]
});
Ext.each(module.Data, function(input){genExploitFormControl(form, input, null, false, zombie, sb)});
panel.add(form);
panel.doLayout();
}
});
}
};

View File

@@ -0,0 +1,129 @@
/*
* The command tab panel. Listing the list of commands sent to the zombie.
* Loaded in /ui/panel/index.html
*/
ZombieTab_Commands = function(zombie) {
var command_module_config = new Ext.Panel({
id: 'zombie-command-module-config-'+zombie.session,
region: 'center',
border: false,
layout: 'fit',
html: "<div class='x-grid-empty'>Please select an command module in the command module tree on the left</div>"
});
var command_module_grid = new Ext.grid.GridPanel({
store: new Ext.data.JsonStore({
url: '/ui/modules/commandmodule/commands.json',
params: { // insert the nonce with the form
nonce: Ext.get ("nonce").dom.value
},
autoDestroy: false,
autoLoad: false,
root: 'commands',
fields: ['label', 'creationdate', 'id', 'object_id'],
sortInfo: {field: 'id', direction: 'ASC'}
}),
id: 'command-module-grid-zombie-'+zombie.session,
sortable: true,
autoWidth: false,
region: 'west',
stripeRows: true,
autoScroll: true,
border: false,
width: 260,
bodyStyle: 'border-right: 1px solid #99BBE8; border-left: 1px solid #99BBE8;',
i:0,
view: new Ext.grid.GridView({
forceFit: true,
emptyText: "No Command found",
enableRowBody:true
}),
columns: [
{header: 'id', width: 35, sortable: true, dataIndex: 'id'},
{header: 'date', width: 100, sortable: true, dataIndex: 'creationdate'},
{header: 'label', sortable: true, dataIndex: 'label', renderer: function(value) { if(value==null) {command_module_grid.i +=1; return 'command '+command_module_grid.i;} else return value;}},
{header: 'object_id', sortable: true, dataIndex: 'object_id', hidden: true, menuDisabled: true}
]
});
command_module_grid.on('rowclick', function(grid, rowIndex, e) {
var r = grid.getStore().getAt(rowIndex).data;
var command_id = r.object_id || null;
if(!command_id) return;
genExisingExploitPanel(command_module_config, command_id, zombie, commands_statusbar);
});
var command_module_tree = new Ext.tree.TreePanel({
border: false,
region: 'west',
width: 190,
useArrows: true,
autoScroll: true,
animate: true,
containerScroll: true,
rootVisible: false,
root: {nodeType: 'async'},
loader: new Ext.tree.TreeLoader({
dataUrl: '/ui/modules/select/commandmodules/tree.json',
baseParams: {zombie_session: zombie.session}
}),
listeners: {
'click': function(node) {
if(!node.leaf) return;
commands_statusbar.showBusy('Loading ' + node.text);
command_module_grid.i = 0;
command_module_grid.store.baseParams = {command_module_id: node.attributes.id, zombie_session: zombie.session};
command_module_grid.store.reload({ //reload the command module grid
params: { // insert the nonce with the request to reload the grid
nonce: Ext.get ("nonce").dom.value
}
});
genNewExploitPanel(command_module_config, node.id, node.text, zombie, commands_statusbar);
commands_statusbar.showValid('Ready');
},
'afterrender' : function() {
}
}
});
var commands_statusbar = new Beef_StatusBar(zombie.session);
ZombieTab_Commands.superclass.constructor.call(this, {
id: 'zombie-'+zombie.session+'-command-module-panel',
title:'Commands',
layout: 'fit',
region: 'center',
autScroll: true,
items: {
layout: 'border',
border: false,
items: [command_module_tree,
new Ext.Panel({
id: 'zombie-command-module-west-'+zombie.session,
region: 'center',
layout: 'fit',
border: false,
items: {
layout: 'border',
border: false,
items: [command_module_grid, command_module_config]
}
})]
},
bbar: commands_statusbar
});
var sb = Ext.getCmp('command-module-bbar-zombie-'+zombie.session);
};
Ext.extend(ZombieTab_Commands, Ext.Panel, {});

View File

@@ -0,0 +1,22 @@
/*
* The log Tab panel for the selected zombie.
*/
ZombieTab_LogTab = function(zombie) {
var zombieLog = new DataGrid('/ui/logs/zombie.json',25,{session:zombie.session});
zombieLog.border = false;
ZombieTab_LogTab.superclass.constructor.call(this, {
id: 'zombie-log-tab' + zombie.session,
layout: 'fit',
title: 'Logs',
items: {
layout: 'border',
border: false,
items:[zombieLog]
}
});
};
Ext.extend(ZombieTab_LogTab, Ext.Panel, {} );

View File

@@ -0,0 +1,83 @@
/*
* The main Tab panel for the selected zombie.
*/
ZombieTab_MainTab = function(zombie) {
var store_summary = new Ext.data.GroupingStore({
url: '/ui/modules/select/zombie_summary.json',
baseParams: {zombie_session: zombie.session} ,
reader: new Ext.data.JsonReader({
root: 'results'
},[
{name: 'data'},
{name: 'category'},
{name: 'from'}
]),
autoLoad: true,
sortInfo:{field: 'from', direction: "ASC"},
groupField:'category'
});
var grid_summary = new Ext.grid.GridPanel({
store: store_summary,
border: false,
region: 'center',
layout: 'fit',
hideHeaders: true,
view: new Ext.grid.GroupingView({
forceFit:true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})',
emptyText: "No Record found: this tab gets populated after you've ran some command modules.",
enableRowBody:true
}),
viewConfig: {
forceFit:true
},
columns:[
{
header: 'information',
dataIndex: 'data',
renderer: function(value, p, record) {
html = ''
for(index in value) {
result = value[index];
index = index.toString().replace('_', ' ');
html += String.format('<b>{0}</b>: {1}<br>', index, result);
}
return html;
}
},
{header: 'command_module', dataIndex:'from', width: 25, renderer: function(value){return value;}},
{header: 'Category', dataIndex:'category', hidden: true, renderer: function(value){return value;}}
]
});
ZombieTab_MainTab.superclass.constructor.call(this, {
id: 'zombie-main-tab'+zombie.session,
layout: 'fit',
title: 'Main',
items: {
layout:'border',
border: false,
items:[grid_summary]
},
listeners:{
activate : function(maintab){
maintab.items.items[0].items.items[0].store.reload();
}
}
});
};
Ext.extend(ZombieTab_MainTab, Ext.Panel, {});

View File

@@ -0,0 +1,237 @@
/*
* The request Tab panel for the selected zombie.
* Loaded in /ui/panel/index.html
*/
ZombieTab_Requester = function(zombie) {
// The status bar.
var commands_statusbar = new Beef_StatusBar('requester-bbar-zombie-'+zombie.session);
/*
* The panel used to forge raw HTTP requests.
********************************************/
var requests_panel = new Ext.Panel({
id: 'requester-forge-requests-zombie-'+zombie.session,
title: 'Forge Request',
layout: 'fit'
});
/*
* The panel that displays the history of all requests performed.
********************************************/
var history_panel_store = new Ext.data.JsonStore({
storeId: 'requester-history-store-zombie-'+zombie.session,
url: '/ui/requester/history.json',
remoteSort: false,
autoDestroy: true,
root: 'history',
fields: ['domain', 'date', 'id', 'has_ran', 'path'],
sortInfo: {field: 'date', direction: 'DESC'},
baseParams: {
nonce: Ext.get("nonce").dom.value,
zombie_session: zombie.session
}
});
var history_panel_grid = new Ext.grid.GridPanel({
id: 'requester-history-grid-zombie-'+zombie.session,
store: history_panel_store,
border: false,
loadMask: {msg:'Loading History...'},
viewConfig: {
forceFit:true
},
view: new Ext.grid.GridView({
forceFit: true,
emptyText: "No History",
enableRowBody:true
}),
columns: [
{header: 'id', width: 10, sortable: true, dataIndex: 'id', hidden: true},
{header: 'domain', sortable: true, dataIndex: 'domain'},
{header: 'path', sortable: true, dataIndex: 'path'},
{header: 'response', width: 20, sortable: true, dataIndex: 'has_ran'},
{header: 'date', width: 50, sortable: true, dataIndex: 'date'}
],
listeners: {
rowclick: function(grid, rowIndex) {
var tab_panel = Ext.getCmp('zombie-requester-tab-zombie-'+zombie.session);
var r = grid.getStore().getAt(rowIndex).data;
if(!r.has_ran) {
commands_statusbar.update_fail("Response for this request has not been received yet.");
return;
}
if(!tab_panel.get('requester-response-'+r.id)) {
genResultTab(r, zombie, commands_statusbar);
}
}
}
});
var history_panel = new Ext.Panel({
id: 'requester-history-panel-zombie-'+zombie.session,
title: 'History',
items:[history_panel_grid],
layout: 'fit',
listeners: {
activate: function(history_panel) {
history_panel.items.items[0].store.reload();
}
}
});
// Function generating the requests panel to send raw requests
//-------------------------------------------------------------
function genRawRequestPanel(zombie, bar, value) {
var form = new Ext.FormPanel({
title: 'Forge Raw HTTP Request',
id: 'requester-request-form-zombie'+zombie.session,
url: '/ui/requester/send',
hideLabels : true,
border: false,
padding: '3px 5px 0 5px',
items:[{
xtype: 'textarea',
id: 'raw-request-zombie-'+zombie.session,
name: 'raw_request',
width: '100%',
height: '100%',
allowBlank: false
}],
buttons: [{
text: 'Send',
handler: function() {
var form = Ext.getCmp('requester-request-form-zombie'+zombie.session).getForm();
bar.update_sending('Sending request to ' + zombie.ip + '...');
form.submit({
params: {
nonce: Ext.get("nonce").dom.value,//insert the nonce with the form
zombie_session: zombie.session
},
success: function() {
bar.update_sent("Request sent to hooked browser " + zombie.ip);
},
failure: function() {
bar.update_fail("Error! Invalid http request.");
}
});
}
}]
});
if(!value) {
value = "GET /demos/secret_page.html HTTP/1.1\n";
if(zombie.domain) {
value += "Host: "+zombie.domain.split(':')[0]+"\n";
} else {
value += "Host: \n";
}
}
form.get('raw-request-zombie-'+zombie.session).value = value;
panel = Ext.getCmp('requester-forge-requests-zombie-'+zombie.session);
panel.setTitle('Forge Request');
panel.add(form);
};
// Function generating the panel that shows the results of a request
// This function is called when the user clicks on a row in the grid
// showing the results in the history.
//------------------------------------------------------------------
function genResultTab(request, zombie, bar) {
var tab_panel = Ext.getCmp('zombie-requester-tab-zombie-'+zombie.session);
bar.update_sending('Getting response...');
Ext.Ajax.request({
url: '/ui/requester/response.json',
loadMask: true,
params: {
nonce: Ext.get("nonce").dom.value,
http_id: request.id
},
success: function(response) {
var xhr = Ext.decode(response.responseText);
var tab_result_response = new Ext.Panel({
title: 'Reponse',
border: false,
layout: 'fit',
padding: '5px 5px 5px 5px',
items:[new Ext.form.TextArea({id: 'requester-response-res-'+request.id, value: xhr.result.response})]
});
var tab_result_request = new Ext.Panel({
title: 'Request',
border: false,
layout: 'fit',
padding: '5px 5px 5px 5px',
items:[new Ext.form.TextArea({id: 'requester-response-req-'+request.id, value: xhr.result.request})]
});
var tab_result_accordion = new Ext.Panel({
id: 'requester-response-'+request.id,
title: request.path,
split: true,
border: false,
layout:'accordion',
closable: true,
items:[tab_result_response, tab_result_request]
});
tab_panel.add(tab_result_accordion);
tab_panel.activate(tab_result_accordion.id);
bar.update_sent("Displaying response.");
},
failure: function() {
bar.update_fail("Error! Could you retrieve the response.");
}
});
};
ZombieTab_Requester.superclass.constructor.call(this, {
id: 'zombie-requester-tab-zombie-'+zombie.session,
title: 'Requester',
activeTab: 0,
viewConfig: {
forceFit: true,
type: 'fit'
},
items: [history_panel, requests_panel],
bbar: commands_statusbar,
listeners: {
afterrender : function(){
genRawRequestPanel(zombie, commands_statusbar);
}
}
});
};
Ext.extend(ZombieTab_Requester, Ext.TabPanel, {});