Support added to retrieve msf payload options and display them in the UI.
git-svn-id: https://beef.googlecode.com/svn/trunk@694 b87d56ec-f9c0-11de-8c8a-61c5e9addfc9
This commit is contained in:
@@ -27,17 +27,20 @@ class Msf < BeEF::Command
|
||||
save({'result' => @datastore['result']})
|
||||
end
|
||||
|
||||
#
|
||||
def update_info(id)
|
||||
mod = BeEF::Models::CommandModule.first(:id => id)
|
||||
msfinfo = nil
|
||||
targets = []
|
||||
|
||||
|
||||
if mod.dynamic_command_info == nil
|
||||
|
||||
msf = BeEF::MsfClient.new
|
||||
msf.login()
|
||||
msfinfo = msf.get_exploit_info(mod.name)
|
||||
|
||||
st = mod.name.split('/').first
|
||||
puts "st: " + st
|
||||
|
||||
os_name = BeEF::Constants::Os::match_os(st)
|
||||
browsers = BeEF::Constants::Browsers::match_browser(msfi['name'] + msfi['targets'].to_json)
|
||||
@@ -48,7 +51,6 @@ class Msf < BeEF::Command
|
||||
targets << {'os_name' => os_name, 'browser_name' => bn}
|
||||
end
|
||||
|
||||
|
||||
mod.dynamic_command_info = BeEF::Models::DynamicCommandInfo.new(
|
||||
:name => msfinfo['name'],
|
||||
:description => msfinfo['description'],
|
||||
@@ -63,7 +65,6 @@ class Msf < BeEF::Command
|
||||
@info['MsfModName'] = mod.name
|
||||
@target = targets
|
||||
|
||||
|
||||
end
|
||||
def update_data()
|
||||
modname = @info['MsfModName']
|
||||
@@ -106,11 +107,46 @@ class Msf < BeEF::Command
|
||||
'displayField' => 'payload' ,
|
||||
'autoWidth' => true,
|
||||
'mode' => 'local',
|
||||
'reloadOnChange' => true,
|
||||
'emptyText' => "select a payload..."]
|
||||
|
||||
|
||||
end
|
||||
|
||||
def get_payload_options(payload_name)
|
||||
# get payload options from metasploit
|
||||
msf_xmlrpc_clinet = BeEF::MsfClient.new()
|
||||
msf_xmlrpc_clinet.login()
|
||||
payload_options = msf_xmlrpc_clinet.payload_options(payload_name)
|
||||
|
||||
info = {}
|
||||
info['Data'] = []
|
||||
|
||||
payload_options.keys.each { |k|
|
||||
next if payload_options[k]['advanced'] == true
|
||||
next if payload_options[k]['evasion'] == true
|
||||
info['Data'] << [ 'name' => k + '_txt', 'type' => 'label', 'html' => payload_options[k]['desc']]
|
||||
case payload_options[k]['type']
|
||||
when "string","address","port","raw","path"
|
||||
info['Data'] << ['name' => k , 'ui_label' => k, 'value' => payload_options[k]['default']]
|
||||
when "bool"
|
||||
info['Data'] << ['name' => k, 'type' => 'checkbox', 'ui_label' => k ]
|
||||
when "enum"
|
||||
info['Data'] << [ 'name' => k, 'type' => 'combobox', 'ui_label' => k, 'store_type' => 'arraystore', 'store_fields' => ['enum'], 'store_data' => payload_options[k]['enums'], 'valueField' => 'enum', 'displayField' => 'enum' , 'autoWidth' => true, 'mode' => 'local', 'value' => payload_options[k]['default']]
|
||||
else
|
||||
# Debug output if the payload option type isn't found
|
||||
puts "K => #{k}\n"
|
||||
puts "Status => #{payload_options[k]['advanced']}\n"
|
||||
puts "Type => #{payload_options[k]['type']}\n"
|
||||
puts payload_options[k]
|
||||
end
|
||||
}
|
||||
|
||||
# turn results into JSON
|
||||
payload_options_json = []
|
||||
payload_options_json[1] = JSON.parse(info.to_json)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -118,16 +154,4 @@ end
|
||||
end
|
||||
end
|
||||
|
||||
#@info = info
|
||||
#@datastore = @info['Data'] || nil
|
||||
#@friendlyname = @info['Name'] || nil
|
||||
#@target = @info['Target'] || nil
|
||||
#@output = ''
|
||||
#@path = @info['File'].sub(BeEF::HttpHookServer.instance.root_dir, '')
|
||||
#@default_command_url = '/command/'+(File.basename @path, '.rb')+'.js'
|
||||
#@id = BeEF::Models::CommandModule.first(:path => @info['File']).object_id
|
||||
#@use_template = false
|
||||
#@auto_update_zombie = false
|
||||
#@results = {}
|
||||
#@beefjs_components = {}
|
||||
|
||||
|
||||
@@ -280,8 +280,16 @@ class Modules < BeEF::HttpController
|
||||
# get the command_module path
|
||||
absolute_command_module_path = get_command_module_path(command_module_id)
|
||||
|
||||
# check if the request relates to a dynamic module
|
||||
if(absolute_command_module_path.match(/^Dynamic/))
|
||||
@body = dynamic_modules2json(command_module_id);
|
||||
# get command_module id
|
||||
payload_name = @params['payload_name'] || nil
|
||||
|
||||
if not payload_name.nil?
|
||||
@body = dynamic_payload2json(command_module_id, payload_name)
|
||||
else
|
||||
@body = dynamic_modules2json(command_module_id);
|
||||
end
|
||||
else
|
||||
@body = command_modules2json([absolute_command_module_path]);
|
||||
end
|
||||
@@ -455,13 +463,18 @@ class Modules < BeEF::HttpController
|
||||
end
|
||||
end
|
||||
|
||||
# return the input requred for the module in JSON format
|
||||
def dynamic_modules2json(id)
|
||||
command_modules_json = {}
|
||||
|
||||
|
||||
mod = BeEF::Models::CommandModule.first(:id => id)
|
||||
|
||||
# if the module id is not in the database return false
|
||||
return {'success' => 'false'}.to_json if(not mod)
|
||||
|
||||
# the path will equal Dynamic/<type> and this will get just the type
|
||||
dynamic_type = mod.path.split("/").last
|
||||
|
||||
e = BeEF::Modules::Commands.const_get(dynamic_type.capitalize).new
|
||||
e.update_info(mod.id)
|
||||
e.update_data()
|
||||
@@ -473,6 +486,24 @@ class Modules < BeEF::HttpController
|
||||
end
|
||||
end
|
||||
|
||||
def dynamic_payload2json(id, payload_name)
|
||||
command_modules_json = {}
|
||||
|
||||
dynamic_command_module = BeEF::Models::CommandModule.first(:id => id)
|
||||
raise WEBrick::HTTPStatus::BadRequest, "Module does not exists" if dynamic_command_module.nil?
|
||||
|
||||
# the path will equal Dynamic/<type> and this will get just the type
|
||||
dynamic_type = dynamic_command_module.path.split("/").last
|
||||
|
||||
# get payload options in JSON
|
||||
e = BeEF::Modules::Commands.const_get(dynamic_type.capitalize).new
|
||||
payload_options_json = []
|
||||
payload_options_json[1] = e.get_payload_options(payload_name)
|
||||
raise WEBrick::HTTPStatus::BadRequest, "Payload JSON generation error" if payload_options_json.empty?
|
||||
|
||||
return {'success' => 'true', 'command_modules' => payload_options_json}.to_json
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -68,16 +68,23 @@ function genExploitFormControl(form, input, value, disabled, zombie, sb) {
|
||||
break;
|
||||
case 'combobox':
|
||||
input_def['triggerAction'] = 'all';
|
||||
field = new Ext.form.ComboBox(input_def);
|
||||
|
||||
if(input.reloadOnChange) {
|
||||
Ext.getCmp("payload-panel").show();
|
||||
input_def['listeners'] = {
|
||||
'select': function(combo, value) {
|
||||
get_metasploit_payload_details(combo.getValue(), zombie, sb);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
switch(input['store_type'].toLowerCase()){
|
||||
case 'arraystore':
|
||||
field['store'] = new Ext.data.ArrayStore( {
|
||||
fields: input['store_fields'],
|
||||
data: input['store_data']
|
||||
});
|
||||
break;
|
||||
}
|
||||
input_def['store'] = new Ext.data.ArrayStore( {
|
||||
fields: input['store_fields'],
|
||||
data: input['store_data']
|
||||
});
|
||||
|
||||
field = new Ext.form.ComboBox(input_def);
|
||||
|
||||
break;
|
||||
default:
|
||||
field = new Ext.form.TextField(input_def);
|
||||
@@ -101,6 +108,26 @@ function genExploitFormControl(form, input, value, disabled, zombie, sb) {
|
||||
}
|
||||
};
|
||||
|
||||
function get_metasploit_payload_details(payload, zombie, sb) {
|
||||
|
||||
Ext.Ajax.request({
|
||||
loadMask: true,
|
||||
url: '/ui/modules/select/commandmodule.json',
|
||||
method: 'POST',
|
||||
params: 'command_module_id=' + '29' + '&' + 'payload_name=' + payload,
|
||||
success: function(resp) {
|
||||
var module = Ext.decode(resp.responseText);
|
||||
module = module.command_modules[1];
|
||||
|
||||
Ext.getCmp("payload-panel").removeAll();
|
||||
Ext.each(module.Data, function(input){genExploitFormControl(Ext.getCmp("payload-panel"), input, null, false, zombie, sb)});
|
||||
|
||||
Ext.getCmp("payload-panel").doLayout();
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a panel for an command module that already has been executed.
|
||||
*
|
||||
@@ -319,11 +346,16 @@ function genNewExploitPanel(panel, command_module_id, command_module_name, zombi
|
||||
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;
|
||||
|
||||
if(!form || !form.getForm().isValid()) {
|
||||
console.log("TODO: Update status bar with message to complete the form")
|
||||
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
|
||||
@@ -333,7 +365,7 @@ function genNewExploitPanel(panel, command_module_id, command_module_name, zombi
|
||||
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
|
||||
},
|
||||
@@ -345,8 +377,20 @@ function genNewExploitPanel(panel, command_module_id, command_module_name, zombi
|
||||
}]
|
||||
});
|
||||
|
||||
// create the panel and hide it
|
||||
var payload_panel = new Ext.Panel({
|
||||
id: 'payload-panel', // used with Ext.GetCmp('payload-panel')
|
||||
bodyStyle: 'padding:10px;', // we can assign styles to the main div
|
||||
bodyBorder: false,
|
||||
height:200,
|
||||
border: false //we can remove the border of the panel
|
||||
});
|
||||
payload_panel.hide();
|
||||
|
||||
Ext.each(module.Data, function(input){genExploitFormControl(form, input, null, false, zombie, sb)});
|
||||
|
||||
form.add(payload_panel);
|
||||
|
||||
panel.add(form);
|
||||
panel.doLayout();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user