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:
@@ -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' %>
|
||||
|
||||
113
extensions/admin_ui/controllers/xssrays/xssrays.rb
Normal file
113
extensions/admin_ui/controllers/xssrays/xssrays.rb
Normal 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
|
||||
@@ -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;
|
||||
|
||||
BIN
extensions/admin_ui/media/images/icons/xssrays.png
Normal file
BIN
extensions/admin_ui/media/images/icons/xssrays.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 865 B |
@@ -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]
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -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, {} );
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user