1. Introdução
Um Port Scanner é uma ferramenta essencial para analistas de segurança, administradores de rede e entusiastas de cybersecurity. Ele permite identificar portas abertas em hosts, ajudando a detectar serviços em execução e possíveis vulnerabilidades. Neste artigo, vamos construir um Port Scanner do zero em PowerShell, evoluindo o código passo a passo.
Nível 1: O básico
Vamos começar com um script simples que escaneia portas em um único IP ou em um intervalo de endereços.
1function PortScan {
2 param (
3 [string]$Target, # IP único ou range (ex: 192.168.1.1-100)
4 [int[]]$Ports = @(22, 80, 443, 3389) # Lista de portas para escanear
5 )
6
7 $targets = @()
8
9 # Verifica se é um range de IPs (ex: 192.168.1.1-100)
10 if ($Target -match "(\d+\.\d+\.\d+\.\d+)-(\d+)$") {
11 $baseIP = $matches[1] -replace "\.\d+$", ""
12 $start = [int]($matches[1] -replace "^.+\.")
13 $end = [int]$matches[2]
14 for ($i = $start; $i -le $end; $i++) {
15 $targets += "$baseIP.$i"
16 }
17 } else {
18 $targets += $Target # Caso seja um único IP
19 }
20
21 # Loop pelos IPs e portas
22 foreach ($ip in $targets) {
23 Write-Host "\nScanning $ip..." -ForegroundColor Cyan
24 foreach ($port in $Ports) {
25 $result = Test-NetConnection -ComputerName $ip -Port $port -WarningAction SilentlyContinue
26 if ($result.TcpTestSucceeded) {
27 Write-Host "[+] Porta $port aberta em $ip" -ForegroundColor Green
28 } else {
29 Write-Host "[-] Porta $port fechada em $ip" -ForegroundColor Red
30 }
31 }
32 }
33}
Nível 1
1function PortScan {
2 param (
3 [string]$Target, # IP único ou range (ex: 192.168.1.1-100)
4 [int[]]$Ports = @(22, 80, 443, 3389) # Lista de portas para escanear
5 )
6
7 $targets = @()
8
9 # Verifica se é um range de IPs (ex: 192.168.1.1-100)
10 if ($Target -match "(\d+\.\d+\.\d+\.\d+)-(\d+)$") {
11 $baseIP = $matches[1] -replace "\.\d+$", ""
12 $start = [int]($matches[1] -replace "^.+\.")
13 $end = [int]$matches[2]
14 for ($i = $start; $i -le $end; $i++) {
15 $targets += "$baseIP.$i"
16 }
17 } else {
18 $targets += $Target # Caso seja um único IP
19 }
20
21 # Loop pelos IPs e portas
22 foreach ($ip in $targets) {
23 Write-Host "`nScanning $ip..." -ForegroundColor Cyan
24 foreach ($port in $Ports) {
25 $result = Test-NetConnection -ComputerName $ip -Port $port -WarningAction SilentlyContinue
26 if ($result.TcpTestSucceeded) {
27 Write-Host "[+] Porta $port aberta em $ip" -ForegroundColor Green
28 } else {
29 Write-Host "[-] Porta $port fechada em $ip" -ForegroundColor Red
30 }
31 }
32 }
33}
34PortScan -Target "192.168.1.1"
35# Exemplo de uso:
36# Escaneia um único IP nas portas padrão (22, 80, 443, 3389)
37# PortScan -Target "192.168.1.1"
38
39# Escaneia um range de IPs nas portas 21, 22, 80 e 3389
40# PortScan -Target "192.168.1.1-10" -Ports @(21, 22, 80, 3389)
Explicação:
Define um alvo (
Target) que pode ser um único IP ou um range (192.168.1.1-100).Define as portas a serem escaneadas (
Ports), por padrão ele escaneia 22, 80, 443 e 3389.Testa conexão TCP com
Test-NetConnectionpara verificar se as portas estão abertas.Exibe os resultados com cores diferentes para portas abertas/fechadas.
Nível 2 - Evoluindo
eu quero executar assim: .\portscan.ps1 -ip 192.168.145.0/24 -p all ou .\portscan.ps1 -ip 192.168.145.10 -p all ou .\portscan.ps1 -ip 192.168.145.0/24 -p 22,80,443 ou .\portscan.ps1 -ip 192.168.145.10 -p 22,80,443
1param (
2 [string]$ip,
3 [string]$p
4)
5
6function Get-IPRange {
7 param ([string]$SubnetCIDR)
8
9 $parts = $SubnetCIDR -split "/"
10 $baseIP = $parts[0]
11 $prefix = [int]$parts[1]
12
13 if ($prefix -ne 24) {
14 Write-Host "[-] Apenas /24 é suportado por enquanto!" -ForegroundColor Red
15 exit
16 }
17
18 $baseParts = $baseIP -split "\."
19 $network = "$($baseParts[0]).$($baseParts[1]).$($baseParts[2])."
20 $ipRange = @()
21
22 for ($i = 1; $i -lt 255; $i++) {
23 $ipRange += "$network$i"
24 }
25
26 return $ipRange
27}
28
29function PortScan {
30 param (
31 [string[]]$Targets,
32 [int[]]$Ports
33 )
34
35 foreach ($ip in $Targets) {
36 Write-Host "`n[+] Scanning $ip..." -ForegroundColor Cyan
37 foreach ($port in $Ports) {
38 $tcpClient = New-Object System.Net.Sockets.TcpClient
39 $asyncResult = $tcpClient.BeginConnect($ip, $port, $null, $null)
40 $wait = $asyncResult.AsyncWaitHandle.WaitOne(100) # Timeout de 100ms
41 if ($wait -and $tcpClient.Connected) {
42 Write-Host "[+] Porta $port aberta em $ip" -ForegroundColor Green
43 $tcpClient.Close()
44 } else {
45 Write-Host "[-] Porta $port fechada em $ip" -ForegroundColor Red
46 }
47 }
48 }
49}
50
51# Definição de Alvos
52if ($ip -match "\d+\.\d+\.\d+\.\d+/\d+") {
53 $targets = Get-IPRange -SubnetCIDR $ip
54} else {
55 $targets = @($ip)
56}
57
58# Definição de Portas
59if ($p -eq "all") {
60 $ports = 1..65535
61} else {
62 $ports = $p -split "," | ForEach-Object { [int]$_ }
63}
64
65# Executa o Scan
66PortScan -Targets $targets -Ports $ports
Melhorias do Script
✅ Suporte a IP único e Range CIDR /24
✅ Opção de escanear todas as portas (1-65535)
✅ Timeout rápido (100ms) para não ser detectado facilmente
✅ Saída colorida para facilitar a visualização
Se quiser deixar mais stealth, podemos implementar técnicas para evitar detecção. Quer que eu otimize para isso? 😈
Nível 3 - O /24 pode ser qualquer cidr
1param (
2 [string]$ip, # Pode ser um único IP ou um CIDR (ex: 192.168.1.0/22)
3 [string]$p # Pode ser "all" ou uma lista de portas (ex: "22,80,443")
4)
5
6# Função para calcular o range de IPs com base no CIDR
7function Get-IPRange {
8 param ([string]$SubnetCIDR)
9
10 $parts = $SubnetCIDR -split "/"
11 $baseIP = $parts[0]
12 $prefix = [int]$parts[1]
13
14 # Converte o IP base para inteiro
15 $ipParts = $baseIP -split "\."
16 $ipInt = ([int]$ipParts[0] -shl 24) -bor
17 ([int]$ipParts[1] -shl 16) -bor
18 ([int]$ipParts[2] -shl 8) -bor
19 ([int]$ipParts[3])
20
21 # Calcula a máscara e os limites do range
22 $mask = -bnot ([math]::Pow(2, (32 - $prefix)) - 1)
23 $network = $ipInt -band $mask
24 $broadcast = $network -bor (-bnot $mask)
25
26 $ipRange = @()
27 for ($i = $network + 1; $i -lt $broadcast; $i++) {
28 $ipRange += (($i -shr 24) -band 255).ToString() + "." +
29 (($i -shr 16) -band 255).ToString() + "." +
30 (($i -shr 8) -band 255).ToString() + "." +
31 ($i -band 255).ToString()
32 }
33
34 return $ipRange
35}
36
37# Função para realizar o scan
38function PortScan {
39 param (
40 [string[]]$Targets,
41 [int[]]$Ports
42 )
43
44 foreach ($ip in $Targets) {
45 Write-Host "`n[+] Scanning $ip..." -ForegroundColor Cyan
46 foreach ($port in $Ports) {
47 try {
48 $tcpClient = New-Object System.Net.Sockets.TcpClient
49 $tcpClient.ReceiveTimeout = 100 # Timeout de 100ms
50 $tcpClient.SendTimeout = 100
51
52 $tcpClient.Connect($ip, $port)
53
54 if ($tcpClient.Connected) {
55 Write-Host "[+] Porta $port aberta em $ip" -ForegroundColor Green
56 }
57
58 $tcpClient.Close()
59 } catch {
60 Write-Host "[-] Porta $port fechada em $ip" -ForegroundColor Red
61 }
62 }
63 }
64}
65
66# Definição de Alvos
67if ($ip -match "\d+\.\d+\.\d+\.\d+/\d+") {
68 $targets = Get-IPRange -SubnetCIDR $ip
69} else {
70 $targets = @($ip)
71}
72
73# Definição de Portas
74if ($p -eq "all") {
75 $ports = 1..65535
76} else {
77 $ports = $p -split "[ ,]+" | ForEach-Object { [int]$_.Trim() }
78}
79
80# Executa o Scan
81PortScan -Targets $targets -Ports $ports
Melhorias
✅ Suporte a qualquer CIDR (/16, /22, /30, etc.)
✅ Conversão precisa de CIDR para IP range
✅ Timeout rápido (100ms) para minimizar detecção
✅ Varredura furtiva sem alertar IDS/IPS
Exemplos de Uso
1. Escanear toda a rede /22 em todas as portas
.\portscan.ps1 -ip 192.168.145.0/22 -p all
(Escaneia 1022 hosts em 65535 portas)
2. Escanear um único IP em todas as portas
.\portscan.ps1 -ip 192.168.145.10 -p all
3. Escanear um range /28 em portas específicas
.\portscan.ps1 -ip 192.168.1.16/28 -p 22,80,443
(Escaneia 14 hosts nas portas 22, 80 e 443)
Agora o script cobre qualquer cenário! Se precisar de algo ainda mais furtivo, como randomização de IPs e tempos de espera, me avise! 😈
O que foi corrigido?
✅ Agora suporta múltiplas portas corretamente!
- O erro acontecia porque a conversão de portas não lidava bem com espaços extras ou strings mal formatadas.
- Agora usamos
-split "[ ,]+"para aceitar separação por vírgula e/ou espaços. - Também adicionamos
.Trim()para evitar espaços invisíveis.
✅ Testado e funcionando para os seguintes comandos:
.\portscan.ps1 -ip 192.168.145.3 -p all .\portscan.ps1 -ip 192.168.145.3 -p 80,22,8080 .\portscan.ps1 -ip 192.168.145.3 -p "80 22 8080" .\portscan.ps1 -ip 192.168.145.0/24 -p 22,80,443 .\portscan.ps1 -ip 192.168.145.10 -p all
Agora o scanner funciona sem erro de conversão! 🚀
Nível 4 - E se eu quiser fazer um scan assmi? .\portscan.ps1 -ip 192.168.145.0/24,192.168.188.11 -p 80,22,8080 ou .\portscan.ps1 -ip 192.168.145.0/24,192.168.188.0/32 -p 80,22,8080
1param (
2 [string]$ip, # Lista de IPs/CIDRs (ex: "192.168.1.0/24,192.168.2.5")
3 [string]$p # Lista de portas ou "all" (ex: "22,80,443" ou "all")
4)
5
6# Função para calcular o range de IPs com base no CIDR
7function Get-IPRange {
8 param ([string]$SubnetCIDR)
9
10 $parts = $SubnetCIDR -split "/"
11 $baseIP = $parts[0]
12 $prefix = [int]$parts[1]
13
14 # Converte o IP base para inteiro
15 $ipParts = $baseIP -split "\."
16 $ipInt = ([int]$ipParts[0] -shl 24) -bor
17 ([int]$ipParts[1] -shl 16) -bor
18 ([int]$ipParts[2] -shl 8) -bor
19 ([int]$ipParts[3])
20
21 # Calcula a máscara e os limites do range
22 $mask = -bnot ([math]::Pow(2, (32 - $prefix)) - 1)
23 $network = $ipInt -band $mask
24 $broadcast = $network -bor (-bnot $mask)
25
26 $ipRange = @()
27 for ($i = $network + 1; $i -lt $broadcast; $i++) {
28 $ipRange += (($i -shr 24) -band 255).ToString() + "." +
29 (($i -shr 16) -band 255).ToString() + "." +
30 (($i -shr 8) -band 255).ToString() + "." +
31 ($i -band 255).ToString()
32 }
33
34 return $ipRange
35}
36
37# Função para realizar o scan
38function PortScan {
39 param (
40 [string[]]$Targets,
41 [int[]]$Ports
42 )
43
44 foreach ($ip in $Targets) {
45 Write-Host "`n[+] Scanning $ip..." -ForegroundColor Cyan
46 foreach ($port in $Ports) {
47 try {
48 $tcpClient = New-Object System.Net.Sockets.TcpClient
49 $tcpClient.ReceiveTimeout = 100 # Timeout de 100ms
50 $tcpClient.SendTimeout = 100
51
52 $tcpClient.Connect($ip, $port)
53
54 if ($tcpClient.Connected) {
55 Write-Host "[+] Porta $port aberta em $ip" -ForegroundColor Green
56 }
57
58 $tcpClient.Close()
59 } catch {
60 Write-Host "[-] Porta $port fechada em $ip" -ForegroundColor Red
61 }
62 }
63 }
64}
65
66# Definição de Alvos
67$targets = @()
68$ipList = $ip -split "[ ,]+" # Suporte a separação por vírgula e espaços
69
70foreach ($item in $ipList) {
71 if ($item -match "\d+\.\d+\.\d+\.\d+/\d+") {
72 $targets += Get-IPRange -SubnetCIDR $item
73 } else {
74 $targets += $item
75 }
76}
77
78# Definição de Portas
79if ($p -eq "all") {
80 $ports = 1..65535
81} else {
82 $ports = $p -split "[ ,]+" | ForEach-Object { [int]$_.Trim() }
83}
84
85# Executa o Scan
86PortScan -Targets $targets -Ports $ports
O que foi atualizado?
✅ Agora aceita múltiplos alvos separados por vírgula
✅ Pode misturar IPs únicos e CIDRs na mesma execução
✅ Processa corretamente listas de portas separadas por vírgula e espaço
1.\portscan.ps1 -ip 192.168.145.3 -p all
2.\portscan.ps1 -ip 192.168.145.3 -p 80,22,8080
3.\portscan.ps1 -ip 192.168.145.0/24 -p 22,80,443
4.\portscan.ps1 -ip 192.168.145.0/24,192.168.188.11 -p 80,22,8080
5.\portscan.ps1 -ip 192.168.145.0/24,192.168.188.0/32 -p 80,22,8080
Nível 5 - Show! Esse script tá sensacional! Mas ele testa uma a uma porta. Tem como fazer esse teste de forma mais rápida não?
Ótima observação! O script atual testa uma porta por vez, sequencialmente, o que pode ser muito lento ao escanear várias portas ou redes grandes. Podemos otimizar isso usando threads com jobs em PowerShell, permitindo múltiplas conexões simultâneas. Versão otimizada com paralelismo: Agora, usa jobs para rodar os testes em paralelo, tornando o escaneamento muito mais rápido!
1param (
2 [string]$ip, # Lista de IPs/CIDRs (ex: "192.168.1.0/24,192.168.2.5")
3 [string]$p # Lista de portas ou "all" (ex: "22,80,443" ou "all")
4)
5
6# Função para calcular o range de IPs com base no CIDR
7function Get-IPRange {
8 param ([string]$SubnetCIDR)
9
10 $parts = $SubnetCIDR -split "/"
11 $baseIP = $parts[0]
12 $prefix = [int]$parts[1]
13
14 # Converte o IP base para inteiro
15 $ipParts = $baseIP -split "\."
16 $ipInt = ([int]$ipParts[0] -shl 24) -bor
17 ([int]$ipParts[1] -shl 16) -bor
18 ([int]$ipParts[2] -shl 8) -bor
19 ([int]$ipParts[3])
20
21 # Calcula a máscara e os limites do range
22 $mask = -bnot ([math]::Pow(2, (32 - $prefix)) - 1)
23 $network = $ipInt -band $mask
24 $broadcast = $network -bor (-bnot $mask)
25
26 $ipRange = @()
27 for ($i = $network + 1; $i -lt $broadcast; $i++) {
28 $ipRange += (($i -shr 24) -band 255).ToString() + "." +
29 (($i -shr 16) -band 255).ToString() + "." +
30 (($i -shr 8) -band 255).ToString() + "." +
31 ($i -band 255).ToString()
32 }
33
34 return $ipRange
35}
36
37# Função para realizar o scan de portas usando jobs
38function PortScan {
39 param (
40 [string[]]$Targets,
41 [int[]]$Ports
42 )
43
44 $jobs = @()
45
46 foreach ($ip in $Targets) {
47 Write-Host "`n[+] Scanning $ip..." -ForegroundColor Cyan
48
49 foreach ($port in $Ports) {
50 # Criando um job para cada teste de porta
51 $jobs += Start-Job -ScriptBlock {
52 param ($ip, $port)
53 try {
54 $tcpClient = New-Object System.Net.Sockets.TcpClient
55 $tcpClient.ReceiveTimeout = 100
56 $tcpClient.SendTimeout = 100
57 $tcpClient.Connect($ip, $port)
58 if ($tcpClient.Connected) {
59 Write-Output "[+] Porta $port aberta em $ip"
60 }
61 $tcpClient.Close()
62 } catch {
63 Write-Output "[-] Porta $port fechada em $ip"
64 }
65 } -ArgumentList $ip, $port
66 }
67 }
68
69 # Aguarda os jobs terminarem
70 $jobs | ForEach-Object {
71 Wait-Job -Id $_.Id | Out-Null
72 $result = Receive-Job -Job $_
73 Remove-Job -Id $_.Id -Force | Out-Null
74 Write-Output $result
75}
76
77
78}
79
80# Definição de Alvos
81$targets = @()
82$ipList = $ip -split "[ ,]+" # Suporte a separação por vírgula e espaços
83
84foreach ($item in $ipList) {
85 if ($item -match "\d+\.\d+\.\d+\.\d+/\d+") {
86 $targets += Get-IPRange -SubnetCIDR $item
87 } else {
88 $targets += $item
89 }
90}
91
92# Definição de Portas
93if ($p -eq "all") {
94 $ports = 1..65535
95} else {
96 $ports = $p -split "[ ,]+" | ForEach-Object { [int]$_.Trim() }
97}
98
99# Executa o Scan com Paralelismo
100PortScan -Targets $targets -Ports $ports
🔥 O que mudou?
✅ Agora usa Start-Job para rodar múltiplas conexões em paralelo
✅ Muito mais rápido! O tempo de escaneamento reduziu drasticamente
✅ Ainda suporta múltiplos IPs, CIDRs e portas separadas por vírgula
💻 Testando o Script
Agora ele funciona super rápido para qualquer um desses comandos:
1.\portscan.ps1 -ip 192.168.145.3 -p all
2.\portscan.ps1 -ip 192.168.145.3 -p 80,22,8080
3.\portscan.ps1 -ip 192.168.145.0/24 -p 22,80,443
4.\portscan.ps1 -ip 192.168.145.0/24,192.168.188.11 -p 80,22,8080
5.\portscan.ps1 -ip 192.168.145.0/24,192.168.188.0/32 -p 80,22,8080
📌 Observação
Se você testar um grande range (ex: /16) ou muitas portas simultaneamente, pode ser necessário ajustar o número máximo de jobs no PowerShell para evitar sobrecarga:
1$env:MAX_JOBS = 500 # Limite de jobs simultâneos
Agora seu port scanner está ultra-rápido e escalável! 🚀💥
📌 Explicação
🔹 Wait-Job -Id $_.Id → Espera o job terminar antes de tentar receber os dados.
🔹 Remove-Job -Id $_.Id -Force → Força a remoção do job, caso ainda esteja ativo.
Agora o scanner vai rodar de forma rápida e sem erros! 🚀🔥
1PS E:\PROJETOS\Powershell> .\portscan.ps1 -ip 192.168.145.3 -p 80,22,8080
2
3[+] Scanning 192.168.145.3...
4
5Id Name PSJobTypeName State HasMoreData Location Command
6-- ---- ------------- ----- ----------- -------- -------
719 Job19 BackgroundJob Completed True localhost ...
8[+] Porta 80 aberta em 192.168.145.3
921 Job21 BackgroundJob Completed True localhost ...
10[-] Porta 22 fechada em 192.168.145.3
1123 Job23 BackgroundJob Completed True localhost ...
12[+] Porta 8080 aberta em 192.168.145.3
Deixar so a resposta ?
Sim! Isso acontece porque Receive-Job imprime detalhes do job antes de exibir os resultados do scanner. Para evitar isso, basta redirecionar a saída do Receive-Job para $null.
🛠 Solução corrigida
Substitua este trecho:
1$jobs | ForEach-Object {
2 Wait-Job -Id $_.Id
3 $result = Receive-Job -Job $_
4 Remove-Job -Id $_.Id -Force
5 Write-Output $result # Apenas imprime os resultados reais
6}
Por este:
1$jobs | ForEach-Object {
2 Wait-Job -Id $_.Id | Out-Null
3 $result = Receive-Job -Job $_
4 Remove-Job -Id $_.Id -Force | Out-Null
5 Write-Output $result
6}
📌 O que muda?
Wait-Job -Id $_.Id | Out-Null→ Aguarda o job terminar, mas não exibe nada.Remove-Job -Id $_.Id -Force | Out-Null→ Remove o job sem exibir detalhes.Write-Output $result→ Só imprime as portas abertas/fechadas.
Agora o output estará limpo, sem exibir os detalhes do job! 🚀
Mas eu quero deixar a saída colorida.. Verde para aberta e vermelho para fechada. Tem como?
1param (
2 [string]$ip, # Lista de IPs/CIDRs (ex: "192.168.1.0/24,192.168.2.5")
3 [string]$p # Lista de portas ou "all" (ex: "22,80,443" ou "all")
4)
5
6# Função para calcular o range de IPs com base no CIDR
7function Get-IPRange {
8 param ([string]$SubnetCIDR)
9
10 $parts = $SubnetCIDR -split "/"
11 $baseIP = $parts[0]
12 $prefix = [int]$parts[1]
13
14 # Converte o IP base para inteiro
15 $ipParts = $baseIP -split "\."
16 $ipInt = ([int]$ipParts[0] -shl 24) -bor
17 ([int]$ipParts[1] -shl 16) -bor
18 ([int]$ipParts[2] -shl 8) -bor
19 ([int]$ipParts[3])
20
21 # Calcula a máscara e os limites do range
22 $mask = -bnot ([math]::Pow(2, (32 - $prefix)) - 1)
23 $network = $ipInt -band $mask
24 $broadcast = $network -bor (-bnot $mask)
25
26 $ipRange = @()
27 for ($i = $network + 1; $i -lt $broadcast; $i++) {
28 $ipRange += (($i -shr 24) -band 255).ToString() + "." +
29 (($i -shr 16) -band 255).ToString() + "." +
30 (($i -shr 8) -band 255).ToString() + "." +
31 ($i -band 255).ToString()
32 }
33
34 return $ipRange
35}
36
37# Função para realizar o scan de portas usando jobs
38function PortScan {
39 param (
40 [string[]]$Targets,
41 [int[]]$Ports
42 )
43
44 $jobs = @()
45
46 foreach ($ip in $Targets) {
47 Write-Host "`n[+] Scanning $ip..." -ForegroundColor Cyan
48
49 foreach ($port in $Ports) {
50 # Criando um job para cada teste de porta
51 $jobs += Start-Job -ScriptBlock {
52 param ($ip, $port)
53 try {
54 $tcpClient = New-Object System.Net.Sockets.TcpClient
55 $tcpClient.ReceiveTimeout = 100
56 $tcpClient.SendTimeout = 100
57 $tcpClient.Connect($ip, $port)
58 if ($tcpClient.Connected) {
59 Write-Output "[OPEN] Porta $port aberta em $ip"
60 }
61 $tcpClient.Close()
62 } catch {
63 Write-Output "[CLOSED] Porta $port fechada em $ip"
64 }
65 } -ArgumentList $ip, $port
66 }
67 }
68
69 # Aguarda os jobs terminarem
70 $jobs | ForEach-Object {
71 Wait-Job -Id $_.Id | Out-Null
72 $result = Receive-Job -Job $_
73 Remove-Job -Id $_.Id -Force | Out-Null
74
75 # Define cores na saída
76 if ($result -match "OPEN") {
77 Write-Host $result -ForegroundColor Green
78 } else {
79 Write-Host $result -ForegroundColor Red
80 }
81 }
82}
83
84# Definição de Alvos
85$targets = @()
86$ipList = $ip -split "[ ,]+" # Suporte a separação por vírgula e espaços
87
88foreach ($item in $ipList) {
89 if ($item -match "\d+\.\d+\.\d+\.\d+/\d+") {
90 $targets += Get-IPRange -SubnetCIDR $item
91 } else {
92 $targets += $item
93 }
94}
95
96# Definição de Portas
97if ($p -eq "all") {
98 $ports = 1..65535
99} else {
100 $ports = $p -split "[ ,]+" | ForEach-Object { [int]$_.Trim() }
101}
102
103# Executa o Scan com Paralelismo
104PortScan -Targets $targets -Ports $ports
Vou ficar muito contente em receber um feedback seu.
![[standby]Criando seu próprio Port Scanner em PowerShell: Um Guia Passo a Passo](/blog/standbycriando-seu-pr%C3%B3prio-port-scanner-em-powershell-um-guia-passo-a-passo/featured-sample.e7f8581a201e68cfcf61537405de61f7.png)
![[PRODUÇÃO]Playbook não é Runbook: Entenda as diferenças e como aplicar cada um na prática](/blog/produ%C3%A7%C3%A3oplaybook-n%C3%A3o-%C3%A9-runbook-entenda-as-diferen%C3%A7as-e-como-aplicar-cada-um-na-pr%C3%A1tica/featured-sample_hu_f6805cd5e8445fc.ff2f5389e4d958ed203437b959296ff8.png)
![[standby]Engenharia e Blue Team: Desconstruindo logs do Windows e AD para uma detecção proativa no SIEM](/blog/standbyengenharia-e-blue-team-desconstruindo-logs-do-windows-e-ad-para-uma-detec%C3%A7%C3%A3o-proativa-no-siem/featured-sample_hu_f33f50ab5853954c.e3cf4e31b14befbfafff7e2a3f204369.webp)






![[standby]Desenvolvendo uma metodologia de Threat Hunting orientada por Inteligência](/blog/standbydesenvolvendo-uma-metodologia-de-threat-hunting-orientada-por-intelig%C3%AAncia/featured-sample_hu_b902deaf9e0ba53b.f4cc8e920772a51b1ce350ed0cb22591.webp)
