Skip to content

Commit

Permalink
Handle weird PowerShell edge case
Browse files Browse the repository at this point in the history
  • Loading branch information
smashery committed Oct 16, 2024
1 parent 205adfe commit 9972587
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 1 deletion.
11 changes: 11 additions & 0 deletions lib/msf/base/sessions/powershell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ def self.to_cmd(cmd_and_args)
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
Expand Down
2 changes: 1 addition & 1 deletion spec/lib/msf/base/sessions/command_shell_windows_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
end

it 'should handle the weird backslash escaping behaviour in front of quotes' do
expect(described_class.to_cmd(['test.exe'] + ['quote\\\\"'])).to eq('test.exe "quote\\\\\\\\"""')
expect(described_class.to_cmd(['test.exe'] + ['quote\\\\"'])).to eq('test.exe "quote\\\\\\\\""')
expect(described_class.to_cmd(['test.exe'] + ['will be quoted\\\\'])).to eq('test.exe "will be quoted\\\\\\\\"')
expect(described_class.to_cmd(['test.exe'] + ['will be quoted\\\\ '])).to eq('test.exe "will be quoted\\\\ "') # Should not be doubled up
expect(described_class.to_cmd(['test.exe'] + ['"test"', 'test\\"', 'test\\\\"', 'test words\\\\\\\\', 'test words\\\\\\', '\\\\'])).to eq('test.exe """test""" "test\\\\"" "test\\\\\\\\"" "test words\\\\\\\\\\\\\\\\" "test words\\\\\\\\\\\\" \\\\')
Expand Down
4 changes: 4 additions & 0 deletions test/modules/post/test/cmd_exec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ def valid_show_args_response?(output, expected:)

# Match the binary name, to support the binary name containing relative or absolute paths, i.e.
# "show_args.exe\r\none\r\ntwo",
if output_binary.nil?
vprint_status("#{__method__}: Malformed output: no process binary returned")
return false
end
match = output_binary.include?(expected[0]) && output_args == expected[1..]
if !match
vprint_status("#{__method__}: expected: #{expected.inspect} - actual: #{output_lines.inspect}")
Expand Down

0 comments on commit 9972587

Please sign in to comment.