Issue 384: First draft of XssRays (admin UI): extjs UI

git-svn-id: https://beef.googlecode.com/svn/trunk@1113 b87d56ec-f9c0-11de-8c8a-61c5e9addfc9
This commit is contained in:
antisnatchor
2011-07-26 18:35:46 +00:00
parent 83463fcaa7
commit a14fe4ba0a
7 changed files with 247 additions and 7 deletions

View File

@@ -20,6 +20,7 @@
<%= script_tag 'ui/panel/tabs/ZombieTabLogs.js' %>
<%= script_tag 'ui/panel/tabs/ZombieTabCommands.js' %>
<%= script_tag 'ui/panel/tabs/ZombieTabRequester.js' %>
<%= script_tag 'ui/panel/tabs/ZombieTabXssRays.js' %>
<%= script_tag 'ui/panel/PanelViewer.js' %>
<%= script_tag 'ui/panel/DataGrid.js' %>

View File

@@ -0,0 +1,113 @@
#
# Copyright 2011 Wade Alcorn wade@bindshell.net
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
module BeEF
module Extension
module AdminUI
module Controllers
class Xssrays < BeEF::Extension::AdminUI::HttpController
HB = BeEF::Core::Models::HookedBrowser
XS = BeEF::Core::Models::Xssraysscan
XD = BeEF::Core::Models::Xssraysdetail
def initialize
super({
'paths' => {
'/set_scan_target' => method(:set_scan_target),
'/zombie.json' => method(:get_xssrays_logs),
'/rays' => method(:parse_rays)
}
})
end
# called by the UI when rendering xssrays_details table content in the XssRays zombie tab
def get_xssrays_logs
# validate nonce
nonce = @params['nonce'] || nil
raise WEBrick::HTTPStatus::BadRequest, "nonce is nil" if nonce.nil?
raise WEBrick::HTTPStatus::BadRequest, "nonce incorrect" if @session.get_nonce != nonce
# validate that the hooked browser's session has been sent
zombie_session = @params['zombie_session'] || nil
raise WEBrick::HTTPStatus::BadRequest, "Zombie session is nil" if zombie_session.nil?
# validate that the hooked browser exists in the db
zombie = Z.first(:session => zombie_session) || nil
raise WEBrick::HTTPStatus::BadRequest, "Invalid hooked browser session" if zombie.nil?
logs = []
BeEF::Core::Models::Xssraysdetail.all(:hooked_browser_id => zombie.id).each{|log|
logs << {
'id' => log.id,
'vector_method' => log.vector_method,
'vector_name' => log.vector_name,
'vector_poc' => log.vector_poc
}
}
@body = {'success' => 'true', 'logs' => logs}.to_json
end
# called by the UI. needed to pass the hooked browser ID/session and store a new scan in the DB
def set_scan_target
hooked_browser = HB.first(:session => @params['hb_id'].to_s)
if(hooked_browser != nil)
hooked_browser.update(:start_xssrays => true)
xssrays_scan = XS.new(
:hooked_browser_id => hooked_browser.id,
:scan_start => Time.now,
:domain => hooked_browser.domain,
:same_origin => false #check also cross-domain URIs found by the spider
)
xssrays_scan.save
print_info("[XSSRAYS] Starting XSSRays on HB with ip [#{hooked_browser.ip.to_s}], hooked on domain [#{hooked_browser.domain.to_s}]")
end
end
# parse incoming rays: rays are veryfied XSS, as the attack vector is calling back BeEF when executed.
def parse_rays
print_debug("[XSSRAYS] Received ray: \n #{@params.to_s}")
hooked_browser = HB.first(:session => @params['hbsess'].to_s)
if(hooked_browser != nil)
xssrays_scan = XS.first(:id => @params['raysscanid'])
if(xssrays_scan != nil)
xssrays_detail = XD.new(
:hooked_browser_id => hooked_browser.id,
:vector_name => @params['name'],
:vector_method => @params['method'],
:vector_poc => @params['poc'],
:scan_id => xssrays_scan.id
)
xssrays_detail.save
end
print_info("[XSSRAYS] Received ray from HB with ip [#{hooked_browser.ip.to_s}], hooked on domain [#{hooked_browser.domain.to_s}]")
end
end
end
end
end
end
end

View File

@@ -74,6 +74,10 @@
background-image: url(../images/icons/proxy.gif);
}
.zombie-tree-ctxMenu-xssrays {
background-image: url(../images/icons/xssrays.png);
}
.x-tree-node-leaf .x-tree-node-icon {
width: 13px;
height: 13px;

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

View File

@@ -19,6 +19,7 @@ ZombieTab = function(zombie) {
log_tab = new ZombieTab_LogTab(zombie);
commands_tab = new ZombieTab_Commands(zombie);
requester_tab = new ZombieTab_Requester(zombie);
xssrays_tab = new ZombieTab_XssRaysTab(zombie);
//-------------------------------------------
ZombieTab.superclass.constructor.call(this, {
@@ -32,7 +33,7 @@ ZombieTab = function(zombie) {
forceFit: true,
type: 'fit'
},
items:[main_tab, log_tab, commands_tab, requester_tab]
items:[main_tab, log_tab, commands_tab, requester_tab, xssrays_tab]
});
};

View File

@@ -0,0 +1,109 @@
//
// Copyright 2011 Wade Alcorn wade@bindshell.net
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/*
* The XssRays Tab panel for the selected zombie.
*/
//TODO: fix positioning issues, probably because we are not creating a nested (fucking) panel
ZombieTab_XssRaysTab = function(zombie) {
var commands_statusbar = new Beef_StatusBar('xssrays-bbar-zombie-'+zombie.session);
var req_pagesize = 30;
var xssrays_logs_store = new Ext.ux.data.PagingJsonStore({
storeId: 'xssrays-logs-store-zombie-' + zombie.session,
url: '/ui/xssrays/zombie.json',
remoteSort: false,
autoDestroy: true,
autoLoad: false,
root: 'logs',
fields: ['id', 'vector_method', 'vector_name', 'vector_poc'],
sortInfo: {field: 'id', direction: 'DESC'},
baseParams: {
nonce: Ext.get("nonce").dom.value,
zombie_session: zombie.session
}
});
var xssrays_logs_bbar = new Ext.PagingToolbar({
pageSize: req_pagesize,
store: xssrays_logs_store,
displayInfo: true,
displayMsg: 'Displaying history {0} - {1} of {2}',
emptyMsg: 'No history to display'
});
var xssrays_logs_grid = new Ext.grid.GridPanel({
id: 'xssrays-logs-grid-zombie-' + zombie.session,
store: xssrays_logs_store,
bbar: xssrays_logs_bbar,
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: 'Vector Method', width: 30, sortable: true, dataIndex: 'vector_method'},
{header: 'Vector Name', width: 40, sortable: true, dataIndex: 'vector_name'},
{header: 'Vector PoC', sortable: true, dataIndex: 'vector_poc'}
],
listeners: {
afterrender: function(datagrid) {
datagrid.store.reload({params:{start:0,limit:req_pagesize, sort: "date", dir:"DESC"}});
}
}
});
var xssrays_logs_panel = new Ext.Panel({
id: 'xssrays-logs-panel-zombie-'+zombie.session,
title: 'Logs',
items:[xssrays_logs_grid],
layout: 'fit',
listeners: {
activate: function(xssrays_logs_panel) {
xssrays_logs_panel.items.items[0].store.reload();
}
}
});
ZombieTab_XssRaysTab.superclass.constructor.call(this, {
id: 'xssrays-log-tab-'+zombie.session,
title: 'XssRays',
activeTab: 0,
viewConfig: {
forceFit: true,
type: 'fit'
},
items: [xssrays_logs_panel],
bbar: commands_statusbar
});
};
Ext.extend(ZombieTab_XssRaysTab, Ext.Panel, {} );

View File

@@ -76,20 +76,32 @@ Ext.extend(zombiesTreeList, Ext.tree.TreePanel, {
//add a context menu that will contain common action shortcuts for HBs
contextMenu: new Ext.menu.Menu({
items: [{
id: 'use_as_proxy',
text: 'Use as Proxy',
iconCls: 'zombie-tree-ctxMenu-proxy'
}
id: 'use_as_proxy',
text: 'Use as Proxy',
iconCls: 'zombie-tree-ctxMenu-proxy'
},{
id: 'xssrays_hooked_domain',
text: 'Launch XssRays on Hooked Homain',
iconCls: 'zombie-tree-ctxMenu-xssrays'
}
],
listeners: {
itemclick: function(item, object) {
var hb_id = this.contextNode.id.split('zombie-online-')[1];
switch (item.id) {
case 'use_as_proxy':
var hb_id = this.contextNode.id.split('zombie-online-')[1];
Ext.Ajax.request({
url: '/ui/proxy/setTargetZombie',
method: 'POST',
params: 'hb_id=' + hb_id //,
params: 'hb_id=' + escape(hb_id)
});
break;
case 'xssrays_hooked_domain':
Ext.Ajax.request({
url: '/ui/xssrays/set_scan_target',
method: 'POST',
params: 'hb_id=' + escape(hb_id)
});
break;
}