PowerShell System Port Scans
R. Eric Kiser

During a penetration test, it’s common to use various types of scans to identify vulnerabilities and potential entry points. However, many organizations have endpoint security measures in place that can block or detect these scans. In these cases, a more sophisticated and targeted approaches are needed. I call this the “Swedish carving knife” method, versus using a broad and blunt “hatchet” method. One solution to this is to use PowerShell to perform a simple port scan, which can often evade detection and provide valuable information about open ports and potential vulnerabilities.
The script provided will gather the IP address of the system and perform a targeted port scan. By specifying the specific ports you wish to scan, the process is made more efficient and stealthy, which can make it faster and less likely to be detected.
$ip = (Test-Connection -ComputerName $env:COMPUTERNAME -Count 1).IPV4Address.IPAddressToString
Write-Host "IP address of this system is: $ip"
$commonPorts = @(20, 21, 22, 23, 25, 53, 80, 110, 123, 135, 137, 139, 143, 389, 443, 445, 3389, 8080, 8888, 8081)
foreach ($port in $commonPorts) {
$tcpClient = New-Object System.Net.Sockets.TcpClient
try {
$tcpClient.Connect($ip, $port)
if ($tcpClient.Connected) {
Write-Host "Port $port is open"
}
$tcpClient.Close()
} catch {
# Do nothing on exception
}
}Explanation :
The $ip variable: This variable is used to store the current IP address of the system the script is running on. The Test-Connection cmdlet is used to ping the local computer and retrieve its IP address using the $env:COMPUTERNAME environment variable. The .IPV4Address.IPAddressToString property is used to extract the IP address from the output of the Test-Connection cmdlet.
The $commonPorts variable: This variable is an array that contains a list of the most common open ports.
The foreach loop: This loop iterates over each port in the $commonPorts array and calls the Test-Port function for each port.
The $tcpClient variable: This variable is used to create a new instance of the TcpClient class from the System.Net.Sockets namespace.
The try-catch
block: This block of code is used to catch any errors that may occur
while trying to connect to the host on the specified port. The try block contains the code that may raise an exception, and the catch block contains the code that will be executed if an exception is raised.
The $tcpClient.Connect() method: This method is used to connect to the localhost on the specified port.
The if statement: This statement checks if the $tcpClient is connected to the remote host and if it is it prints the port as open.
The $tcpClient.Close() method: This method is used to close the TcpClient connection.
Web Applications using netstat port scan
The following script will complete a port scan for web applications by using netstat on a local machine to discover internal resources
$webPorts = @(80, 443, 8000, 8080, 8888)
$ips = netstat -ano | Select-String ":80|:8000|:8080|:8888" | % {$_ -split ' '} | select -Unique
foreach ($ip in $ips) {
foreach ($port in $webPorts) {
$tcpClient = New-Object System.Net.Sockets.TcpClient
try {
$tcpClient.Connect($ip, $port)
if ($tcpClient.Connected) {
Write-Host "IP: $ip Port $port is open"
}
$tcpClient.Close()
} catch {
# Do nothing on exception
}
}
}Explanation :
The $webPorts variable: This variable is an array that contains a list of web application ports.
The $ips variable: This variable is used to store the list of IP addresses discovered by running the netstat command with the -ano parameters, which shows active connections and their associated process IDs. The Select-String cmdlet is used to filter the output for the IP addresses that are listening on the ports specified in the $webPorts array. The % {$_ -split ' '} operator is used to split the output into an array of strings, and the select -Unique cmdlet is used to remove any duplicates.
The first foreach loop: This loop iterates over each IP address in the $ips array.
The second foreach loop: This loop iterates over each port in the $webPorts array.
The $tcpClient variable: This variable is used to create a new instance of the TcpClient class from the System.Net.Sockets namespace.
The try-catch block: This block of code is used to catch any errors that may occur while trying to connect to the host on
Grab the host file and port scan discovered IP
This script will grab the host file on a system and print discovered IP addresses. It will then take those IP addresses and scan them for open ports. This is useful when trying to discover internal resources that the current user has access too.
$hostFile = Get-Content "C:\Windows\System32\drivers\etc\hosts"
$ipList = @()
foreach ($line in $hostFile) {
if ($line -match "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b") {
$ip = $matches[0]
$ipList += $ip
}
}
$commonPorts = "21","22","23","25","80","443","8080","8081","8888"
foreach ($ip in $ipList) {
Write-Host "Scanning IP: $ip"
foreach ($port in $commonPorts) {
$connection = New-Object System.Net.Sockets.TcpClient
try {
$connection.Connect($ip, $port)
Write-Host "Port $port is open on IP $ip" -ForegroundColor Green
$connection.Close()
} catch {
Write-Host "Port $port is closed on IP $ip" -ForegroundColor Red
}
}
}Explanation :
- The
$hostFilevariable: This variable is used to store the content of the host file by running theGet-Contentcmdlet and passing the path to the host file. The path is set to the host file location in windows. - The
$ipListvariable: This variable is an empty array that will be used to store the IP addresses that are found in the host file. - The first
foreachloop: This loop iterates over each line in the$hostFilevariable, checks if the line matches the regular expression pattern of an IP address and assigns the matched IP address to the variable$ip. Then it adds the value of$ipto the$ipListarray. - The
$commonPortsvariable: This variable is an array that contains a list of common ports that the script will scan. - The outer
foreachloop: This loop iterates over each IP address in the$ipListarray and assigns the current IP address to the variable$ip. - The
Write-Hoststatement: This statement prints the current IP address that the script is scanning. - The inner
foreachloop: This loop iterates over each port in the$commonPortsarray and assigns the current port to the variable$port. - The
$connectionvariable: This variable is used to create a new TCP client connection to the current IP address and port. - The
try-catchblock: This block attempts to connect to the current IP address and port using the$connectionvariable. If the connection is successful, it will print "Port $port is open on IP $ip" in green. If the connection is not successful, it will print "Port $port is closed on IP $ip" in red. - The
$connection.Close()method: This method is used to close the connection after each iteration.
Comments
Post a Comment