Skip to content

Commit

Permalink
Don't do any escaping on platforms with unknown escaping
Browse files Browse the repository at this point in the history
  • Loading branch information
smashery committed Jan 10, 2025
1 parent 851beb7 commit e024c11
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 21 deletions.
4 changes: 4 additions & 0 deletions lib/metasploit/framework/ssh/platform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ def self.get_platform_info(ssh_socket, timeout: 10)
info
end

def self.is_posix(platform)
return ['unifi','linux','osx','solaris','bsd','hpux','aix'].include?(platform)
end

def self.get_platform_from_info(info)
case info
when /unifi\.version|UniFiSecurityGateway/i # Ubiquiti Unifi. uname -a is left in, so we got to pull before Linux
Expand Down
2 changes: 1 addition & 1 deletion lib/msf/base/sessions/ssh_command_shell_bind.rb
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def bootstrap(datastore = {}, handler = nil)
@platform = Metasploit::Framework::Ssh::Platform.get_platform(ssh_connection)
if @platform == 'windows'
extend(Msf::Sessions::WindowsEscaping)
else
elsif Metasploit::Framework::Ssh::Platform.is_posix(@platform)
extend(Msf::Sessions::UnixEscaping)
end

Expand Down
36 changes: 16 additions & 20 deletions lib/msf/base/sessions/windows_escaping.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,34 @@ def escape_cmd(executable)
# to cmd.exe, whereas this is expected to be passed directly to the Win32 API, anticipating that it
# will in turn be interpreted by CommandLineToArgvW.
def argv_to_commandline(args)
escaped_args = args.map do |arg|
escape_arg(arg)
end
escaped_args = args.map { |arg| escape_arg(arg) }

escaped_args.join(' ')
end

# Escape an individual argument per Windows shell rules
# @param arg [String] Shell argument
def escape_arg(arg)
needs_quoting = space_chars.any? do |char|
arg.include?(char)
end
needs_quoting = space_chars.any? { |char| arg.include?(char) }

# 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"')
# 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('"', '\\"')
# 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
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 == ''
# Empty string needs to be coerced to have a value
arg = '""' if arg == ''

arg
arg
end

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

0 comments on commit e024c11

Please sign in to comment.