Hay muchos escáneres de puertos de red disponibles. Algunos de los más populares incluyen Nmap, Masscan, Angry IP Scanner, ZMap y muchos otros. Todos son excelentes, están bien probados y son funcionales, pero también son grandes, complejos y, lo más importante, marcados por cualquier antivirus o solución EDR respetable. Y esto puede ser un obstáculo en algunos escenarios de pruebas de penetración. Esta vez vamos a hablar sobre un escáner de puertos minimalista en PowerShell (TCP/UDP).
¿Por qué Escribir un Escáner de Puertos desde Cero?
Escribir herramientas desde cero puede ser necesario, por ejemplo, cuando realizamos una prueba de penetración en un entorno estrictamente limitado donde no podemos usar ninguna herramienta típica de prueba de penetración.
Esto sería crucial al probar un entorno VDI / Citrix aislado, en el que no podemos cargar nada, o cuando simulamos a un empleado insatisfecho desde una estación de trabajo con todas las medidas de seguridad instaladas.
En todos estos casos, necesitaremos crear nuestras propias herramientas para poder realizar operaciones básicas, como escanear puertos.
Sin la capacidad de escanear puertos, es poco probable que logremos algún éxito, detectar sistemas en la red o realizar algún movimiento horizontal en este sentido.
Un escáner de puertos es simplemente necesario, y si no podemos usarlo, debemos crearlo.
Escáner de Puertos TCP y UDP en PowerShell
Para tales casos, se ha desarrollado el siguiente escáner de puertos rápido y simple, pero poderoso y confiable.
Para mantener un tamaño pequeño, el escáner se divide en dos módulos independientes separados:
- Escáner de Puertos TCP:
https://github.com/InfosecMatter/Minimalistic-offensive-security-tools/blob/master/port-scan-tcp.ps1
- Escáner de Puertos UDP:
https://github.com/InfosecMatter/Minimalistic-offensive-security-tools/blob/master/port-scan-udp.ps1
Así que realmente son dos escáneres de puertos, no uno. Ambos escáneres se pueden encontrar en el siguiente repositorio de GitHub:
https://github.com/InfosecMatter/Minimalistic-offensive-security-tools
Lista de Características
Ambos escáneres de puertos tienen las siguientes características:
- Detección de puertos abiertos, cerrados y filtrados (tanto TCP como UDP).
- Capacidad para escanear un único host, un rango de red o una lista de hosts en un archivo.
- Valores de tiempo de espera personalizables para un escaneo de puertos eficiente y confiable.
- No es malicioso: no es detectado por ningún antivirus o solución EDR.
En cuanto al diseño:
- Pequeño y minimalista: se escribe a mano (a través del teclado).
- Escrito en PowerShell puro: no se requieren módulos adicionales.
- Diseño práctico y bien pensado:
- Soporte para reanudación si se interrumpe.
- Omite los hosts/puertos que ya han sido escaneados.
Veamos cómo utilizar estos escáneres.
Escenario de Uso Típico
Dado que los escáneres de puertos están escritos en PowerShell, debemos tener la capacidad de ejecutar comandos de PowerShell en el sistema que estamos utilizando. En una estación de trabajo con acceso limitado, esto puede ser un problema, así que…
- (1) El primer paso suele ser eludir las restricciones y crear un shell. Una vez que podamos ejecutar comandos de PowerShell cómodamente, podemos pasar al siguiente paso.
- (2) Ahora podemos colocar los escáneres de puertos en algún lugar del sistema de archivos. Por ejemplo, podríamos colocarlos en nuestro escritorio, pero debido a diversas restricciones, es posible que tengamos que colocarlos en algún otro lugar donde podamos escribir, como:
C:\Users\Public
C:\Windows\Tasks
C:\Windows\Tracing
C:\Windows\System32\Spool\Drivers\Color
etc.
Ahora podemos comenzar a escanear puertos. Aquí hay una breve introducción a cómo usarlos.
Escáner de puertos TCP:
Import-Module .\port-scan-tcp.ps1
# Uso:
port-scan-tcp <host(s)> <port(s)>
Escáner de puertos UDP:
Import-Module .\port-scan-udp.ps1
# Uso:
port-scan-udp <host(s)> <port(s)>
Veamos algunos ejemplos de su uso en la práctica.
Escaneo de puertos de un único host
Aquí tienes un ejemplo básico: verifica si el puerto TCP/445 está abierto en el host remoto:
port-scan-tcp 192.168.204.183 445
Aquí tienes un ejemplo de escaneo de un solo host para detectar los puertos TCP seleccionados:
port-scan-tcp 192.168.204.183 (21, 22, 23, 25, 80, 443, 445, 3389)
Escaneo de un rango de puertos de una red
Aquí tienes un ejemplo de escaneo de puertos en el rango 192.168.204.0/24 para el puerto TCP/445 (escaneo de puertos):
0..255 | foreach { port-scan-tcp 192.168.204.$_ 445 }
Aquí tienes un ejemplo de escaneo de un rango de red 192.168.204.0/24 para los puertos TCP seleccionados:
0..255 | foreach { port-scan-tcp 192.168.204.$_ (22,80,445) }
Lista de hosts en un archivo
También podemos proporcionar una lista de objetivos como un archivo de entrada.
Por ejemplo, en redes corporativas con implementación de Active Directory (AD), podríamos extraer una lista de computadoras de AD usando los cmdlets de PowerShell de la siguiente manera:
$a = [adsisearcher]"(objectCategory=computer)"
$a.PropertiesToLoad.add("dnshostname") | out-null
$a.PageSize = 1
$a.FindAll() | % { echo $_.properties.dnshostname } > pcs.txt
Ahora podemos identificar todos los sistemas vivos de Windows escaneando el puerto TCP/445:
port-scan-tcp (gc .\pcs.txt) 445
Obtener Resultados
Ambos escáneres rastrean todo utilizando un archivo de estado (scanresults.txt
), que se crea en el directorio de trabajo actual. Esto nos permite verificar los resultados en cualquier momento, incluso durante el escaneo actual.
Por ejemplo, así es como podemos obtener una lista de sistemas con el puerto TCP/445 abierto:
Get-Content .\scanresults.txt | Select-String "tcp,445,Open"
Si quisiéramos listar solo la primera columna, podríamos hacerlo fácilmente con PowerShell de la siguiente manera:
(Get-Content .\scanresults.txt | Select-String "tcp,445,Open") -replace ",.*",""
Ahora podríamos pasar esta lista a nuestro escáner de fuerza bruta de inicio de sesión SMB, por ejemplo, e intentar piratear algunas de estas máquinas Windows. O podríamos usar alguna otra automatización, todo lo que deseemos.
Requisitos y Limitaciones
Compatibilidad. El escáner TCP viene en dos versiones, pero con la diferencia de que usa el método TcpClient.ConnectAsync()
. Este método, disponible en .NET 4.5, permite al escáner distinguir entre puertos “cerrados” y “filtrados”. La versión compatible (para sistemas más antiguos) no puede reconocer esto y simplemente informa sobre todos estos casos como “Cerrado”.
Velocidad. Ambos escáneres de puertos (TCP y UDP) son simplemente bucles de un solo hilo sin paralelización. Por lo tanto, la velocidad de escaneo está limitada. Pero en el peor de los casos, la velocidad debería ser de aproximadamente 1 escaneo de puerto por segundo, dependiendo de los valores de tiempo de espera, que también puede cambiar fácilmente.
Reducción de velocidad. También hay que tener en cuenta que los escáneres pueden ralentizarse un poco con el tiempo si ya hay demasiados resultados. Para mitigar este problema, podemos girar el archivo de resultados o usar otro, cambiando los módulos y recargando:
Import-Module .\port-scan-tcp.ps1 -force
Import-Module .\port-scan-udp.ps1 -force
Conclusión
Aunque estos escáneres de puertos no son perfectos, en algunas situaciones cumplen su función gracias a una lista hermosa de características y una forma compacta. Espero que también los encuentres útiles en ocasiones.