Invoke-PortKnock/Invoke-PortKnock.ps1
2021-09-13 13:43:33 -06:00

101 lines
2.7 KiB
PowerShell

<#
.SYNOPSIS
PowerShell script that knocks on a given sets of ports. It can optionally take an execute parameter to run a secondary script after the knocking is complete.
.DESCRIPTION
PowerShell script that knocks on a given sets of ports. It can optionally take an execute parameter to run a secondary script after the knocking is complete.
.PARAMETER Knock_Ports
Object Array for of the sequence of ports that should be knocked. The array must follow the following pattern.
Destination, Port, Protocol
.PARAMETER Delay
The time to pause between knocks in milliseconds. Defaults to 200 milliseconds.
.PARAMETER Execute
Optional command that will be run after the knocking sequence is complete. This is passed directly to a Invoke-Expression command.
.EXAMPLE
$Knock_Ports = @(
("10.1.1.1", 36041, "TCP"),
("10.1.1.1", 38097, "UDP"),
("10.1.1.1", 27079, "TCP")
)
PortKnock.ps1 -Knock_Ports $Knock_Ports
.NOTES
Version: 1.0
Author: Tyler Hale
Creation Date: 2021.09.13
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[Object[]]
$Knock_Ports,
[Parameter(Mandatory = $false)]
[int]
$Delay = 200,
[Parameter(Mandatory = $false)]
[string]
$Execute
)
$ErrorDetected = $False
foreach ($Knock in $Knock_Ports) {
if (!([ipaddress]::TryParse("$($Knock[0])",[ref][ipaddress]::Loopback))) {
$DNS_Resolve = (Resolve-DnsName $Knock[0])
$Knock_Destination = $DNS_Resolve.IP4Address
}
else {
$Knock_Destination = $Knock[0]
}
$Knock_Port = $Knock[1]
$Knock_Protocol = $Knock[2]
try {
switch ($Knock_Protocol) {
"TCP" {
$tcpClient = New-Object System.Net.Sockets.TcpClient
$tcpClient.BeginConnect($Knock_Destination, $Knock_Port, $null, $null) | Out-Null
$tcpClient.Close() | Out-Null
}
"UDP" {
$udpClient = New-Object System.Net.Sockets.UdpClient
$udpClient.Connect($Knock_Destination, $Knock_Port) | Out-Null
$udpClient.Send([byte[]](0), 1) | Out-Null
$udpClient.Close() | Out-Null
}
default {
throw "Protocol not found $Knock_Protocol"
}
}
Write-Verbose "Sent $Knock_Protocol packet to $($Knock_Destination):$Knock_Port"
}
catch {
Write-Error $_
$ErrorDetected = $True
}
Start-Sleep -Milliseconds $Delay
}
if ($ErrorDetected) {
Write-Warning "Knock may not have completed successfully"
}
else {
Write-Host "Knock Complete"
if ($null,"" -ne $Execute) {
Write-Verbose "Invoking command: $Execute"
Invoke-Expression -Command $Execute
}
}