From 052f57ba4fb689d030a9def8d5172fb8c3ef37d3 Mon Sep 17 00:00:00 2001 From: cgranleese-r7 Date: Wed, 21 Aug 2024 11:30:39 +0100 Subject: [PATCH] Debug powershell --- lib/msf/core/payload/windows/powershell.rb | 10 +++--- spec/acceptance/non_meterpreter_spec.rb | 7 ++-- spec/support/acceptance/child_process.rb | 36 +++++++++++++++++++ .../acceptance/non_meterpreter/powershell.rb | 8 ++--- 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/lib/msf/core/payload/windows/powershell.rb b/lib/msf/core/payload/windows/powershell.rb index 0ba12ed10a89e..f41954e9f45ff 100644 --- a/lib/msf/core/payload/windows/powershell.rb +++ b/lib/msf/core/payload/windows/powershell.rb @@ -57,11 +57,12 @@ def generate_powershell_code(conntype) script_in.gsub!('LHOST_REPLACE', lhost.to_s) script = Rex::Powershell::Command.compress_script(script_in) + # script = script_in command_args = { - noprofile: true, - windowstyle: 'hidden', - noninteractive: true, - executionpolicy: 'bypass' + # noprofile: true, + # windowstyle: 'hidden', + # noninteractive: true, + # executionpolicy: 'bypass' } cli = Rex::Powershell::Command.generate_psh_command_line(command_args) return "#{cli} \"#{script}\"" @@ -72,4 +73,3 @@ def command_string end end end - diff --git a/spec/acceptance/non_meterpreter_spec.rb b/spec/acceptance/non_meterpreter_spec.rb index 46385353a0724..02fc79c485053 100644 --- a/spec/acceptance/non_meterpreter_spec.rb +++ b/spec/acceptance/non_meterpreter_spec.rb @@ -141,17 +141,18 @@ def initialize(path) session_id = nil # Wait for the session to open, or break early if the payload is detected as dead - wait_for_expect do + larger_retry_count_for_powershell = 600 + wait_for_expect(larger_retry_count_for_powershell) do unless payload_process.alive? break end # TODO: Was strictly for Meterpreter sessions, now more generic # - can be reverted if we decide to move these new tests - session_opened_matcher = /\w.* session (\d+) opened[^\n]*\n/ + session_opened_matcher = /session (\d+) opened[^\n]*\n/ session_message = '' begin - session_message = console.recvuntil(session_opened_matcher, timeout: 1) + session_message = console.recvuntil_debug(session_opened_matcher, timeout: 1) rescue Acceptance::ChildProcessRecvError # noop end diff --git a/spec/support/acceptance/child_process.rb b/spec/support/acceptance/child_process.rb index cb70f50f3043e..fc07b8e3c08b0 100644 --- a/spec/support/acceptance/child_process.rb +++ b/spec/support/acceptance/child_process.rb @@ -101,6 +101,42 @@ def recvuntil(delim, timeout: @default_timeout, drop_delim: false) raise ChildProcessRecvError, "Failed #{__method__}: Did not match #{delim.inspect}, process was alive?=#{alive?.inspect}, remaining buffer: #{self.buffer.string[self.buffer.pos..].inspect}" end + + def recvuntil_debug(delim, timeout: @default_timeout, drop_delim: false) + buffer = '' + result = nil + + with_countdown(timeout) do |countdown| + while alive? && !countdown.elapsed? + data_chunk = recv(timeout: [countdown.remaining_time, 1].min) + if !data_chunk + next + end + + buffer += data_chunk + $stderr.puts "Attempting o to match buffer: #{buffer.inspect} with delim #{delim.inspect}" + has_delimiter = delim.is_a?(Regexp) ? buffer.match?(delim) : buffer.include?(delim) + next unless has_delimiter + + result, matched_delim, remaining = buffer.partition(delim) + unless drop_delim + result += matched_delim + end + unrecv(remaining) + # Reset the temporary buffer to avoid the `ensure` mechanism unrecv'ing the buffer unintentionally + buffer = '' + + return result + end + ensure + unrecv(buffer) + end + + result + rescue ChildProcessTimeoutError + raise ChildProcessRecvError, "Failed #{__method__}: Did not match #{delim.inspect}, process was alive?=#{alive?.inspect}, remaining buffer: #{self.buffer.string[self.buffer.pos..].inspect}" + end + # @return [String] Recv until additional reads would cause a block, or eof is reached, or a maximum timeout is reached def recv_available(timeout: @default_timeout) result = '' diff --git a/spec/support/acceptance/non_meterpreter/powershell.rb b/spec/support/acceptance/non_meterpreter/powershell.rb index 5cfc8de3bd32a..49f7ea63953b0 100644 --- a/spec/support/acceptance/non_meterpreter/powershell.rb +++ b/spec/support/acceptance/non_meterpreter/powershell.rb @@ -4,13 +4,13 @@ module Acceptance::NonMeterpreter POWERSHELL = { payloads: [ { - name: 'windows/x64/powershell_reverse_tcp', - extension: '.exe', + name: 'cmd/windows/powershell_reverse_tcp', + extension: '.ps1', platforms: [:windows], - execute_cmd: ['${payload_path}'], + execute_cmd: ['./${payload_path}'], executable: true, generate_options: { - '-f': 'exe' + '-f': 'raw' }, datastore: { global: {},