Changes to add error handling, graceful recovery, and better user feedback. Fixes #257

git-svn-id: https://beef.googlecode.com/svn/trunk@714 b87d56ec-f9c0-11de-8c8a-61c5e9addfc9
This commit is contained in:
sussurro@happypacket.net
2011-01-24 16:46:43 +00:00
parent 0e159f8bfe
commit 5b74c0ffe4
3 changed files with 60 additions and 23 deletions

View File

@@ -39,9 +39,8 @@ class Migration
end
end
msf = BeEF::MsfClient.new()
if(msf.is_enabled)
msf.login()
msf = BeEF::MsfClient.instance
if(msf.is_enabled && msf.login())
sploits = msf.browser_exploits()
sploits.each do |sploit|
if not BeEF::Models::CommandModule.first(:name => sploit)

View File

@@ -4,6 +4,7 @@ module BeEF
# XML RPC Client for Metasploit
#
class MsfClient < ::XMLRPC::Client
include Singleton
def initialize
@config = BeEF::Configuration.instance
@@ -16,14 +17,14 @@ module BeEF
@pw = @config.get('msf_pass')
if(not host or not path or not port or not @un or not @pw)
raise RuntimeError, "#{@enabled}:Insufficient information to initliaze Metasploit"
print "There is not enough information to initalize Metasploit connectivity at this time. Please check your options in config.ini to verify that all information is present\n"
@enabled = false
end
@token = nil
@lastauth = nil
super(host,path,port)
super(host,path,port)
end
@@ -36,7 +37,10 @@ module BeEF
# login into metasploit
def login
res = self.call("auth.login", @un ,@pw )
raise RuntimeError, "MSF Authentication failed" if(not (res and res['result'] == "success"))
if(not (res and res['result'] == "success"))
@enabled = false
return false
end
@token = res['token']
@lastauth = Time.now
@@ -46,50 +50,79 @@ module BeEF
# sends commands to the metasploit xml rpc server
def call(meth, *args)
return if not @enabled
if(meth != "auth.login")
raise RuntimeError, "client not authenticated" if(not @token)
self.login() if not @token
args.unshift(@token)
end
super(meth, *args)
begin
super(meth, *args)
rescue Errno::ECONNREFUSED
print "WARNING: Connection to Metasploit backend failed. This is typically because it is either not running your your connection information is incorrect, please verify this information and try again. Metasploit capabilities have been disabled until this is fixed\n"
@enabled = false
return false
rescue XMLRPC::FaultException => e
if e.faultCode == 401 and meth == "auth.login"
print "WARNING: Your username and password combination was rejected by the Metasploit backend server. Please verify your settings and restart the BeEF server. Metasploit connectivity has been disabled.\n"
@enabled = false
elsif e.faultCode == 401
res = self.login()
else
print "WARNING: An unknown exception has occured while talking to the Metasploit backend. The Exception text is (#{e.faultCode} : #{e.faultString}. Please check the Metasploit logs for more details.\n"
end
return false
rescue Exception => e
print "WARNING: An unknown exception (#{e}) has occured while talking to the Metasploit backend. Please check the Metasploit logs for more details.\n"
return false
end
end
def browser_exploits()
return if not @enabled
res = self.call('module.exploits')
raise RuntimeError, "Metasploit exploit retreval failed" if(not res['modules'])
return [] if not res or not res['modules']
mods = res['modules']
ret = []
mods.each do |m|
ret << m if(m.include? '/browser/')
end
ret.sort
end
def get_exploit_info(name)
return if not @enabled
res = self.call('module.info','exploit',name)
res
res || {}
end
def get_payloads(name)
return if not @enabled
res = self.call('module.compatible_payloads',name)
res
res || {}
end
def get_options(name)
return if not @enabled
res = self.call('module.options','exploit',name)
res
res || {}
end
def payloads()
return if not @enabled
res = self.call('module.payloads')
return {} if not res or not res['modules']
res['modules']
end
def payload_options(name)
begin
res = self.call('module.options','payload',name)
rescue Exception => e
return {}
end
return if not @enabled
res = self.call('module.options','payload',name)
return {} if not res
res
end
def launch_exploit(exploit,opts)
return if not @enabled
begin
res = self.call('module.execute','exploit',exploit,opts)
rescue Exception => e

View File

@@ -34,7 +34,7 @@ class Msf < BeEF::Command
if mod.dynamic_command_info == nil
msf = BeEF::MsfClient.new
msf = BeEF::MsfClient.instance
msf.login()
msfinfo = msf.get_exploit_info(mod.name)
@@ -70,9 +70,12 @@ class Msf < BeEF::Command
def update_data()
modname = @info['MsfModName']
msf = BeEF::MsfClient.new
msf.login()
msf = BeEF::MsfClient.instance
if not msf.is_enabled
@info['Description'] += "<BR>" + "*"*15 + "WARNING" + "*"*15 + "<BR>"
@info['Description'] += "Metasploit capapbilities have been disabled, please verify your configuration or if msf_enabled = 1 then check the BeEF console for errors"
return
end
msfoptions = msf.get_options(modname)
msfoptions.keys.each { |k|
next if msfoptions[k]['advanced'] == true
@@ -97,6 +100,8 @@ class Msf < BeEF::Command
}
msfpayloads = msf.get_payloads(modname)
return if not msfpayloads or not msfpayloads['payloads']
payloads = msfpayloads['payloads']
pl = []
payloads.each { |p|
@@ -122,7 +127,7 @@ class Msf < BeEF::Command
def get_payload_options(payload_name)
# get payload options from metasploit
msf_xmlrpc_clinet = BeEF::MsfClient.new()
msf_xmlrpc_clinet = BeEF::MsfClient.instance
msf_xmlrpc_clinet.login()
payload_options = msf_xmlrpc_clinet.payload_options(payload_name)
@@ -159,7 +164,7 @@ class Msf < BeEF::Command
end
def launch_exploit(opts)
msf = BeEF::MsfClient.new
msf = BeEF::MsfClient.instance
msf.login()
ret = msf.launch_exploit(@info['msfid'],opts)
@output = "<script>alert('#{ret['uri']}')</script>\n" if ret['result'] == 'success'