Invoke-PortKnock/Invoke-PortKnock.ps1

102 lines
2.7 KiB
PowerShell
Raw Permalink Normal View History

2021-09-13 13:43:33 -06:00
<#
.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
}
}