Class: Msf::Ui::Console::Driver
- Defined in:
- lib/msf/ui/console/driver.rb
Overview
A user interface driver on a console interface.
Constant Summary collapse
- ConfigCore =
"framework/core"
- ConfigGroup =
"framework/ui/console"
- DefaultPrompt =
"%undmsf#{Metasploit::Framework::Version::MAJOR}%clr"
- DefaultPromptChar =
"%clr>"
- CommandDispatchers =
Console Command Dispatchers to be loaded after the Core dispatcher.
[ CommandDispatcher::Modules, CommandDispatcher::Jobs, CommandDispatcher::Resource, CommandDispatcher::Db, CommandDispatcher::Creds, CommandDispatcher::Developer, CommandDispatcher::DNS ]
Instance Attribute Summary collapse
-
#active_module ⇒ Object
The active module associated with the driver.
-
#active_session ⇒ Object
The active session associated with the driver.
-
#command_passthru ⇒ Object
Whether or not commands can be passed through.
-
#confirm_exit ⇒ Object
Whether or not to confirm before exiting.
-
#framework ⇒ Object
The framework instance associated with this driver.
Attributes included from Rex::Ui::Text::DispatcherShell
#blocked, #busy, #dispatcher_stack
Attributes included from Rex::Ui::Text::Shell
#cont_flag, #cont_prompt, #disable_output, #hist_last_saved, #histfile, #history_manager, #input, #local_hostname, #local_username, #log_source, #name, #on_command_proc, #on_print_proc, #output, #prompt, #prompt_char, #stop_count, #stop_flag, #tab_complete_proc
Instance Method Summary collapse
- #av_warning_message ⇒ Object
-
#choose_readline(opts) ⇒ void
protected
Require the appropriate readline library based on the user’s preference.
-
#get_config ⇒ Object
Generate configuration for the console.
- #get_config_core ⇒ Object
- #get_config_group ⇒ Object
-
#handle_console_logging(val) ⇒ Object
protected
ConsoleLogging.
-
#handle_loglevel(val) ⇒ Object
protected
This method handles adjusting the global log level threshold.
-
#handle_payload(val) ⇒ Object
protected
This method handles setting a desired payload.
-
#handle_session_logging(val) ⇒ Object
protected
SessionLogging.
- #handle_session_tlv_logging(val) ⇒ Object protected
-
#handle_ssh_ident(val) ⇒ Object
protected
This method monkeypatches Net::SSH’s client identification string.
-
#initialize(prompt = DefaultPrompt, prompt_char = DefaultPromptChar, opts = {}) ⇒ Driver
constructor
Initializes a console driver instance with the supplied prompt string and prompt character.
-
#load_config(path = nil) ⇒ Object
Loads configuration for the console.
-
#load_preconfig ⇒ Object
Loads configuration that needs to be analyzed before the framework instance is created.
-
#on_startup(opts = {}) ⇒ Object
Called before things actually get rolling such that banners can be displayed, scripts can be processed, and other fun can be had.
-
#on_variable_set(glob, var, val) ⇒ Object
Called when a variable is set to a specific value.
-
#on_variable_unset(glob, var) ⇒ Object
Called when a variable is unset.
- #run_unknown_command(command) ⇒ Object protected
-
#save_config ⇒ Object
Saves configuration for the console.
-
#save_recent_history(path) ⇒ Object
Saves the recent history to the specified file.
-
#save_resource(data, path = nil) ⇒ Object
Creates the resource script file for the console.
- #stop ⇒ Object
-
#unknown_command(method, line) ⇒ Object
protected
If an unknown command was passed, try to see if it’s a valid local executable.
-
#update_prompt(*args) ⇒ Object
Proxies to shell.rb’s update prompt with our own extras.
Methods included from Rex::Ui::Text::Resource
Methods included from Rex::Ui::Text::DispatcherShell
#append_dispatcher, #block_command, #blocked_command?, #current_dispatcher, #destack_dispatcher, #enstack_dispatcher, #help_to_s, #remove_dispatcher, #run_command, #run_single, #shellsplitex, #tab_complete, #tab_complete_helper, #tab_complete_stub, #unblock_command
Methods included from Rex::Ui::Text::Shell
#_print_prompt, #format_prompt, #get_input_line, #init_tab_complete, #init_ui, #log_input, #log_output, #parse_line, #print, #print_error, #print_good, #print_line, #print_status, #print_warning, #prompt_yesno, #reset_ui, #run, #set_log_source, #stopped?, #supports_color?, #tab_complete, #unset_log_source, #with_history_manager_context
Methods included from FrameworkEventManager
#deregister_event_handlers, #on_session_close, #on_session_fail, #on_session_open, #register_event_handlers
Methods included from SessionEvent
#on_session_close, #on_session_command, #on_session_download, #on_session_filedelete, #on_session_interact, #on_session_open, #on_session_output, #on_session_upload
Methods inherited from Driver
Constructor Details
#initialize(prompt = DefaultPrompt, prompt_char = DefaultPromptChar, opts = {}) ⇒ Driver
Initializes a console driver instance with the supplied prompt string and prompt character. The optional hash can take extra values that will serve to initialize the console driver.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/msf/ui/console/driver.rb', line 66 def initialize(prompt = DefaultPrompt, prompt_char = DefaultPromptChar, opts = {}) choose_readline(opts) histfile = opts['HistFile'] || Msf::Config.history_file begin FeatureManager.instance.load_config rescue StandardError => e elog(e) end if opts['DeferModuleLoads'].nil? opts['DeferModuleLoads'] = Msf::FeatureManager.instance.enabled?(Msf::FeatureManager::DEFER_MODULE_LOADS) end # Initialize attributes = opts.merge({ 'DeferModuleLoads' => true }) if Msf::FeatureManager.instance.enabled?(Msf::FeatureManager::DNS) dns_resolver = Rex::Proto::DNS::CachedResolver.new dns_resolver.extend(Rex::Proto::DNS::CustomNameserverProvider) dns_resolver.load_config if dns_resolver.has_config? # Defer loading of modules until paths from opts can be added below = .merge({ 'CustomDnsResolver' => dns_resolver }) end self.framework = opts['Framework'] || Msf::Simple::Framework.create() if self.framework.datastore['Prompt'] prompt = self.framework.datastore['Prompt'] prompt_char = self.framework.datastore['PromptChar'] || DefaultPromptChar end # Call the parent super(prompt, prompt_char, histfile, framework, :msfconsole) # Temporarily disable output self.disable_output = true # Load pre-configuration load_preconfig # Initialize the user interface to use a different input and output # handle if one is supplied input = opts['LocalInput'] input ||= Rex::Ui::Text::Input::Stdio.new if !opts['Readline'] input.disable_readline end if (opts['LocalOutput']) if (opts['LocalOutput'].kind_of?(String)) output = Rex::Ui::Text::Output::File.new(opts['LocalOutput']) else output = opts['LocalOutput'] end else output = Rex::Ui::Text::Output::Stdio.new end init_ui(input, output) init_tab_complete # Add the core command dispatcher as the root of the dispatcher # stack enstack_dispatcher(CommandDispatcher::Core) # Report readline error if there was one.. if !@rl_err.nil? print_error("***") print_error("* Unable to load readline: #{@rl_err}") print_error("* Falling back to RbReadLine") print_error("***") end # Load the other "core" command dispatchers CommandDispatchers.each do |dispatcher_class| dispatcher = enstack_dispatcher(dispatcher_class) dispatcher.load_config(opts['Config']) end if !framework.db || !framework.db.active if framework.db.error == "disabled" print_warning("Database support has been disabled") else error_msg = "#{framework.db.error.class.is_a?(String) ? "#{framework.db.error.class} " : nil}#{framework.db.error}" print_warning("No database support: #{error_msg}") end end # Register event handlers register_event_handlers # Re-enable output self.disable_output = false # Whether or not command passthru should be allowed self.command_passthru = opts.fetch('AllowCommandPassthru', true) # Whether or not to confirm before exiting self.confirm_exit = opts['ConfirmExit'] # Initialize the module paths only if we didn't get passed a Framework instance and 'DeferModuleLoads' is false unless opts['Framework'] # Configure the framework module paths self.framework.init_module_paths(module_paths: opts['ModulePath'], defer_module_loads: opts['DeferModuleLoads']) end unless opts['DeferModuleLoads'] framework.threads.spawn("ModuleCacheRebuild", true) do framework.modules.refresh_cache_from_module_files end end # Load console-specific configuration (after module paths are added) load_config(opts['Config']) # Process things before we actually display the prompt and get rocking on_startup(opts) # Process any resource scripts if opts['Resource'].blank? # None given, load the default default_resource = ::File.join(Msf::Config.config_directory, 'msfconsole.rc') load_resource(default_resource) if ::File.exist?(default_resource) else opts['Resource'].each { |r| load_resource(r) } end # Process persistent job handler begin restore_handlers = JSON.parse(File.read(Msf::Config.persist_file)) rescue Errno::ENOENT, JSON::ParserError restore_handlers = nil end if restore_handlers print_status("Starting persistent handler(s)...") restore_handlers.each.with_index do |handler_opts, index| handler = framework.modules.create(handler_opts['mod_name']) handler.init_ui(self.input, self.output) replicant_handler = nil handler.exploit_simple(handler_opts['mod_options']) do |yielded_replicant_handler| replicant_handler = yielded_replicant_handler end if replicant_handler.nil? || replicant_handler.error print_status("Failed to start persistent payload handler ##{index} (#{handler_opts['mod_name']})") next end if replicant_handler.error.nil? job_id = handler.job_id print_status "Persistent payload handler started as Job #{job_id}" end end end # Process any additional startup commands if opts['XCommands'] and opts['XCommands'].kind_of? Array opts['XCommands'].each { |c| run_single(c) } end end |
Instance Attribute Details
#active_module ⇒ Object
The active module associated with the driver.
501 502 503 |
# File 'lib/msf/ui/console/driver.rb', line 501 def active_module @active_module end |
#active_session ⇒ Object
The active session associated with the driver.
505 506 507 |
# File 'lib/msf/ui/console/driver.rb', line 505 def active_session @active_session end |
#command_passthru ⇒ Object
Whether or not commands can be passed through.
497 498 499 |
# File 'lib/msf/ui/console/driver.rb', line 497 def command_passthru @command_passthru end |
#confirm_exit ⇒ Object
Whether or not to confirm before exiting
493 494 495 |
# File 'lib/msf/ui/console/driver.rb', line 493 def confirm_exit @confirm_exit end |
#framework ⇒ Object
The framework instance associated with this driver.
489 490 491 |
# File 'lib/msf/ui/console/driver.rb', line 489 def framework @framework end |
Instance Method Details
#av_warning_message ⇒ Object
421 422 423 424 425 426 427 428 429 |
# File 'lib/msf/ui/console/driver.rb', line 421 def avdwarn = "\e[31m"\ "Warning: This copy of the Metasploit Framework has been corrupted by an installed anti-virus program."\ " We recommend that you disable your anti-virus or exclude your Metasploit installation path, "\ "then restore the removed files from quarantine or reinstall the framework.\e[0m"\ "\n\n" $stderr.puts(Rex::Text.wordwrap(avdwarn, 0, 80)) end |
#choose_readline(opts) ⇒ void (protected)
This method returns an undefined value.
Require the appropriate readline library based on the user’s preference.
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 |
# File 'lib/msf/ui/console/driver.rb', line 709 def choose_readline(opts) # Choose a readline library before calling the parent @rl_err = nil if opts['RealReadline'] # Remove the gem version from load path to be sure we're getting the # stdlib readline. gem_dir = Gem::Specification.find_all_by_name('rb-readline').first.gem_dir rb_readline_path = File.join(gem_dir, "lib") index = $LOAD_PATH.index(rb_readline_path) # Bundler guarantees that the gem will be there, so it should be safe to # assume we found it in the load path, but check to be on the safe side. if index $LOAD_PATH.delete_at(index) end end begin require 'readline' # Only Windows requires a monkey-patched RbReadline return unless Rex::Compat.is_windows if defined?(::RbReadline) && !defined?(RbReadline.refresh_console_handle) ::RbReadline.instance_eval do class << self alias_method :old_rl_move_cursor_relative, :_rl_move_cursor_relative alias_method :old_rl_get_screen_size, :_rl_get_screen_size alias_method :old_space_to_eol, :space_to_eol alias_method :old_insert_some_chars, :insert_some_chars end def self.refresh_console_handle # hConsoleHandle gets set only when RbReadline detects it is running on Windows. # Therefore, we don't need to check Rex::Compat.is_windows, we can simply check if hConsoleHandle is nil or not. @hConsoleHandle = @GetStdHandle.Call(::Readline::STD_OUTPUT_HANDLE) if @hConsoleHandle end def self._rl_move_cursor_relative(*args) refresh_console_handle old_rl_move_cursor_relative(*args) end def self._rl_get_screen_size(*args) refresh_console_handle old_rl_get_screen_size(*args) end def self.space_to_eol(*args) refresh_console_handle old_space_to_eol(*args) end def self.insert_some_chars(*args) refresh_console_handle old_insert_some_chars(*args) end end end rescue ::LoadError => e if @rl_err.nil? && index # Then this is the first time the require failed and we have an index # for the gem version as a fallback. @rl_err = e # Put the gem back and see if that works $LOAD_PATH.insert(index, rb_readline_path) index = rb_readline_path = nil retry else # Either we didn't have the gem to fall back on, or we failed twice. # Nothing more we can do here. raise e end end end |
#get_config ⇒ Object
Generate configuration for the console.
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/msf/ui/console/driver.rb', line 286 def get_config # Build out the console config group group = {} if (active_module) group['ActiveModule'] = active_module.fullname end if framework.db.active unless framework.db.workspace.default? group['ActiveWorkspace'] = framework.db.workspace.name end end group end |
#get_config_core ⇒ Object
303 304 305 |
# File 'lib/msf/ui/console/driver.rb', line 303 def get_config_core ConfigCore end |
#get_config_group ⇒ Object
307 308 309 |
# File 'lib/msf/ui/console/driver.rb', line 307 def get_config_group ConfigGroup end |
#handle_console_logging(val) ⇒ Object (protected)
ConsoleLogging.
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 |
# File 'lib/msf/ui/console/driver.rb', line 588 def handle_console_logging(val) if (val =~ /^(y|t|1)/i) Msf::Logging.enable_log_source('console') print_line("Console logging is now enabled.") set_log_source('console') rlog("\n[*] Console logging started: #{Time.now}\n\n", 'console') else rlog("\n[*] Console logging stopped: #{Time.now}\n\n", 'console') unset_log_source Msf::Logging.disable_log_source('console') print_line("Console logging is now disabled.") end end |
#handle_loglevel(val) ⇒ Object (protected)
This method handles adjusting the global log level threshold.
609 610 611 612 |
# File 'lib/msf/ui/console/driver.rb', line 609 def handle_loglevel(val) set_log_level(Rex::LogSource, val) set_log_level(Msf::LogSource, val) end |
#handle_payload(val) ⇒ Object (protected)
This method handles setting a desired payload
TODO: Move this out of the console driver!
619 620 621 622 623 624 625 626 627 628 629 |
# File 'lib/msf/ui/console/driver.rb', line 619 def handle_payload(val) if framework && !framework.payloads.valid?(val) return false elsif active_module && (active_module.exploit? || active_module.evasion?) return false unless active_module.is_payload_compatible?(val) elsif active_module && !framework.features.enabled?(Msf::FeatureManager::DATASTORE_FALLBACKS) active_module.datastore.clear_non_user_defined elsif framework && !framework.features.enabled?(Msf::FeatureManager::DATASTORE_FALLBACKS) framework.datastore.clear_non_user_defined end end |
#handle_session_logging(val) ⇒ Object (protected)
SessionLogging.
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 |
# File 'lib/msf/ui/console/driver.rb', line 569 def handle_session_logging(val) if (val =~ /^(y|t|1)/i) Msf::Logging.enable_session_logging(true) framework.sessions.values.each do |session| Msf::Logging.start_session_log(session) end print_line("Session logging enabled.") else Msf::Logging.enable_session_logging(false) framework.sessions.values.each do |session| Msf::Logging.stop_session_log(session) end print_line("Session logging disabled.") end end |
#handle_session_tlv_logging(val) ⇒ Object (protected)
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 |
# File 'lib/msf/ui/console/driver.rb', line 659 def handle_session_tlv_logging(val) return false if val.nil? if val.casecmp?('console') || val.casecmp?('true') || val.casecmp?('false') return true elsif val.start_with?('file:') && !val.split('file:').empty? pathname = ::Pathname.new(val.split('file:').last) # Check if we want to write the log to file if ::File.file?(pathname) if ::File.writable?(pathname) return true else print_status "No write permissions for log output file: #{pathname}" return false end # Check if we want to write the log file to a directory elsif ::File.directory?(pathname) if ::File.writable?(pathname) return true else print_status "No write permissions for log output directory: #{pathname}" return false end # Check if the subdirectory exists elsif ::File.directory?(pathname.dirname) if ::File.writable?(pathname.dirname) return true else print_status "No write permissions for log output directory: #{pathname.dirname}" return false end else # Else the directory doesn't exist. Check if we can create it. begin ::FileUtils.mkdir_p(pathname.dirname) return true rescue ::StandardError => e print_status "Error when trying to create directory #{pathname.dirname}: #{e.}" return false end end end false end |
#handle_ssh_ident(val) ⇒ Object (protected)
This method monkeypatches Net::SSH’s client identification string
TODO: Move this out of the console driver!
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 |
# File 'lib/msf/ui/console/driver.rb', line 636 def handle_ssh_ident(val) # HACK: Suppress already initialized constant warning verbose, $VERBOSE = $VERBOSE, nil return false unless val.is_a?(String) && !val.empty? require 'net/ssh' # HACK: Bypass dynamic constant assignment error ::Net::SSH::Transport::ServerVersion.const_set(:PROTO_VERSION, val) true rescue LoadError print_error('Net::SSH could not be loaded') false rescue NameError print_error('Invalid constant Net::SSH::Transport::ServerVersion::PROTO_VERSION') false ensure # Restore warning $VERBOSE = verbose end |
#load_config(path = nil) ⇒ Object
Loads configuration for the console.
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/msf/ui/console/driver.rb', line 259 def load_config(path=nil) begin conf = Msf::Config.load(path) rescue wlog("Failed to load configuration: #{$!}") return end # If we have configuration, process it if (conf.group?(ConfigGroup)) conf[ConfigGroup].each_pair { |k, v| case k.downcase when 'activemodule' run_single("use #{v}") when 'activeworkspace' if framework.db.active workspace = framework.db.find_workspace(v) framework.db.workspace = workspace if workspace end end } end end |
#load_preconfig ⇒ Object
Loads configuration that needs to be analyzed before the framework instance is created.
241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/msf/ui/console/driver.rb', line 241 def load_preconfig begin conf = Msf::Config.load rescue wlog("Failed to load configuration: #{$!}") return end if (conf.group?(ConfigCore)) conf[ConfigCore].each_pair { |k, v| on_variable_set(true, k, v) } end end |
#on_startup(opts = {}) ⇒ Object
Called before things actually get rolling such that banners can be displayed, scripts can be processed, and other fun can be had.
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 |
# File 'lib/msf/ui/console/driver.rb', line 363 def on_startup(opts = {}) # Check for modules that failed to load if framework.modules.module_load_error_by_path.length > 0 wlog("The following modules could not be loaded!") framework.modules.module_load_error_by_path.each do |path, _error| wlog("\t#{path}") end end if framework.modules.module_load_warnings.length > 0 print_warning("The following modules were loaded with warnings:") framework.modules.module_load_warnings.each do |path, _error| wlog("\t#{path}") end end if framework.db&.active framework.db.workspace = framework.db.default_workspace unless framework.db.workspace end framework.events.on_ui_start(Msf::Framework::Revision) if $msf_spinner_thread $msf_spinner_thread.kill $stderr.print "\r" + (" " * 50) + "\n" end run_single("banner") unless opts['DisableBanner'] payloads_manifest_errors = [] begin payloads_manifest_errors = ::MetasploitPayloads.manifest_errors if framework.features.enabled?(::Msf::FeatureManager::METASPLOIT_PAYLOAD_WARNINGS) rescue ::StandardError => e $stderr.print('Could not verify the integrity of the Metasploit Payloads manifest') elog(e) end if (framework.eicar_corrupted? || payloads_manifest_errors.any?) if framework.features.enabled?(::Msf::FeatureManager::METASPLOIT_PAYLOAD_WARNINGS) if payloads_manifest_errors.any? warn_msg = "Metasploit Payloads manifest errors:\n" payloads_manifest_errors.each do |file| warn_msg << "\t#{file[:path]} : #{file[:error]}\n" end $stderr.print(warn_msg) end end opts["Plugins"].each do |plug| run_single("load '#{plug}'") end if opts["Plugins"] self.on_command_proc = Proc.new { |command| framework.events.on_ui_command(command) } end |
#on_variable_set(glob, var, val) ⇒ Object
Called when a variable is set to a specific value. This allows the console to do extra processing, such as enabling logging or doing some other kind of task. If this routine returns false it will indicate that the variable is not being set to a valid value.
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
# File 'lib/msf/ui/console/driver.rb', line 437 def on_variable_set(glob, var, val) case var.downcase when 'sessionlogging' handle_session_logging(val) if glob when 'sessiontlvlogging' handle_session_tlv_logging(val) if glob when 'consolelogging' handle_console_logging(val) if glob when 'loglevel' handle_loglevel(val) if glob when 'payload' handle_payload(val) when 'ssh_ident' handle_ssh_ident(val) end end |
#on_variable_unset(glob, var) ⇒ Object
Called when a variable is unset. If this routine returns false it is an indication that the variable should not be allowed to be unset.
458 459 460 461 462 463 464 465 466 467 468 469 |
# File 'lib/msf/ui/console/driver.rb', line 458 def on_variable_unset(glob, var) case var.downcase when 'sessionlogging' handle_session_logging('0') if glob when 'sessiontlvlogging' handle_session_tlv_logging('false') if glob when 'consolelogging' handle_console_logging('0') if glob when 'loglevel' handle_loglevel(nil) if glob end end |
#run_unknown_command(command) ⇒ Object (protected)
554 555 556 557 558 |
# File 'lib/msf/ui/console/driver.rb', line 554 def run_unknown_command(command) print_status("exec: #{command}") print_line('') system(command) end |
#save_config ⇒ Object
Saves configuration for the console.
314 315 316 317 318 319 320 |
# File 'lib/msf/ui/console/driver.rb', line 314 def save_config begin Msf::Config.save(ConfigGroup => get_config) rescue ::Exception print_error("Failed to save console config: #{$!}") end end |
#save_recent_history(path) ⇒ Object
Saves the recent history to the specified file
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
# File 'lib/msf/ui/console/driver.rb', line 325 def save_recent_history(path) num = Readline::HISTORY.length - hist_last_saved - 1 tmprc = "" num.times { |x| tmprc << Readline::HISTORY[hist_last_saved + x] + "\n" } if tmprc.length > 0 print_status("Saving last #{num} commands to #{path} ...") save_resource(tmprc, path) else print_error("No commands to save!") end # Always update this, even if we didn't save anything. We do this # so that we don't end up saving the "makerc" command itself. self.hist_last_saved = Readline::HISTORY.length end |
#save_resource(data, path = nil) ⇒ Object
Creates the resource script file for the console.
348 349 350 351 352 353 354 355 356 357 |
# File 'lib/msf/ui/console/driver.rb', line 348 def save_resource(data, path=nil) path ||= File.join(Msf::Config.config_directory, 'msfconsole.rc') begin rcfd = File.open(path, 'w') rcfd.write(data) rcfd.close rescue ::Exception end end |
#stop ⇒ Object
507 508 509 510 |
# File 'lib/msf/ui/console/driver.rb', line 507 def stop framework.events.on_ui_stop() super end |
#unknown_command(method, line) ⇒ Object (protected)
If an unknown command was passed, try to see if it’s a valid local executable. This is only allowed if command passthru has been permitted
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 |
# File 'lib/msf/ui/console/driver.rb', line 522 def unknown_command(method, line) if File.basename(method) == 'msfconsole' print_error('msfconsole cannot be run inside msfconsole') return end [method, method+".exe"].each do |cmd| if command_passthru && Rex::FileUtils.find_full_path(cmd) self.busy = true begin run_unknown_command(line) rescue ::Errno::EACCES, ::Errno::ENOENT print_error("Permission denied exec: #{line}") end self.busy = false return end end if framework.modules.create(method) super if prompt_yesno "This is a module we can load. Do you want to use #{method}?" run_single "use #{method}" end return end super end |
#update_prompt(*args) ⇒ Object
Proxies to shell.rb’s update prompt with our own extras
474 475 476 477 478 479 480 481 482 483 484 |
# File 'lib/msf/ui/console/driver.rb', line 474 def update_prompt(*args) if args.empty? pchar = framework.datastore['PromptChar'] || DefaultPromptChar p = framework.datastore['Prompt'] || DefaultPrompt p = "#{p} #{active_module.type}(%bld%red#{active_module.promptname}%clr)" if active_module super(p, pchar) else # Don't squash calls from within lib/rex/ui/text/shell.rb super(*args) end end |