Class: Msf::Sessions::PowerShell

Inherits:
CommandShell show all
Includes:
Mixin
Defined in:
lib/msf/base/sessions/powershell.rb

Defined Under Namespace

Modules: Mixin

Instance Attribute Summary

Attributes inherited from CommandShell

#arch, #banner, #max_threads

Attributes included from Msf::Session::Interactive

#rstream

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

#user_input

Attributes included from Rex::Ui::Subscriber::Output

#user_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

#framework

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixin

#shell_command

Methods inherited from CommandShell

#_file_transfer, _glue_cmdline_escape, #_interact, #_interact_stream, #abort_foreground_supported, binary_exists, #binary_exists, #bootstrap, #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, #docs_dir, #escape_arg, #execute_file, #initialize, #run_builtin_cmd, #run_single, #shell_close, #shell_command, #shell_init, #shell_read, #shell_write, #type

Methods included from Rex::Ui::Text::Resource

#load_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, #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

#_interact, #type

Methods included from Msf::Session::Interactive

#_interact, #_interact_complete, #_interrupt, #_suspend, #_usr1, #abort_foreground, #abort_foreground_supported, #cleanup, #comm_channel, #initialize, #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

#copy_ui, #init_ui, #reset_ui

Methods included from Rex::Ui::Subscriber::Input

#gets

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?, #initialize, #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, #via_exploit, #via_payload

Constructor Details

This class inherits a constructor from Msf::Sessions::CommandShell

Class Method Details

.can_cleanup_filesObject

[View source]

151
152
153
# File 'lib/msf/base/sessions/powershell.rb', line 151

def self.can_cleanup_files
  true
end

.to_cmd(cmd_and_args) ⇒ Object

Convert the executable and argument array to a command that can be run in this command shell

Parameters:

  • cmd_and_args (Array<String>)

    The process path and the arguments to the process

[View source]

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
# File 'lib/msf/base/sessions/powershell.rb', line 49

def self.to_cmd(cmd_and_args)
  # The principle here is that we want to launch a process such that it receives *exactly* what is in `args`. 
  # This means we need to:
  # - Escape all special characters
  # - Not escape environment variables
  # - Side-step any PowerShell magic
  # If someone specifically wants to use the PowerShell magic, they can use other APIs

  needs_wrapping_chars = ['$', '`', '(', ')', '@', '>', '<', '{','}', '&', ',', ' ', ';']

  result = ""
  cmd_and_args.each_with_index do |arg, index|
    needs_single_quoting = false
    if arg.include?("'")
      arg = arg.gsub("'", "''")
      needs_single_quoting = true
    end
    
    if arg.include?('"')
      # PowerShell acts weird around quotes and backslashes
      # First we need to escape backslashes immediately prior to a double-quote, because
      # they're treated differently than backslashes anywhere else
      arg = arg.gsub(/(\\+)"/, '\\1\\1"')

      # Then we can safely prepend a backslash to escape our double-quote
      arg = arg.gsub('"', '\\"')
      needs_single_quoting = true
    end
    
    needs_wrapping_chars.each do |char|
      if arg.include?(char)
        needs_single_quoting = true
      end
    end

    # PowerShell magic - https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_special_characters?view=powershell-7.4#stop-parsing-token---
    if arg == '--%'
      needs_single_quoting = true
    end

    will_be_double_quoted_by_powershell = [' ', '\t', '\v'].any? do |bad_char|
      arg.include?(bad_char)
    end

    if will_be_double_quoted_by_powershell
      # This is horrible, and I'm so so sorry.
      # If an argument ends with a series of backslashes, and it will be quoted by PowerShell when *it* launches the process (e.g. because the arg contains a space),
      # PowerShell will not correctly handle backslashes immediately preceeding the quote that it *itself* adds. So we need to be responsible for this.
      arg = arg.gsub(/(\\*)$/, '\\1\\1')
    end

    if needs_single_quoting
      arg = "'#{arg}'"
    end

    if arg == ''
      # Pass in empty strings
      arg = '\'""\''
    end

    if index == 0
      if needs_single_quoting
        # If the executable name (i.e. index 0) has beeen wrapped, then we'll have converted it to a string.
        # We then need to use the call operator ('&') to call it.
        # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7.3#call-operator-
        result = "& #{arg}"
      else
        result = arg
      end
    else
      result = "#{result} #{arg}"
    end
  end

  result
end

.typeObject

Returns the type of session.

[View source]

147
148
149
# File 'lib/msf/base/sessions/powershell.rb', line 147

def self.type
  'powershell'
end

Instance Method Details

#descObject

Returns the session description.

[View source]

165
166
167
# File 'lib/msf/base/sessions/powershell.rb', line 165

def desc
  'Powershell session'
end

#platformObject

Returns the session platform.

[View source]

158
159
160
# File 'lib/msf/base/sessions/powershell.rb', line 158

def platform
  'windows'
end

#process_autoruns(datastore) ⇒ Object

Execute any specified auto-run scripts for this session

[View source]

129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/msf/base/sessions/powershell.rb', line 129

def process_autoruns(datastore)
  # Read the username and hostname from the initial banner
  initial_output = shell_read(-1, 2)
  if initial_output =~ /running as user ([^\s]+) on ([^\s]+)/
    username = Regexp.last_match(1)
    hostname = Regexp.last_match(2)
    self.info = "#{username} @ #{hostname}"
  elsif initial_output
    self.info = initial_output.gsub(/[\r\n]/, ' ')
  end

  # Call our parent class's autoruns processing method
  super
end

#to_cmd(cmd_and_args) ⇒ Object

Convert the executable and argument array to a command that can be run in this command shell

Parameters:

  • cmd_and_args (Array<String>)

    The process path and the arguments to the process

[View source]

43
44
45
# File 'lib/msf/base/sessions/powershell.rb', line 43

def to_cmd(cmd_and_args)
  self.class.to_cmd(cmd_and_args)
end