Class: Msf::Sessions::CommandShellWindows
- Inherits:
-
CommandShell
- Object
- CommandShell
- Msf::Sessions::CommandShellWindows
- Defined in:
- lib/msf/base/sessions/command_shell_windows.rb
Instance Attribute Summary
Attributes inherited from CommandShell
#arch, #banner, #max_threads, #platform
Attributes included from Msf::Session::Interactive
Attributes included from Rex::Ui::Interactive
#completed, #interacting, #next_session, #on_command_proc, #on_print_proc, #on_run_command_error_proc, #orig_suspend, #orig_usr1, #orig_winch
Attributes included from Rex::Ui::Subscriber::Input
Attributes included from Rex::Ui::Subscriber::Output
Attributes included from Msf::Session
#alive, #db_record, #exploit, #exploit_datastore, #exploit_task, #exploit_uuid, #framework, #info, #machine_id, #payload_uuid, #routes, #sid, #sname, #target_host, #target_port, #username, #uuid, #via, #workspace
Attributes included from Framework::Offspring
Class Method Summary collapse
-
.argv_to_commandline(args) ⇒ Object
Convert the executable and argument array to a commandline that can be passed to CreateProcessAsUserW.
-
.escape_arg(arg) ⇒ Object
Escape an individual argument per Windows shell rules.
-
.escape_cmd(executable) ⇒ Object
Escape a process for the command line.
- .space_chars ⇒ Object
-
.to_cmd(cmd_and_args) ⇒ Object
Convert the executable and argument array to a command that can be run in this command shell.
Instance Method Summary collapse
-
#initialize(*args) ⇒ CommandShellWindows
constructor
A new instance of CommandShellWindows.
- #shell_command_token(cmd, timeout = 10) ⇒ Object
-
#to_cmd(cmd_and_args) ⇒ Object
Convert the executable and argument array to a command that can be run in this command shell.
Methods inherited from CommandShell
#_file_transfer, _glue_cmdline_escape, #_interact, #_interact_stream, #abort_foreground_supported, binary_exists, #binary_exists, #bootstrap, can_cleanup_files, #cleanup, #cmd_background, #cmd_background_help, #cmd_download, #cmd_download_help, #cmd_help, #cmd_help_help, #cmd_irb, #cmd_irb_help, #cmd_pry, #cmd_pry_help, #cmd_resource, #cmd_resource_help, #cmd_sessions, #cmd_sessions_help, #cmd_shell, #cmd_shell_help, #cmd_source, #cmd_source_help, #cmd_upload, #cmd_upload_help, #commands, #desc, #docs_dir, #execute_file, #process_autoruns, #run_builtin_cmd, #run_single, #shell_close, #shell_command, #shell_init, #shell_read, #shell_write, type, #type
Methods included from Rex::Ui::Text::Resource
Methods included from Scriptable
#execute_file, #execute_script, included, #legacy_script_to_post_module
Methods included from Msf::Session::Provider::SingleCommandShell
#command_termination, #set_is_echo_shell, #shell_close, #shell_command_token_base, #shell_command_token_unix, #shell_command_token_win32, #shell_init, #shell_read, #shell_read_until_token, #shell_write
Methods included from Msf::Session::Basic
Methods included from Msf::Session::Interactive
#_interact, #_interact_complete, #_interrupt, #_suspend, #_usr1, #abort_foreground, #abort_foreground_supported, #cleanup, #comm_channel, #interactive?, #kill, #run_cmd, #tunnel_local, #tunnel_peer, #user_want_abort?
Methods included from Rex::Ui::Interactive
#_interact, #_interact_complete, #_interrupt, #_local_fd, #_remote_fd, #_stream_read_local_write_remote, #_stream_read_remote_write_local, #_suspend, #_winch, #detach, #handle_suspend, #handle_usr1, #handle_winch, #interact, #interact_stream, #prompt, #prompt_yesno, #restore_suspend, #restore_usr1, #restore_winch
Methods included from Rex::Ui::Subscriber
Methods included from Rex::Ui::Subscriber::Input
Methods included from Rex::Ui::Subscriber::Output
#flush, #print, #print_blank_line, #print_error, #print_good, #print_line, #print_status, #print_warning
Methods included from Msf::Session
#alive?, #cleanup, #comm_channel, #dead?, #desc, #inspect, #interactive?, #kill, #log_file_name, #log_source, #name, #name=, #register?, #session_host, #session_host=, #session_port, #session_port=, #session_type, #set_from_exploit, #set_via, #tunnel_local, #tunnel_peer, #tunnel_to_s, type, #type, #via_exploit, #via_payload
Constructor Details
#initialize(*args) ⇒ CommandShellWindows
Returns a new instance of CommandShellWindows.
4 5 6 7 |
# File 'lib/msf/base/sessions/command_shell_windows.rb', line 4 def initialize(*args) self.platform = "windows" super end |
Class Method Details
.argv_to_commandline(args) ⇒ Object
Convert the executable and argument array to a commandline that can be passed to CreateProcessAsUserW.
42 43 44 45 46 47 48 |
# File 'lib/msf/base/sessions/command_shell_windows.rb', line 42 def self.argv_to_commandline(args) escaped_args = args.map do |arg| escape_arg(arg) end escaped_args.join(' ') end |
.escape_arg(arg) ⇒ Object
Escape an individual argument per Windows shell rules
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/msf/base/sessions/command_shell_windows.rb', line 52 def self.escape_arg(arg) needs_quoting = space_chars.any? do |char| arg.include?(char) end # Fix the weird behaviour when backslashes are treated differently when immediately prior to a double-quote # We need to send double the number of backslashes to make it work as expected # See: https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw#remarks arg = arg.gsub(/(\\*)"/, '\\1\\1"') # Quotes need to be escaped arg = arg.gsub('"', '\\"') if needs_quoting # At the end of the argument, we're about to add another quote - so any backslashes need to be doubled here too arg = arg.gsub(/(\\*)$/, '\\1\\1') arg = "\"#{arg}\"" end # Empty string needs to be coerced to have a value arg = '""' if arg == '' arg end |
.escape_cmd(executable) ⇒ Object
Escape a process for the command line
25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/msf/base/sessions/command_shell_windows.rb', line 25 def self.escape_cmd(executable) needs_quoting = space_chars.any? do |char| executable.include?(char) end if needs_quoting executable = "\"#{executable}\"" end executable end |
.space_chars ⇒ Object
9 10 11 |
# File 'lib/msf/base/sessions/command_shell_windows.rb', line 9 def self.space_chars [' ', '\t', '\v'] end |
.to_cmd(cmd_and_args) ⇒ Object
Convert the executable and argument array to a command that can be run in this command shell
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 |
# File 'lib/msf/base/sessions/command_shell_windows.rb', line 79 def self.to_cmd(cmd_and_args) # The space, caret and quote chars need to be inside double-quoted strings. # The percent character needs to be escaped using a caret char, while being outside a double-quoted string. # # Situations where these two situations combine are going to be the trickiest cases: something that has quote-requiring # characters (e.g. spaces), but which also needs to avoid expanding an environment variable. In this case, # the string needs to end up being partially quoted; with parts of the string in quotes, but others (i.e. bits with percents) not. # For example: # 'env var is %temp%, yes, %TEMP%' needs to end up as '"env var is "^%temp^%", yes, "^%TEMP^%' # # There is flexibility in how you might implement this, but I think this one looks the most "human" to me, # which would make it less signaturable. # # To do this, we'll consider each argument character-by-character. Each time we encounter a percent sign, we break out of any quotes # (if we've been inside them in the current "token"), and then start a new "token". quote_requiring = ['"', '^', ' ', "\t", "\v", '&', '<', '>', '|'] escaped_cmd_and_args = cmd_and_args.map do |arg| # Escape quote chars by doubling them up, except those preceeded by a backslash (which are already effectively escaped, and handled below) arg = arg.gsub(/([^\\])"/, '\\1""') arg = arg.gsub(/^"/, '""') result = CommandShell._glue_cmdline_escape(arg, quote_requiring, '%', '^%', '"') # Fix the weird behaviour when backslashes are treated differently when immediately prior to a double-quote # We need to send double the number of backslashes to make it work as expected # See: https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw#remarks result.gsub!(/(\\*)"/, '\\1\\1"') # Empty string needs to be coerced to have a value result = '""' if result == '' result end escaped_cmd_and_args.join(' ') end |
Instance Method Details
#shell_command_token(cmd, timeout = 10) ⇒ Object
13 14 15 |
# File 'lib/msf/base/sessions/command_shell_windows.rb', line 13 def shell_command_token(cmd,timeout = 10) shell_command_token_win32(cmd,timeout) end |
#to_cmd(cmd_and_args) ⇒ Object
Convert the executable and argument array to a command that can be run in this command shell
19 20 21 |
# File 'lib/msf/base/sessions/command_shell_windows.rb', line 19 def to_cmd(cmd_and_args) self.class.to_cmd(cmd_and_args) end |