Public/Network/Scan-NetworkforWebLogonPages.ps1
|
FUNCTION Scan-NetworkforWebLogon { [CmdletBinding()] PARAM ( $CIDR, $TimeountSeconds = 3 ) FUNCTION Get-IPRangeFromCIDR { Param( [Parameter(Mandatory=$true, HelpMessage="Enter a subnet in the form a.b.c.d/m")] [string]$Cidr ) # Split the CIDR notation into IP and prefix length $parts = $Cidr -split "/" $ipAddressString = $parts[0] [int]$prefixLength = $parts[1] # Convert the IP address to a 32-bit integer for bitwise operations $ip = [System.Net.IPAddress]::Parse($ipAddressString) [byte[]]$ipBytes = $ip.GetAddressBytes() [Array]::Reverse($ipBytes) # Reverse to match little-endian byte order [UInt32]$ipUint = [System.BitConverter]::ToUInt32($ipBytes, 0) # Calculate the network mask (e.g., /24 is 255.255.255.0) [UInt32]$maskUint = [UInt32]::MaxValue -shr (32 - $prefixLength) -shl (32 - $prefixLength) # Calculate the network ID (first IP) and broadcast address (last IP) using bitwise operations [UInt32]$networkIdUint = $ipUint -band $maskUint [UInt32]$broadcastUint = $ipUint -bor (-bnot $maskUint) # Convert the integer results back to IPAddress objects [byte[]]$networkBytes = [System.BitConverter]::GetBytes($networkIdUint) [Array]::Reverse($networkBytes) [System.Net.IPAddress]$firstIP = [System.Net.IPAddress]::New($networkBytes) [byte[]]$broadcastBytes = [System.BitConverter]::GetBytes($broadcastUint) [Array]::Reverse($broadcastBytes) [System.Net.IPAddress]$lastIP = [System.Net.IPAddress]::New($broadcastBytes) # Return a custom object with the results return [pscustomobject][ordered]@{ CIDR = $Cidr FirstIP = $firstIP.IPAddressToString LastIP = $lastIP.IPAddressToString NetworkID = $firstIP.IPAddressToString # First IP is generally the network ID Broadcast = $lastIP.IPAddressToString # Last IP is the broadcast address } } FUNCTION Get-IPRange { param( [Parameter(Mandatory=$true)] [string]$StartIP, [Parameter(Mandatory=$true)] [string]$EndIP ) # Convert the IP addresses to numerical values for iteration # The bytes need to be reversed due to Endianness differences between network order and system's UInt32 representation $start_bytes = ([System.Net.IPAddress]$StartIP).GetAddressBytes() [Array]::Reverse($start_bytes) $start_int = [System.BitConverter]::ToUInt32($start_bytes, 0) $end_bytes = ([System.Net.IPAddress]$EndIP).GetAddressBytes() [Array]::Reverse($end_bytes) $end_int = [System.BitConverter]::ToUInt32($end_bytes, 0) # Ensure start IP is not greater than end IP if ($start_int -gt $end_int) { Write-Error "Start IP address must be less than or equal to End IP address." return } $ip_range = @() for ($i = $start_int+1; $i -le $end_int-1; $i++) { # Convert the integer back to an IP address byte array, reverse it again, and join the octets $ip_bytes = [System.BitConverter]::GetBytes([UInt32]$i) [Array]::Reverse($ip_bytes) $ip_string = ($ip_bytes -join '.') $ip_range += $ip_string } return $ip_range } FUNCTION Test-TCPPorts { <# .SYNOPSIS Tests TCP connectivity to a specified host on multiple ports asynchronously. .DESCRIPTION Tests TCP connectivity to a specified hostname or IP address on ports 1-1024, 4443, 4444, 8000, 8080, 8443, and 10443. Runs tests asynchronously with a maximum of 100 concurrent tests and displays a progress bar. .PARAMETER ComputerName The hostname or IP address to test connectivity against. .PARAMETER Timeout The timeout in milliseconds for each TCP connection attempt. Default is 2000ms. .EXAMPLE Test-TCPPorts -ComputerName "example.com" Tests TCP connectivity to example.com on specified ports. .EXAMPLE Test-TCPPorts -ComputerName "192.168.1.1" -Timeout 1000 Tests TCP connectivity to 192.168.1.1 with a 1000ms timeout. .OUTPUTS PSCustomObject with properties: ComputerName, Port, IsOpen, Error (if any). #> [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string]$ComputerName, [Parameter()] [int]$Timeout = 1200 ) # Define the ports to test $ports = @() $ports = 80, 443, 4433, 4443, 4444, 8000, 8080, 8443, 10443 $ports = $ports | Sort-Object -Unique $totalPorts = $ports.Count $results = [System.Collections.ArrayList]::new() $completed = 0 # Create a runspace pool $runspacePool = [RunspaceFactory]::CreateRunspacePool(1, 50) $runspacePool.Open() $tasks = [System.Collections.ArrayList]::new() # ScriptBlock for testing a single port $scriptBlock = { param ($ComputerName, $Port, $Timeout) $result = [PSCustomObject]@{ ComputerName = $ComputerName Port = $Port IsOpen = $false } try { $tcpClient = New-Object System.Net.Sockets.TcpClient $connection = $tcpClient.BeginConnect($ComputerName, $Port, $null, $null) $success = $connection.AsyncWaitHandle.WaitOne($Timeout, $false) if ($success) { $tcpClient.EndConnect($connection) $result.IsOpen = $true } $tcpClient.Close() } catch { $result.Error = $_.Exception.Message } finally { if ($null -ne $tcpClient) { $tcpClient.Dispose() } } return $result | Where-Object { $_.IsOpen -eq $True } } # Create async tasks for each port foreach ($port in $ports) { $powershell = [PowerShell]::Create() $powershell.RunspacePool = $runspacePool [void]$powershell.AddScript($scriptBlock).AddArgument($ComputerName).AddArgument($port).AddArgument($Timeout) $handle = $powershell.BeginInvoke() $tasks.Add([PSCustomObject]@{ PowerShell = $powershell Handle = $handle Port = $port }) | Out-Null } # Process tasks and update progress while ($tasks.Count -gt 0) { $completedTasks = $tasks | Where-Object { $_.Handle.IsCompleted } foreach ($task in $completedTasks) { $result = $task.PowerShell.EndInvoke($task.Handle) if ($result.IsOpen) { [void]$results.Add($result) } $task.PowerShell.Dispose() $tasks.Remove($task) $completed++ # Update progress bar $percentComplete = [math]::Round(($completed / $totalPorts) * 100, 2) Write-Progress -Activity "Testing TCP Ports on $ComputerName" ` -Status "Tested $completed of $totalPorts ports" ` -PercentComplete $percentComplete -Id 120932315 } # Small sleep to prevent excessive CPU usage Start-Sleep -Milliseconds 100 } # Clean up $runspacePool.Close() $runspacePool.Dispose() # Complete the progress bar Write-Progress -Id 120932315 -Activity "Testing TCP Ports on $ComputerName" -Completed # Return results sorted by port return $results | Sort-Object Port } FUNCTION ParseWebContentforDeviceInfo { [CmdletBinding()] PARAM ( $Page ) $Result = [PSCustomObject]@{ DeviceType = $null DeviceManufacturer = $null DeviceModel = $null LoginPage = "Unknown" } IF ($Page.Content -like "* ARRIS *") { $Result.DeviceManufacturer = "ARRIS" ; $Result.DeviceType = "Modem\Router" } RETURN $Result } $IPs = Get-IPRange -StartIP (Get-IPRangeFromCIDR $CIDR).FirstIP -EndIP (Get-IPRangeFromCIDR $CIDR).LastIP $ScanResults = @() $DeviceInfo = $Null $IPCount = $IPs.Count $IPCountCurrent = 0 $Protocol = $null FOREACH ($IP in $IPs) { $IPCountCurrent++ $PercentProgress = [Math]::Round($($(($IPCountCurrent-1)/$IPCount)*100),0) Write-Progress -Id 120932316 -Activity "$PercentProgress% - Checking for Open Ports on $IP" -Status "Checking IP $IPCountCurrent of $IPCount" -PercentComplete $PercentProgress $Protocol = $null $OpenPorts = (Test-TCPPorts $IP).Port FOREACH ($OpenPort in $OpenPorts) { $Page = $null TRY { #IF ($OpenPort -ne 80) { [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } $Page = Invoke-WebRequest -Uri "https://$($IP):$OpenPort/" -UseBasicParsing -TimeoutSec $TimeountSeconds -ErrorAction SilentlyContinue $Protocol = "HTTPS" #} } CATCH { TRY { #IF ($OpenPort -ne 433) { [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } $Page = Invoke-WebRequest -Uri "http://$($IP):$OpenPort/" -UseBasicParsing -TimeoutSec $TimeountSeconds -ErrorAction SilentlyContinue $Protocol = "HTTP" #} } CATCH { } } IF ($Page -eq $null -or $Page -eq "") { $ScanResults += [PSCustomObject]@{ PSTypeName = 'IntegrisPowerShell.NetworkforWebLogonPages' IPAddress = $IP Port = $OpenPort Protocol = $Protocol Type = $null Manufacturer = $null Model = $null LoginPage = "No" } } ELSE { $DeviceInfo = ParseWebContentforDeviceInfo $Page $ScanResults += [PSCustomObject]@{ PSTypeName = 'IntegrisPowerShell.NetworkforWebLogonPages' IPAddress = $IP Port = $OpenPort Protocol = $Protocol Type = $DeviceInfo.DeviceType Manufacturer = $DeviceInfo.DeviceManufacturer Model = $DeviceInfo.DeviceModel LoginPage = $DeviceInfo.LoginPage } } } } Write-Progress -Id 120932316 -Activity "(($IPCountCurrent/$IPCount)*100)% - Checking for Open Ports on $IP" -Completed RETURN $ScanResults } |