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.

driver.rb 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. # -*- coding: binary -*-
  2. require 'msf/core'
  3. require 'msf/base'
  4. require 'msf/ui'
  5. require 'msf/ui/console/framework_event_manager'
  6. require 'msf/ui/console/command_dispatcher'
  7. require 'msf/ui/console/table'
  8. require 'find'
  9. require 'erb'
  10. require 'rexml/document'
  11. require 'fileutils'
  12. require 'digest/md5'
  13. module Msf
  14. module Ui
  15. module Console
  16. ###
  17. #
  18. # This class implements a user interface driver on a console interface.
  19. #
  20. ###
  21. class Driver < Msf::Ui::Driver
  22. ConfigCore = "framework/core"
  23. ConfigGroup = "framework/ui/console"
  24. DefaultPrompt = "%undmsf%clr"
  25. DefaultPromptChar = "%clr>"
  26. #
  27. # The console driver processes various framework notified events.
  28. #
  29. include FrameworkEventManager
  30. #
  31. # The console driver is a command shell.
  32. #
  33. include Rex::Ui::Text::DispatcherShell
  34. #
  35. # Initializes a console driver instance with the supplied prompt string and
  36. # prompt character. The optional hash can take extra values that will
  37. # serve to initialize the console driver.
  38. #
  39. # The optional hash values can include:
  40. #
  41. # AllowCommandPassthru
  42. #
  43. # Whether or not unknown commands should be passed through and executed by
  44. # the local system.
  45. #
  46. # RealReadline
  47. #
  48. # Whether or to use the system Readline or the RBReadline (default)
  49. #
  50. # HistFile
  51. #
  52. # Name of a file to store command history
  53. #
  54. def initialize(prompt = DefaultPrompt, prompt_char = DefaultPromptChar, opts = {})
  55. # Choose a readline library before calling the parent
  56. rl = false
  57. rl_err = nil
  58. begin
  59. if(opts['RealReadline'])
  60. require 'readline'
  61. rl = true
  62. end
  63. rescue ::LoadError
  64. rl_err = $!
  65. end
  66. # Default to the RbReadline wrapper
  67. require 'readline_compatible' if(not rl)
  68. histfile = opts['HistFile'] || Msf::Config.history_file
  69. # Initialize attributes
  70. self.framework = opts['Framework'] || Msf::Simple::Framework.create(opts)
  71. if self.framework.datastore['Prompt']
  72. prompt = self.framework.datastore['Prompt']
  73. prompt_char = self.framework.datastore['PromptChar'] || DefaultPromptChar
  74. end
  75. # Call the parent
  76. super(prompt, prompt_char, histfile, framework)
  77. # Temporarily disable output
  78. self.disable_output = true
  79. # Load pre-configuration
  80. load_preconfig
  81. # Initialize the user interface to use a different input and output
  82. # handle if one is supplied
  83. input = opts['LocalInput']
  84. input ||= Rex::Ui::Text::Input::Stdio.new
  85. if (opts['LocalOutput'])
  86. if (opts['LocalOutput'].kind_of?(String))
  87. output = Rex::Ui::Text::Output::File.new(opts['LocalOutput'])
  88. else
  89. output = opts['LocalOutput']
  90. end
  91. else
  92. output = Rex::Ui::Text::Output::Stdio.new
  93. end
  94. init_ui(input, output)
  95. init_tab_complete
  96. # Add the core command dispatcher as the root of the dispatcher
  97. # stack
  98. enstack_dispatcher(CommandDispatcher::Core)
  99. # Report readline error if there was one..
  100. if not rl_err.nil?
  101. print_error("***")
  102. print_error("* WARNING: Unable to load readline: #{rl_err}")
  103. print_error("* Falling back to RbReadLine")
  104. print_error("***")
  105. end
  106. # Add the database dispatcher if it is usable
  107. if (framework.db.usable)
  108. require 'msf/ui/console/command_dispatcher/db'
  109. enstack_dispatcher(CommandDispatcher::Db)
  110. else
  111. print_error("***")
  112. if framework.db.error == "disabled"
  113. print_error("* WARNING: Database support has been disabled")
  114. else
  115. print_error("* WARNING: No database support: #{framework.db.error.class} #{framework.db.error}")
  116. end
  117. print_error("***")
  118. end
  119. begin
  120. require 'openssl'
  121. rescue ::LoadError
  122. print_error("***")
  123. print_error("* WARNING: No OpenSSL support. This is required by meterpreter payloads and many exploits")
  124. print_error("* Please install the ruby-openssl package (apt-get install libopenssl-ruby on Debian/Ubuntu")
  125. print_error("***")
  126. end
  127. # Register event handlers
  128. register_event_handlers
  129. # Re-enable output
  130. self.disable_output = false
  131. # Whether or not command passthru should be allowed
  132. self.command_passthru = (opts['AllowCommandPassthru'] == false) ? false : true
  133. # Whether or not to confirm before exiting
  134. self.confirm_exit = (opts['ConfirmExit'] == true) ? true : false
  135. # Disables "dangerous" functionality of the console
  136. @defanged = opts['Defanged'] == true
  137. # If we're defanged, then command passthru should be disabled
  138. if @defanged
  139. self.command_passthru = false
  140. end
  141. # Parse any specified database.yml file
  142. if framework.db.usable and not opts['SkipDatabaseInit']
  143. # Append any migration paths necessary to bring the database online
  144. if opts['DatabaseMigrationPaths']
  145. opts['DatabaseMigrationPaths'].each do |migrations_path|
  146. ActiveRecord::Migrator.migrations_paths << migrations_path
  147. end
  148. end
  149. # Look for our database configuration in the following places, in order:
  150. # command line arguments
  151. # environment variable
  152. # configuration directory (usually ~/.msf3)
  153. dbfile = opts['DatabaseYAML']
  154. dbfile ||= ENV["MSF_DATABASE_CONFIG"]
  155. dbfile ||= File.join(Msf::Config.get_config_root, "database.yml")
  156. if (dbfile and File.exists? dbfile)
  157. if File.readable?(dbfile)
  158. dbinfo = YAML.load(File.read(dbfile))
  159. dbenv = opts['DatabaseEnv'] || "production"
  160. db = dbinfo[dbenv]
  161. else
  162. print_error("Warning, #{dbfile} is not readable. Try running as root or chmod.")
  163. end
  164. if not db
  165. print_error("No database definition for environment #{dbenv}")
  166. else
  167. if not framework.db.connect(db)
  168. if framework.db.error.to_s =~ /RubyGem version.*pg.*0\.11/i
  169. print_error("***")
  170. print_error("*")
  171. print_error("* Metasploit now requires version 0.11 or higher of the 'pg' gem for database support")
  172. print_error("* There a three ways to accomplish this upgrade:")
  173. print_error("* 1. If you run Metasploit with your system ruby, simply upgrade the gem:")
  174. print_error("* $ rvmsudo gem install pg ")
  175. print_error("* 2. Use the Community Edition web interface to apply a Software Update")
  176. print_error("* 3. Uninstall, download the latest version, and reinstall Metasploit")
  177. print_error("*")
  178. print_error("***")
  179. print_error("")
  180. print_error("")
  181. end
  182. print_error("Failed to connect to the database: #{framework.db.error}")
  183. else
  184. self.framework.modules.refresh_cache_from_database
  185. if self.framework.modules.cache_empty?
  186. print_status("The initial module cache will be built in the background, this can take 2-5 minutes...")
  187. end
  188. end
  189. end
  190. end
  191. end
  192. # Initialize the module paths only if we didn't get passed a Framework instance
  193. unless opts['Framework']
  194. # Configure the framework module paths
  195. self.framework.init_module_paths
  196. self.framework.modules.add_module_path(opts['ModulePath']) if opts['ModulePath']
  197. # Rebuild the module cache in a background thread
  198. self.framework.threads.spawn("ModuleCacheRebuild", true) do
  199. self.framework.modules.refresh_cache_from_module_files
  200. end
  201. end
  202. # Load console-specific configuration (after module paths are added)
  203. load_config(opts['Config'])
  204. # Process things before we actually display the prompt and get rocking
  205. on_startup(opts)
  206. # Process the resource script
  207. if opts['Resource'] and opts['Resource'].kind_of? Array
  208. opts['Resource'].each { |r|
  209. load_resource(r)
  210. }
  211. else
  212. # If the opt is nil here, we load ~/.msf3/msfconsole.rc
  213. load_resource(opts['Resource'])
  214. end
  215. # Process any additional startup commands
  216. if opts['XCommands'] and opts['XCommands'].kind_of? Array
  217. opts['XCommands'].each { |c|
  218. run_single(c)
  219. }
  220. end
  221. end
  222. #
  223. # Configure a default output path for jUnit XML output
  224. #
  225. def junit_setup(output_path)
  226. output_path = ::File.expand_path(output_path)
  227. ::FileUtils.mkdir_p(output_path)
  228. @junit_output_path = output_path
  229. @junit_error_count = 0
  230. print_status("Test Output: #{output_path}")
  231. # We need at least one test success in order to pass
  232. junit_pass("framework_loaded")
  233. end
  234. #
  235. # Emit a new jUnit XML output file representing an error
  236. #
  237. def junit_error(tname, ftype, data = nil)
  238. if not @junit_output_path
  239. raise RuntimeError, "No output path, call junit_setup() first"
  240. end
  241. data ||= framework.inspect.to_s
  242. e = REXML::Element.new("testsuite")
  243. c = REXML::Element.new("testcase")
  244. c.attributes["classname"] = "msfrc"
  245. c.attributes["name"] = tname
  246. f = REXML::Element.new("failure")
  247. f.attributes["type"] = ftype
  248. f.text = data
  249. c << f
  250. e << c
  251. bname = ("msfrpc_#{tname}").gsub(/[^A-Za-z0-9\.\_]/, '')
  252. bname << "_" + Digest::MD5.hexdigest(tname)
  253. fname = ::File.join(@junit_output_path, "#{bname}.xml")
  254. cnt = 0
  255. while ::File.exists?( fname )
  256. cnt += 1
  257. fname = ::File.join(@junit_output_path, "#{bname}_#{cnt}.xml")
  258. end
  259. ::File.open(fname, "w") do |fd|
  260. fd.write(e.to_s)
  261. end
  262. print_error("Test Error: #{tname} - #{ftype} - #{data}")
  263. end
  264. #
  265. # Emit a new jUnit XML output file representing a success
  266. #
  267. def junit_pass(tname)
  268. if not @junit_output_path
  269. raise RuntimeError, "No output path, call junit_setup() first"
  270. end
  271. # Generate the structure of a test case run
  272. e = REXML::Element.new("testsuite")
  273. c = REXML::Element.new("testcase")
  274. c.attributes["classname"] = "msfrc"
  275. c.attributes["name"] = tname
  276. e << c
  277. # Generate a unique name
  278. bname = ("msfrpc_#{tname}").gsub(/[^A-Za-z0-9\.\_]/, '')
  279. bname << "_" + Digest::MD5.hexdigest(tname)
  280. # Generate the output path, allow multiple test with the same name
  281. fname = ::File.join(@junit_output_path, "#{bname}.xml")
  282. cnt = 0
  283. while ::File.exists?( fname )
  284. cnt += 1
  285. fname = ::File.join(@junit_output_path, "#{bname}_#{cnt}.xml")
  286. end
  287. # Write to our test output location, as specified with junit_setup
  288. ::File.open(fname, "w") do |fd|
  289. fd.write(e.to_s)
  290. end
  291. print_good("Test Pass: #{tname}")
  292. end
  293. #
  294. # Emit a jUnit XML output file and throw a fatal exception
  295. #
  296. def junit_fatal_error(tname, ftype, data)
  297. junit_error(tname, ftype, data)
  298. print_error("Exiting")
  299. run_single("exit -y")
  300. end
  301. #
  302. # Loads configuration that needs to be analyzed before the framework
  303. # instance is created.
  304. #
  305. def load_preconfig
  306. begin
  307. conf = Msf::Config.load
  308. rescue
  309. wlog("Failed to load configuration: #{$!}")
  310. return
  311. end
  312. if (conf.group?(ConfigCore))
  313. conf[ConfigCore].each_pair { |k, v|
  314. on_variable_set(true, k, v)
  315. }
  316. end
  317. end
  318. #
  319. # Loads configuration for the console.
  320. #
  321. def load_config(path=nil)
  322. begin
  323. conf = Msf::Config.load(path)
  324. rescue
  325. wlog("Failed to load configuration: #{$!}")
  326. return
  327. end
  328. # If we have configuration, process it
  329. if (conf.group?(ConfigGroup))
  330. conf[ConfigGroup].each_pair { |k, v|
  331. case k.downcase
  332. when "activemodule"
  333. run_single("use #{v}")
  334. end
  335. }
  336. end
  337. end
  338. #
  339. # Saves configuration for the console.
  340. #
  341. def save_config
  342. # Build out the console config group
  343. group = {}
  344. if (active_module)
  345. group['ActiveModule'] = active_module.fullname
  346. end
  347. # Save it
  348. begin
  349. Msf::Config.save(ConfigGroup => group)
  350. rescue ::Exception
  351. print_error("Failed to save console config: #{$!}")
  352. end
  353. end
  354. #
  355. # Processes the resource script file for the console.
  356. #
  357. def load_resource(path=nil)
  358. path ||= File.join(Msf::Config.config_directory, 'msfconsole.rc')
  359. return if not ::File.readable?(path)
  360. resource_file = ::File.read(path)
  361. self.active_resource = resource_file
  362. # Process ERB directives first
  363. print_status "Processing #{path} for ERB directives."
  364. erb = ERB.new(resource_file)
  365. processed_resource = erb.result(binding)
  366. lines = processed_resource.each_line.to_a
  367. bindings = {}
  368. while lines.length > 0
  369. line = lines.shift
  370. break if not line
  371. line.strip!
  372. next if line.length == 0
  373. next if line =~ /^#/
  374. # Pretty soon, this is going to need an XML parser :)
  375. # TODO: case matters for the tag and for binding names
  376. if line =~ /<ruby/
  377. if line =~ /\s+binding=(?:'(\w+)'|"(\w+)")(>|\s+)/
  378. bin = ($~[1] || $~[2])
  379. bindings[bin] = binding unless bindings.has_key? bin
  380. bin = bindings[bin]
  381. else
  382. bin = binding
  383. end
  384. buff = ''
  385. while lines.length > 0
  386. line = lines.shift
  387. break if not line
  388. break if line =~ /<\/ruby>/
  389. buff << line
  390. end
  391. if ! buff.empty?
  392. print_status("resource (#{path})> Ruby Code (#{buff.length} bytes)")
  393. begin
  394. eval(buff, bin)
  395. rescue ::Interrupt
  396. raise $!
  397. rescue ::Exception => e
  398. print_error("resource (#{path})> Ruby Error: #{e.class} #{e} #{e.backtrace}")
  399. end
  400. end
  401. else
  402. print_line("resource (#{path})> #{line}")
  403. run_single(line)
  404. end
  405. end
  406. self.active_resource = nil
  407. end
  408. #
  409. # Saves the recent history to the specified file
  410. #
  411. def save_recent_history(path)
  412. num = Readline::HISTORY.length - hist_last_saved - 1
  413. tmprc = ""
  414. num.times { |x|
  415. tmprc << Readline::HISTORY[hist_last_saved + x] + "\n"
  416. }
  417. if tmprc.length > 0
  418. print_status("Saving last #{num} commands to #{path} ...")
  419. save_resource(tmprc, path)
  420. else
  421. print_error("No commands to save!")
  422. end
  423. # Always update this, even if we didn't save anything. We do this
  424. # so that we don't end up saving the "makerc" command itself.
  425. self.hist_last_saved = Readline::HISTORY.length
  426. end
  427. #
  428. # Creates the resource script file for the console.
  429. #
  430. def save_resource(data, path=nil)
  431. path ||= File.join(Msf::Config.config_directory, 'msfconsole.rc')
  432. begin
  433. rcfd = File.open(path, 'w')
  434. rcfd.write(data)
  435. rcfd.close
  436. rescue ::Exception
  437. end
  438. end
  439. #
  440. # Called before things actually get rolling such that banners can be
  441. # displayed, scripts can be processed, and other fun can be had.
  442. #
  443. def on_startup(opts = {})
  444. # Check for modules that failed to load
  445. if framework.modules.module_load_error_by_path.length > 0
  446. print_error("WARNING! The following modules could not be loaded!")
  447. framework.modules.module_load_error_by_path.each do |path, error|
  448. print_error("\t#{path}: #{error}")
  449. end
  450. end
  451. framework.events.on_ui_start(Msf::Framework::Revision)
  452. run_single("banner") unless opts['DisableBanner']
  453. opts["Plugins"].each do |plug|
  454. run_single("load '#{plug}'")
  455. end if opts["Plugins"]
  456. self.on_command_proc = Proc.new { |command| framework.events.on_ui_command(command) }
  457. end
  458. #
  459. # Called when a variable is set to a specific value. This allows the
  460. # console to do extra processing, such as enabling logging or doing
  461. # some other kind of task. If this routine returns false it will indicate
  462. # that the variable is not being set to a valid value.
  463. #
  464. def on_variable_set(glob, var, val)
  465. case var.downcase
  466. when "payload"
  467. if (framework and framework.payloads.valid?(val) == false)
  468. return false
  469. elsif (active_module)
  470. active_module.datastore.clear_non_user_defined
  471. elsif (framework)
  472. framework.datastore.clear_non_user_defined
  473. end
  474. when "sessionlogging"
  475. handle_session_logging(val) if (glob)
  476. when "consolelogging"
  477. handle_console_logging(val) if (glob)
  478. when "loglevel"
  479. handle_loglevel(val) if (glob)
  480. when "prompt"
  481. update_prompt(val, framework.datastore['PromptChar'] || DefaultPromptChar, true)
  482. when "promptchar"
  483. update_prompt(framework.datastore['Prompt'], val, true)
  484. end
  485. end
  486. #
  487. # Called when a variable is unset. If this routine returns false it is an
  488. # indication that the variable should not be allowed to be unset.
  489. #
  490. def on_variable_unset(glob, var)
  491. case var.downcase
  492. when "sessionlogging"
  493. handle_session_logging('0') if (glob)
  494. when "consolelogging"
  495. handle_console_logging('0') if (glob)
  496. when "loglevel"
  497. handle_loglevel(nil) if (glob)
  498. end
  499. end
  500. #
  501. # The framework instance associated with this driver.
  502. #
  503. attr_reader :framework
  504. #
  505. # Whether or not to confirm before exiting
  506. #
  507. attr_reader :confirm_exit
  508. #
  509. # Whether or not commands can be passed through.
  510. #
  511. attr_reader :command_passthru
  512. #
  513. # The active module associated with the driver.
  514. #
  515. attr_accessor :active_module
  516. #
  517. # The active session associated with the driver.
  518. #
  519. attr_accessor :active_session
  520. #
  521. # The active resource file being processed by the driver
  522. #
  523. attr_accessor :active_resource
  524. #
  525. # If defanged is true, dangerous functionality, such as exploitation, irb,
  526. # and command shell passthru is disabled. In this case, an exception is
  527. # raised.
  528. #
  529. def defanged?
  530. if @defanged
  531. raise DefangedException
  532. end
  533. end
  534. def stop
  535. framework.events.on_ui_stop()
  536. super
  537. end
  538. protected
  539. attr_writer :framework # :nodoc:
  540. attr_writer :confirm_exit # :nodoc:
  541. attr_writer :command_passthru # :nodoc:
  542. #
  543. # If an unknown command was passed, try to see if it's a valid local
  544. # executable. This is only allowed if command passthru has been permitted
  545. #
  546. def unknown_command(method, line)
  547. [method, method+".exe"].each do |cmd|
  548. if (command_passthru == true and Rex::FileUtils.find_full_path(cmd))
  549. print_status("exec: #{line}")
  550. print_line('')
  551. self.busy = true
  552. begin
  553. io = ::IO.popen(line, "r")
  554. io.each_line do |data|
  555. print(data)
  556. end
  557. io.close
  558. rescue ::Errno::EACCES, ::Errno::ENOENT
  559. print_error("Permission denied exec: #{line}")
  560. end
  561. self.busy = false
  562. return
  563. end
  564. end
  565. super
  566. end
  567. ##
  568. #
  569. # Handlers for various global configuration values
  570. #
  571. ##
  572. #
  573. # SessionLogging.
  574. #
  575. def handle_session_logging(val)
  576. if (val =~ /^(y|t|1)/i)
  577. Msf::Logging.enable_session_logging(true)
  578. print_line("Session logging will be enabled for future sessions.")
  579. else
  580. Msf::Logging.enable_session_logging(false)
  581. print_line("Session logging will be disabled for future sessions.")
  582. end
  583. end
  584. #
  585. # ConsoleLogging.
  586. #
  587. def handle_console_logging(val)
  588. if (val =~ /^(y|t|1)/i)
  589. Msf::Logging.enable_log_source('console')
  590. print_line("Console logging is now enabled.")
  591. set_log_source('console')
  592. rlog("\n[*] Console logging started: #{Time.now}\n\n", 'console')
  593. else
  594. rlog("\n[*] Console logging stopped: #{Time.now}\n\n", 'console')
  595. unset_log_source
  596. Msf::Logging.disable_log_source('console')
  597. print_line("Console logging is now disabled.")
  598. end
  599. end
  600. #
  601. # This method handles adjusting the global log level threshold.
  602. #
  603. def handle_loglevel(val)
  604. set_log_level(Rex::LogSource, val)
  605. set_log_level(Msf::LogSource, val)
  606. end
  607. end
  608. #
  609. # This exception is used to indicate that functionality is disabled due to
  610. # defanged being true
  611. #
  612. class DefangedException < ::Exception
  613. def to_s
  614. "This functionality is currently disabled (defanged mode)"
  615. end
  616. end
  617. end
  618. end
  619. end