Skip to content

Warn user if they are using PowerShell with impersonation #20180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions lib/rex/post/meterpreter/extensions/powershell/powershell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ def import_file(opts={})
request.add_tlv(TLV_TYPE_POWERSHELL_ASSEMBLY_SIZE, binary.length)
request.add_tlv(TLV_TYPE_POWERSHELL_ASSEMBLY, binary)
client.send_request(request)
return true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is an API change, have all the callers of this API been updated to support this result type?

return { loaded: true }
end

return false
return { loaded: false }
end

def session_remove(opts={})
Expand All @@ -75,7 +75,14 @@ def execute_string(opts={})
request.add_tlv(TLV_TYPE_POWERSHELL_SESSIONID, opts[:session_id]) if opts[:session_id]

response = client.send_request(request)
return response.get_tlv_value(TLV_TYPE_POWERSHELL_RESULT)
result = {}
handle = client.sys.config.get_token_handle()
if handle != 0
result[:warning] = 'Impersonation will not apply to PowerShell.'
end

result[:output] = response.get_tlv_value(TLV_TYPE_POWERSHELL_RESULT)
return result
end

def shell(opts={})
Expand All @@ -87,7 +94,16 @@ def shell(opts={})
if channel_id.nil?
raise Exception, "We did not get a channel back!"
end
Rex::Post::Meterpreter::Channels::Pools::StreamPool.new(client, channel_id, 'powershell_psh', CHANNEL_FLAG_SYNCHRONOUS, response)

result = {}
handle = client.sys.config.get_token_handle()
if handle != 0
result[:warning] = 'Impersonation will not apply to PowerShell.'
end

result[:channel] = Rex::Post::Meterpreter::Channels::Pools::StreamPool.new(client, channel_id, 'powershell_psh', CHANNEL_FLAG_SYNCHRONOUS, response)

result
end

end
Expand Down
1 change: 1 addition & 0 deletions lib/rex/post/meterpreter/extensions/stdapi/command_ids.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ module Stdapi
COMMAND_ID_STDAPI_SYS_PROCESS_SET_TERM_SIZE = EXTENSION_ID_STDAPI + 118
COMMAND_ID_STDAPI_SYS_PROCESS_MEMORY_SEARCH = EXTENSION_ID_STDAPI + 119
COMMAND_ID_STDAPI_SYS_CONFIG_UPDATE_TOKEN = EXTENSION_ID_STDAPI + 120
COMMAND_ID_STDAPI_SYS_CONFIG_GET_TOKEN_HANDLE = EXTENSION_ID_STDAPI + 121


end; end; end; end; end
Expand Down
9 changes: 9 additions & 0 deletions lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,15 @@ def update_token(token_handle)
end

#
# Gets the current impersonation token
#
def get_token_handle()
req = Packet.create_request(COMMAND_ID_STDAPI_SYS_CONFIG_GET_TOKEN_HANDLE)
res = client.send_request(req)
res.get_tlv_value(TLV_TYPE_HANDLE)
end

#
# Enables all possible privileges
#
def getprivs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,14 @@ def cmd_powershell_shell(*args)
end
}

channel = client.powershell.shell(opts)
result = client.powershell.shell(opts)

channel = result[:channel]

if result[:warning].present?
print_warning(result[:warning])
end

shell.interact_with_channel(channel)
end

Expand Down Expand Up @@ -144,12 +151,17 @@ def cmd_powershell_import(*args)
}

result = client.powershell.import_file(opts)
if result.nil? || result == false

if result[:warning].present?
print_warning(result[:warning])
end

if result[:loaded] == false
print_error('File failed to load. The file must end in ".ps1" or ".dll".')
elsif result == true || result.empty?
elsif result[:loaded] == true || result[:output].empty?
print_good("File successfully imported. No result was returned.")
else
print_good("File successfully imported. Result:\n#{result}")
print_good("File successfully imported. Result:\n#{result[:output]}")
end
end

Expand Down Expand Up @@ -186,7 +198,10 @@ def cmd_powershell_execute(*args)
}

result = client.powershell.execute_string(opts)
print_good("Command execution completed:\n#{result}")
if result[:warning].present?
print_warning(result[:warning])
end
print_good("Command execution completed:\n#{result[:output]}")
end

end
Expand Down
Loading