Herramienta nmap

¿Qué es nmap?
Su nombre viene de "Network Mapper". Si consultamos la página oficial de nmap https://nmap.org/man/es/index.html:

nmap — Herramienta de exploración de redes y de sondeo de seguridad / puertos.

Dentro del grupo de programas de mapeo de redes, nmap es la herramienta de referencia más usada y conocida. Permite explorar una red y detectar que equipos tiene levantados, ver el estado de los puertos e incluso que servicios utilizan esos puertos, detectar el sistema operativo y otras características. Los administradores de red lo usan para auditar equipos y redes buscando vulnerabilidades. Aunque está diseñado para escanear redes completas rápidamente funciona perfectamente para un solo host.

Enseguida vamos a practicar como usar nmap en nuestras redes pero antes una recomendación. No debe utilizarse de manera muy insistente contra objetivos que no sean de nuestra propiedad para no meternos en problemas. Aunque nmap no es de por sí un programa malicioso, es una herramienta usada por hackers y un uso intensivo sobre un mismo objetivo puede considerarse un ciberataque.

Los creadores nos prestan un servidor para practicar todo tipo de sondeos: scanme.nmap.org. Se pide no abusar y no lanzar ataques exploits o el servidor caerá con el error: "Failed to resolve given hostname/IP".

El funcionamiento básico de nmap es enviar mensajes a una o más direcciones IP y analizar la respuesta. Si un host responde hará un reconocimiento más profundo indagando información.

En este tutorial practicaremos nmap por comandos desde Linux y echaremos un vistazo a la versión de Windows con GUI, llamada Zenmap.

Instalando nmap

Es un software libre de código abierto disponible para muchos sistemas operativos. Para instalarlo en Linux Ubuntu:

sudo apt install nmap

Lista de parámetros y forma de uso

Al entrar nmap o nmap --help en la terminal tendremos un listado de todos los parámetros. En https://nmap.org/man/es/man-briefoptions.html hay también en castellano un resumen de los parámetros más habituales.

Tampoco hay que olvidarse de man nmap que muestra en un solo archivo txt la totalidad de parámetros con ejemplos y breves explicaciones.

Nmap 7.92 ( https://nmap.org )
Usage: nmap [Scan Type(s)] [Options] {target specification}
TARGET SPECIFICATION:
  Can pass hostnames, IP addresses, networks, etc.
  Ex: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0.0-255.1-254
  -iL <inputfilename>: Input from list of hosts/networks
  -iR <num hosts>: Choose random targets
  --exclude <host1[,host2][,host3],...>: Exclude hosts/networks
  --excludefile <exclude_file>: Exclude list from file
HOST DISCOVERY:
  -sL: List Scan - simply list targets to scan
  -sn: Ping Scan - disable port scan
  -Pn: Treat all hosts as online -- skip host discovery
  -PS/PA/PU/PY[portlist]: TCP SYN/ACK, UDP or SCTP discovery to given ports
  -PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
  -PO[protocol list]: IP Protocol Ping
  -n/-R: Never do DNS resolution/Always resolve [default: sometimes]
  --dns-servers <serv1[,serv2],...>: Specify custom DNS servers
  --system-dns: Use OS's DNS resolver
  --traceroute: Trace hop path to each host
SCAN TECHNIQUES:
  -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
  -sU: UDP Scan
  -sN/sF/sX: TCP Null, FIN, and Xmas scans
  --scanflags <flags>: Customize TCP scan flags
  -sI <zombie host[:probeport]>: Idle scan
  -sY/sZ: SCTP INIT/COOKIE-ECHO scans
  -sO: IP protocol scan
  -b <FTP relay host>: FTP bounce scan
PORT SPECIFICATION AND SCAN ORDER:
  -p <port ranges>: Only scan specified ports
    Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9
  --exclude-ports <port ranges>: Exclude the specified ports from scanning
  -F: Fast mode - Scan fewer ports than the default scan
  -r: Scan ports consecutively - don't randomize
  --top-ports <number>: Scan <number> most common ports
  --port-ratio <ratio>: Scan ports more common than <ratio>
SERVICE/VERSION DETECTION:
  -sV: Probe open ports to determine service/version info
  --version-intensity <level>: Set from 0 (light) to 9 (try all probes)
  --version-light: Limit to most likely probes (intensity 2)
  --version-all: Try every single probe (intensity 9)
  --version-trace: Show detailed version scan activity (for debugging)
SCRIPT SCAN:
  -sC: equivalent to --script=default
  --script=<Lua scripts>: <Lua scripts> is a comma separated list of
           directories, script-files or script-categories
  --script-args=<n1=v1,[n2=v2,...]>: provide arguments to scripts
  --script-args-file=filename: provide NSE script args in a file
  --script-trace: Show all data sent and received
  --script-updatedb: Update the script database.
  --script-help=<Lua scripts>: Show help about scripts.
           <Lua scripts> is a comma-separated list of script-files or
           script-categories.
OS DETECTION:
  -O: Enable OS detection
  --osscan-limit: Limit OS detection to promising targets
  --osscan-guess: Guess OS more aggressively
TIMING AND PERFORMANCE:
  Options which take <time> are in seconds, or append 'ms' (milliseconds),
  's' (seconds), 'm' (minutes), or 'h' (hours) to the value (e.g. 30m).
  -T<0-5>: Set timing template (higher is faster)
  --min-hostgroup/max-hostgroup <size>: Parallel host scan group sizes
  --min-parallelism/max-parallelism <numprobes>: Probe parallelization
  --min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <time>: Specifies
      probe round trip time.
  --max-retries <tries>: Caps number of port scan probe retransmissions.
  --host-timeout <time>: Give up on target after this long
  --scan-delay/--max-scan-delay <time>: Adjust delay between probes
  --min-rate <number>: Send packets no slower than <number> per second
  --max-rate <number>: Send packets no faster than <number> per second
FIREWALL/IDS EVASION AND SPOOFING:
  -f; --mtu <val>: fragment packets (optionally w/given MTU)
  -D <decoy1,decoy2[,ME],...>: Cloak a scan with decoys
  -S <IP_Address>: Spoof source address
  -e <iface>: Use specified interface
  -g/--source-port <portnum>: Use given port number
  --proxies <url1,[url2],...>: Relay connections through HTTP/SOCKS4 proxies
  --data <hex string>: Append a custom payload to sent packets
  --data-string <string>: Append a custom ASCII string to sent packets
  --data-length <num>: Append random data to sent packets
  --ip-options <options>: Send packets with specified ip options
  --ttl <val>: Set IP time-to-live field
  --spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address
  --badsum: Send packets with a bogus TCP/UDP/SCTP checksum
OUTPUT:
  -oN/-oX/-oS/-oG <file>: Output scan in normal, XML, s|<rIpt kIddi3,
     and Grepable format, respectively, to the given filename.
  -oA <basename>: Output in the three major formats at once
  -v: Increase verbosity level (use -vv or more for greater effect)
  -d: Increase debugging level (use -dd or more for greater effect)
  --reason: Display the reason a port is in a particular state
  --open: Only show open (or possibly open) ports
  --packet-trace: Show all packets sent and received
  --iflist: Print host interfaces and routes (for debugging)
  --append-output: Append to rather than clobber specified output files
  --resume <filename>: Resume an aborted scan
  --noninteractive: Disable runtime interactions via keyboard
  --stylesheet <path/URL>: XSL stylesheet to transform XML output to HTML
  --webxml: Reference stylesheet from Nmap.Org for more portable XML
  --no-stylesheet: Prevent associating of XSL stylesheet w/XML output
MISC:
  -6: Enable IPv6 scanning
  -A: Enable OS detection, version detection, script scanning, and traceroute
  --datadir <dirname>: Specify custom Nmap data file location
  --send-eth/--send-ip: Send using raw ethernet frames or IP packets
  --privileged: Assume that the user is fully privileged
  --unprivileged: Assume the user lacks raw socket privileges
  -V: Print version number
  -h: Print this help summary page.
EXAMPLES:
  nmap -v -A scanme.nmap.org
  nmap -v -sn 192.168.0.0/16 10.0.0.0/8
  nmap -v -iR 10000 -Pn -p 80
SEE THE MAN PAGE (https://nmap.org/book/man.html) FOR MORE OPTIONS AND EXAMPLES
                        

En este breve resumen queda de manifiesto lo potente que puede ser esta herramienta. Tomando como índice esta lista veremos de manera práctica una parte de las muchas posibilidades disponibles que ofrece para mapear redes.

ESPECIFICACIÓN DE OBJETIVO

El primer apartado el resumen es bastante claro. Lo vamos a poner en práctica sobre alguno de nuestros hosts y redes. Podemos fijar objetivos de un solo host o rangos de redes de diferentes maneras. Para escanear un host en una ip concreta simplemente pondremos nmap dirección_ip_del_host. Por ejemplo si quiero investigar uno de mis servidores le pondré su ip como parámetro. Si se trata de un host del que estoy dentro via SSH o en local también puedo usar la dirección de loopback 127.0.0.1

ubuntu@ubuntusrv2:~$ nmap 127.0.0.1
Starting Nmap 7.80 ( https://nmap.org ) at 2022-08-21 17:27 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00010s latency).
Not shown: 998 closed ports
PORT    STATE SERVICE
22/tcp  open  ssh
111/tcp open  rpcbind

Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds
                        

Rápidamente nos devuelve información de ese host informando de los puertos abiertos 22 para SSH y 111 para "rpcbind" para conexiones con unidades externas de memoria NFS.

Otras formas de seleccionar objetivos:

# Por nombre de dominio
nmap scanme.nmap.org
# Analizar toda la red usando la notación CIDR
nmap 10.0.0.0/24
# Toda la red usando la notación CIDR excluyendo una o varias IP
nmap 10.0.0.0/24 --exclude 10.0.0.100
# Diferentes IP separadas por espacio
nmap 10.0.0.67 80.54.182.5
# Fragmento de red, por ejemplo de la 50 a la 60
nmap 10.0.0.50-60
#Analizar varias IP designadas dentro de un mismo rango
nmap 10.0.0.12,15,56,125
                        

La lista de objetivos también puede estar dentro de un archivo txt. En un archivo txt ponemos direcciones IP de objetivos y guardamos.

10.0.0.50
10.0.0.1
                        

Para analizar la lista se usa el parámetro -iL seguido del nombre archivo txt.

# Analizar una lista de objetivos contenida dentro de un archivo txt
nmap -iL listado_hosts.txt
                        
DESCUBRIMIENTO DE HOSTS

Dependiendo de si vamos a sondear en una red local o externa nmap usará diferentes técnicas predeterminadas. Algunas de las técnicas que usa son enviar un ping, enviar un paquete por TCP o UDP, SYN y muchas otras.

Todo el proceso de envío de paquetes para detectar dispositivos se ve muy claro si usamos el famoso analizador de redes Wireshark

A los programas como Wireshark se les llama también sniffers (esnifadores). Cuando se pone en marcha registra en una tabla enorme todo el tráfico de red, dando una cantidad de información enorme de protocolos usados, puertos, tiempos de respuesta. Es increible como registra todo. La cantidad de información que extrae es tan grande que debe filtrarse para ver solamente lo que nos interesa.

Vamos a practicar Wireshark sondeando el segmento de scanme.nmap.org y nos vamos a fijar en una ip cualquiera.

nmap scanme.nmap.org/24
                        

Tras un sondeo de 1 minuto usaremos los filtros de Wireshark para que solo muestre el tráfico relacionado con la Ip 45.33.32.181. Al tener miles de paquetes registrados, el poder acotar la visualización a las características de lo que queremos estudiar, es bastante necesario para no perderse ante un aluvión de datos. En la captura de imagen se ven claramente las diferentes técnicas que emplea. Nmap prueba enviando paquetes con ping por protocolo ICMP, SYN al puerto 443 y ACK al 80. Al mismo tiempo está a la escucha para registrar si hay "algo vivo" que responda.

Cómo no recibimos ninguna respuesta pensamos que esa IP está libre o al menos nmap no ha sido capaz de detectarlo.

<> En redes locales un sondeo nmap simple, es decir, sin opciones, buscará dispositivos por medio de ARP. Envía por broadcast una solicitud por protocolo ARP de cada IP de la lista de objetivos. Si le llega la Mac Adress se confirma que el host existe.

Estos 2 comandos serán equivalentes si se lanzan desde red local porque la opción -PR se activa de manera predeterminada:

nmap 10.0.0.0/24
nmap -PR 10.0.0.0/24 
                        

En un escaneo real a mi red de casa con Wireshark puede verse como hace la consulta por broadcast preguntando por todas las ip del segmento de red y allí donde hay un host en la tabla ARP obtenemos la MAC que confirma que "hay algo".

Para redes no locales, en un sondeo simple utiliza las opciones -PE -PS443 -PA -PP. Por tanto, las siguientes sentencias son equivalentes:

nmap scanme.nmap.org
nmap -PE -PS443 -PA -PP scanme.nmap.org
                        

Hasta el momento ya hemos usado estas opciones:

  • -PR Ping ARP. Usado siempre por omisión en redes locales.
  • -PE Ping ICMP tipo 7. Nmap envía paquetes "echo request" y si recibe "echo reply" (tipo 0) hay un host vivo.
  • -PP Ping ICMP tipo 14. Si recibe una respuesta de "Huella de tiempo" hay un host vivo.
  • -PS443 Ping TCP SYN al puerto 443. Cuando dos equipos inician una conexión, el destinatario envía un paquete SYN ACK para indicar que está listo.
  • -PA Ping TCP ACK. Parecido al SYN pero es otra bandera (bit) el que está activo. Si no se especifica puerto utiliza el 80 por omisión.

Si sondeamos una red sola para listar que equipos están levantados sin importarnos los puertos o otras características, tenemos las opciones -sL que usa DNS inversa y -sn que envía una solicitud de eco ICMP y un paquete TCP al 80 por omisión. Importante: -sL solo funciona si escaneamos segmentos de red. No sirve cuando se apunta a una IP concreta. Además en mis pruebas me daba falsos positivos y no detectaba algunos dispositivos Android ( 2 móviles )

nmap -sL 192.168.1.0/24
nmap -sn 192.168.1.0/24
                        

En https://nmap.org/man/es/man-host-discovery.html encontrarás con detalle que hace cada una de las opciones de búsqueda.

Nmap no es infalible para detectar dispositivos. Por ejemplo para encontrar móviles en tu red local seguramente la búsqueda predeterminada no funcione. En mi red de casa consigo resultados mas fiables si activo la opción -F, de Fast, para búsqueda rápida y forzando que solo use IPv4 con -T4.

nmap -T4 -F 192.168.1.0/24
                        

En mi experiencia las dos maneras más fiables para encontrar todos los dispositivos de una red local fueron nmap -T4 -F y nmap -sn. Como técnicas de búsqueda hay muchas y también a veces los equipos pueden quedar ofuscados por seguridad, no siempre encotraremos los host con facilidad y lo que en una red sirve puede no funcionar en otra.

Nmap con --traceroute muestra los saltos de los paquetes para encontrar el host.

TÉCNICAS DE ANÁLISIS Y ESPECIFICACIÓN DE PUERTOS

Muchos analizadores de puertos han agrupado los puertos en 2 estados: abierto o cerrado. Nmap es más descriptivo clasificando el estado de los puertos en 6 estados:

  • Abierto: Una aplicación acepta conexiones TCP o paquetes UDP en este puerto. El encontrar esta clase de puertos es generalmente el objetivo primario de realizar un sondeo de puertos.
  • Cerrado: El puerto no tiene ningún servicio a la escucha. Puede ser interesante analizarlo en otro momento por si ya tiene tráfico.
  • Filtrado: Nmap no puede acceder porque algún cortafuegos o reglas de enrutamiento impide acceder al puerto.
  • No filtrado: El puerto es accesible pero no se puede determinar si está abierto o cerrado. Un análisis con otras técnicas puede ayudar.
  • Abierto|filtrado: No se puede averiguar con seguridad si está abierto o filtrado.
  • Cerrado|filtrado: No se puede averiguar con seguridad si está cerrado o filtrado.

Cuando analizamos una red debemos elegir que técnica de sondeo queremos emplear para buscar puertos. Generalmente, solo se puede usar una técnica en cada rastreo salvo la opción de búsqueda de puertos UDP que se puede simultanear con alguna búsqueda de TCP. El método de detección por omisión es el -sS ( TCP SYN ) si estamos con usuario root y por lo general es bastante fiable, sigiloso y bastante rápido.

Si no se especifica que puertos sondear lo hará a una lista que tiene con 1000 puertos.

-sS ( sondeo TCP SYN )

Para entender esto método nos vamos a apoyar en la imagen de Wikimedia.

Al iniciar una comunicación entre 2 host la máquina de origen envía a la máquina de destino por TCP un primer paquete de datos con una cabecera con varios campos. En uno de ellos hay unos flags (banderas o bits) para hacer seguimiento de la comunicación. Inicialmente en la cabecera se activa el SYN y el destino cuando lo recibe devuelve esa cabecera o el SYN activo (Synchronisation) más otros flags dependiendo del estado o la voluntad de comunicarse. Si está listo para recibir datos porque el puerto está abierto devolverá el flag ACK (Acknowledgment, reconocimiento en inglés). Con esta respuesta el emisor sabrá que puede continuar con la comunicación y enviará el archivo o lo que sea. Como nmap solo quiere saber el estado del puerto y ya le han dado respuesta positiva, detiene la comunicación enviando un SYN mas RST (Reset) para cortar súbitamente. Si fuera una comunicación real entre 2 host para transferirse información de cualquier tipo, la comunicación continuaría hasta enviar el bit SYN FIN (Finalize).

En el caso de encontrarnos con puertos cerrados la respuesta será también el SYN pero en lugar de ACK llegará por respuesta un RST (Reset) cerrando la comunicación indicando a nmap que el puerto no está disponible. Esto ocurre cuando el receptor recibe datos por un puerto que en ese momento no tiene ningún servicio a la escucha.

Como ejemplo voy lanzar Nmap contra mi router para que examine 3 puertos y antes pondremos a Wireshark a la escucha para que registre todo.

#Nota: -sS se puede omitir por ser la técnica por omisión
nmap -sS -p 443,22,555 192.168.1.1
                        

He elegido 3 puertos que están en diferentes estados para ver las diferencias en Wireshark.

Starting Nmap 7.92 ( https://nmap.org ) at 2022-08-24 19:15 Hora de verano romance
Nmap scan report for 192.168.1.1
Host is up (0.0011s latency).

PORT    STATE    SERVICE
22/tcp  filtered ssh
443/tcp open     https
555/tcp closed   dsf
                        

Nmap confirma que tengo el puerto 22 filtrado, el 443 abierto y el 555 cerrado. Y desde Wireshark lo veo tal cual la siguiente captura. Por claridad, está filtrado para que solo muestre paquetes donde intervenga la ip del router. Con Wireshark podemos filtrar los datos por muchos criterios: puertos, ip, protocolos y una larga lista.

En los 3 paquetes de la tabla, numerados como 11,12,13, la IP de origen 192.168.1.173 de mi ordenador contacta con el router 192.168.1.1.

El paquete 11 envía un SYN al puerto 443, el 12 al puerto 22 y el 13 al puerto 555.

En el paquete capturado Nº 14 con origen de mi router llega un SYN ACK del puerto 443. Lo que ya hemos dicho que es un reconocimiento de la comunicación y por tanto el puerto está abierto.

El paquete 15 (línea roja) con origen del router viene con SYN RST del puerto 555. Reset de comunicación. El puerto está cerrado.

El paquete 16 (línea negra) es una retransmisión del SYN ACK que ya envió previamente. Esto es debido a que nmap cuando recibe el primer ACK corta la comunicación de manera abrupta para no perder tiempo. Los paquetes "TCP Retransmission" también se envían cuando hay perdida de paquetes.

En el paquete 17 se repite el intento de conexión al puerto 22 del router. Al tratarse de puertos filtrados por firewall no dan respuesta alguna para la mayor discrepción posible. Nmap intentará varias veces antes de desistir.

El método usado en este ejemplo es uno de los más recomendables. Si no somos root, desde nmap no podremos usarlo y usará como por defecto el sistema -sT

-sT (sondeo TCP connect())

El modo -sT es el utilizado cuando no se puede utilizar el modo SYN por tema de permisos o en redes IPv6. Este método solo es recomendable usarlo cuando no puede usarse -sS

-sU (sondeos UDP)

Los puertos UDP son más lentos de sondear pero, no por ello, deben descuidarse. Son los puertos usados habitualmente para transmisión de video, conexiones VPN, videojuegos online...

Escanear un segmento de red buscando puertos UDP consume mucho tiempo. Para no hacerlo tan largo es recomendable especificar puertos concretos o usar el parámetro --tcp-ports numero_puertos. Siendo numero_puertos un número que delimita la busqueda a los puertos más frecuentes. En nmap hay listas de frecuentes para 1,3,5,10...

En esta prueba vamos a ver como funciona nmap buscando si tengo abierto el puerto 161 en un VPS que uso para temas de snmp . En la instrucción le fijaremos que busque solo el 161 udp para ahorrar tiempo y que Wireshark sea más simple de leer.

Un truco interesante es poder saber cuanto falta para finalizar un sondeo cuando se trata de una red grande o puertos UDP. Al pulsar la tecla ESPACIO nos muestra porcentage de sondeo y tiempo estimado en finalizar. Muy útil para algunos sondeos que tardan muchos minutos.

UDP Scan Timing: About 88.51% done; ETC: 12:09 (0:01:56 remaining)
                        
nmap 194.5.159.198 -sU -p 161
                        

La respuesta por consola es que está abierto.

Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-05 11:51 Hora de verano romance
Nmap scan report for 194.5.159.198
Host is up (0.051s latency).

PORT    STATE  SERVICE
161/udp open   snmp
                        

De nuevo nos vamos a ayudar de Wireshark para ver mejor como trabaja nmap. La captura demuestra que por medio de snmp consigue información de que es una máquina Linux, el nombre del servidor y algún dato de hardware. Los VPS y los ordenadores locales por defecto no suelen estar con SNMP habilitado. Lo tuve que activar y abrir los puertos correspondientes.

Nmap hace una consulta por protocolo snmp a unas direcciones de árbol de datos MIB (Management Information Base, una manera jerárquica de organizar la información recolectada de cualquier dispositivo SNMP que se encuentra conectado a la red). Recibe el OID 1.3.6.1.2.1.1.1.0 que por norma suele apuntar al nombre del sistema operativo, hardware o algún dato de red. Sobre SNMP no veremos mas en este artículo. Un OID es un identificador de objeto de un MIB. Un disposito con snmp tiene muchos OID apuntando a gran variedad de datos como por ejemplo la ip, sistema operativo, si es una impresora el contador de copias, y un larguísimo etcétera. Por último, comentar que todos o (casi todos) los dispositivos de red tienen este sistema de extracción de datos para monitorizar su estado.

Existen muchas páginas sobre los MIB públicos (las listas de OID) de multiples dispositivos. Con el buscador si pones el OID obtienes la descripción de que información contiene. Hay también MIB privados que solo los puedes conseguir a través de la marca si es que los quiere compartir o vender.


Otras técnicas

Nmap también tiene otras técnicas más sofisticadas solo últiles para usuarios avanzados. Están basadas en TCP y el uso de los flags. Hemos visto ya algunos flags como el SYN, ACK y RST. Vamos a enumerarlos todos:

  • SYN: Synchronisation Sincronización. Para establecimiento de comunicación.
  • ACK: Acknowledgment Reconocimiento o aceptación de la comunicación.
  • RST: Reset Comunicación no aceptada y cortada de manera súbita.
  • PSH: Push Empujar la información inmediatamente a las aplicaciones o protocolos de capa superior.
  • URG: Urgent Parecido a PSH pero urgente.
  • ECE: Explicit Congestion Notification [ECN]-Echo Usado por algunos dispositivos como routers y otros con mucho tráfico para controlar que no se pierda información.
  • CWR: Congestion Windows Reduced Si el host emisor recibe un ECE (alerta de congestión) reduce la velocidad.
  • NS: Nonce Sum Flag experimental de momento sin uso conocido.

Desde el manual de nmap tienes con todo detalle como activar uno o varios flags ya sea con los parámetros específicos que hay para cada flag o combinándolos. Para conocer en detalle sN/sF/sX, -scanflags y el resto consulta https://nmap.org/man/es/man-port-scanning-techniques.html

Anteriormente vimos una imagen donde se aprecia como Wireshark registra los valores de los flags TCP en cada paquete.

Especificación de puertos

Hasta el momento ya hemos practicado como limitar el sondeo a algunos puertos concretos. Las formas posibles son:

-p

Permite seleccionar un puerto, rango o lista de puertos indicadados en el comando o en un archivo. Si no se especifica nada por defecto serán puertos TCP. Ejemplos:

#sondear el puerto 22
nmap 127.0.0.1 -p 22
#sondear los puertos indicados
nmap 127.0.0.1 -p 22,80,443
#sondear el rango de puertos separados por -
nmap 127.0.0.1 -p 1000-2000
#sondear todos los puertos, del 1 al 65535
nmap 127.0.0.1 -p-
#sondear los 'numero' puertos más comunes, según clasificación de Nmap. Nmap tiene listas para 1,3,5,10,20, etc
nmap 127.0.0.1 --top-ports 10
                        

Se pueden hacer sondeos mixtos de TCP y UDP especificando con T:puerto o rango y U:puerto o rango. También será necesario añadir los parámetros para queUDP -sU y al menos un tipo de sondeo TCP como -sS, -sF, o -sT

nmap 127.0.0.1 -sS -sU -p U:53,111,137,T:21-25,80,139,8080
                        

-F (Fast. Sondeo rápido (puertos limitados))

En manuales de versiones antiguas dice que cuando se especifica -F, nmap sondeará la lista de puertos contenida en el archivo nmap-services que en Ubuntu se encuentra en el directorio /usr/share/nmap. Hay también una diferencia con el número de puertos por omisión cuando no especificamos nada. En la actualidad son 1000 puertos.

En la versión actual de nmap en el manual en inglés dice que la opción -F solo sondeará una lista de los 100 puertos más comunes. Nos quedamos con este dato.

También es posible sondear los puertos contenidos en un fichero con el comando --datadir, excluir puertos o cambiar el orden del sondeo de puertos pero no vamos a profundizar en esos temas.

DETECCIÓN DE SERVICIOS Y VERSIONES

En las sondeos anteriores hemos podido comprobar que al sondear un equipo nos dice que puerto está abierto y que servicio tiene. En la realidad, el servicio que menciona no estaba verificado. Nmap tiene un archivo con una base de datos con los servicios que normalmente corren en cada puerto y es de ahí de donde "supone" el servicio utilizado. Evidentemente, eso no siempre se cumple. Cualquier administrador puedo hacer correr cualquier servicio en un puerto cualquiera. Algunos puertos como el 22/ssh, 21/ftp o 25/correo y muchos más suelen estar en el punto de mira de los ataques por lo que es frecuente que el administrador decida usar otros.

El archivo lo puedes consultar en /usr/share/nmap/nmap-services. Pongo un pequeño extracto donde vemos los servicios habituales en cada puerto:

ftp     21/sctp 0.000000        # File Transfer [Control] | File Transfer Protocol [Control]
ftp     21/tcp  0.197667        # File Transfer [Control]
ftp     21/udp  0.004844        # File Transfer [Control]
ssh     22/sctp 0.000000        # Secure Shell Login | The Secure Shell (SSH) Protocol
ssh     22/tcp  0.182286        # Secure Shell Login
ssh     22/udp  0.003905        # Secure Shell Login
telnet  23/tcp  0.221265
telnet  23/udp  0.006211
priv-mail       24/tcp  0.001154        # any private mail system
priv-mail       24/udp  0.000329        # any private mail system
smtp    25/tcp  0.131314        # Simple Mail Transfer

                        

Con el parámetro -sV sondeará el puerto confirmando que servicio y su versión realmente utiliza. Conocer la versión es muy importante para la seguridad. Si esa versión tiene alguna vulnerabilidad debemos actualizar el servicio porque ahí tenemos lo que los hackers llaman un vector de entrada. La busqueda de versiones es mucho mas lenta porque cada puerto abierto deberá compararse con un archivo que tiene patrones de miles de servicios y versiones. La lista va creciendo. Los creadores de Nmap nos piden que colaboremos informando de nuevos servicios y versiones si tenemos el patrón que lo detecta. Puedes ver el archivo de versiones en /usr/share/nmap/nmap-service-probes

Pongo una muestra de los complejos comandos match que aplica para detectar versión y servicio para OpenSSH sobre Ubuntu. Para cada servicio hay decenas de comandos buscando patrones de coincidencia entre los muchos sistemas operativos y sus diferentes versiones. Es un archivo enorme con comandos complejos.

#OpenSSH
match ssh m|^SSH-([\d.]+)-OpenSSH_([\w._-]+)[ -]{1,2}Ubuntu[ -_]([^\r\n]+)\r?\n| p/OpenSSH/ v/$2 Ubuntu $3/ i/Ubuntu Linux; protocol $1/ o/Linux/ cpe:/a:openbsd:openssh:$2/ cpe:/o:canonical:ubuntu_linux/ cpe:/o:linux:linux_kernel/
                        

Gracias a este archivo la información de puertos pasa de algo así como esto donde se supone que servicio puede estar ahí:

nmap 127.0.0.1
Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-07 09:43 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000077s latency).
Not shown: 998 closed ports
PORT    STATE SERVICE
22/tcp  open  ssh
111/tcp open  rpcbind

                        

A esto otro verificado y con muchos más detalles:

nmap 127.0.0.1 -sV
Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-07 09:42 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000076s latency).
Not shown: 998 closed ports
PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
111/tcp open  rpcbind 2-4 (RPC #100000)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
                        

El sondeo de versiones se puede ajustar en intensidad del 0 (ligero) al 9 (completo). Un sondeo intenso será más lento pero más fiable. Si no se especifica intensidad por defecto es 7. Para cambiar el valor se añade --version-intensity numero.

Para buscar vulnerabilidades, podemos usar una herramienta muy conocida llamada searchsploit. Es una base de datos que contiene miles de versiones de servicios y aplicaciones con enlaces a programas en phyton y otros lenguajes para atacar objetivos. Searchsploit viene instalado en la distro Kali Linux. En Ubuntu, por el momento no se puede instalar fácilmente.

Si no tenemos una máquina con Kali podemos consultar https://www.exploit-db.com/

A través de su buscador ponemos el servicio y nos mostrará las versiones que se pueden atacar. Buscando por OpenSSH, no existen amenazas para la versión 8.2p1. ¿Quién sabe mañana? ;-)

Nmap Scripting Engine

Nmap permite ejecutar scripts para automatizar tareas de sondeo y llevarlo a otro nivel. Es una caracteristica muy poderosa para profundizar en el escaneo de puertos, servicios, versiones y sistemas operativos.

Los scripts están programados en lenguaje Lua. Se pueden usar tal cual, modificarlos a nuestras necesidades o crear uno totalmente nuevo ampliando la colección de scripts disponibles. Todos los scripts se encuentran en el directorio /usr/share/nmap/scripts. Allí actualmente encontraremos 599 scripts con la extensión .nse. (TRUCO: Para saber el número de archivos de un directorio ls | wc -l)

Otra manera de encontrar los scrips es con el comando locate .nse que mostrará la ruta completa de todas los archivos con extensión .nse. Si no tienes instalado locate lo puedes conseguir con sudo apt install mlocate

La enorme lista la podemos filtrar con grep. Si por ejemplo, solo queremos ver que scripts contienen ftp usaremos el comando:

ubuntu@ubuntusrv2:~$ locate .nse | grep ftp
/usr/share/nmap/scripts/ftp-anon.nse
/usr/share/nmap/scripts/ftp-bounce.nse
/usr/share/nmap/scripts/ftp-brute.nse
/usr/share/nmap/scripts/ftp-libopie.nse
/usr/share/nmap/scripts/ftp-proftpd-backdoor.nse
/usr/share/nmap/scripts/ftp-syst.nse
/usr/share/nmap/scripts/ftp-vsftpd-backdoor.nse
/usr/share/nmap/scripts/ftp-vuln-cve2010-4221.nse
/usr/share/nmap/scripts/tftp-enum.nse
                        

Los scripts se encuentran clasificados por categorías. Actualmente son estas:

  • auth
  • broadcast
  • brute
  • default
  • discovery
  • dos
  • exploit
  • external
  • fuzzer
  • intrusive
  • malware
  • safe
  • version
  • vuln

Para conocer que hace cada una de estas categorías y sus scripts disponibles consulta https://nmap.org/book/nse-usage.html#nse-categories y https://nmap.org/nsedoc/categories/

Existe una base de datos de los scripts y a que categoría pertenecen. Se encuentra en /usr/share/nmap/scripts/script.db. Muestro un extracto de los 3 primeros registros:

ubuntu@ubuntusrv2:~$ cat /usr/share/nmap/scripts/script.db
Entry { filename = "acarsd-info.nse", categories = { "discovery", "safe", } }
Entry { filename = "address-info.nse", categories = { "default", "safe", } }
Entry { filename = "afp-brute.nse", categories = { "brute", "intrusive", } }
                    

Vemos que los scripts pueden pertenecer a uno más categorías. Si queremos listar los scripts de una categoría concreta podemos filtrar con grep. Por ejemplo, para ver los que pertenecen a 'default':

cat /usr/share/nmap/scripts/script.db | grep default
                    

Otra formula para saber la categoría de un script es con el parámetro --script-help. La sintáxis es nmap --script-help nombre_del_script. Ejemplo:

ubuntu@ubuntusrv2:~$ nmap --script-help afp-brute.nse
Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-22 16:02 UTC

afp-brute
Categories: intrusive brute
https://nmap.org/nsedoc/scripts/afp-brute.html
  Performs password guessing against Apple Filing Protocol (AFP).

                    
Uso de Scripts

Los scripts se pueden usar de manera individual o colectiva por categorías. Así por ejemplo si queremos sondear un host usando los scripts de la categoría default usaremos nmap --script=default example.com o de forma abreviada nmap -sC example.com

Para usar un script cualquiera usaremos el parámetro --script= nombre_del_script. Si el script requiere argumentos se añade el parámetro --script-args y debemos buscar en la documentación que tipo de arguementos se necesitan.

Vamos a ver algunas ejemplos típicos usando scripts contra equipos de una red local y de internet. Lo primero que se me ocurre es probar algunas de estas categorías en un VPS. Conviene consultar la documentación para saber que puertos deben ser sondeados según el tipo de script seleccionado. En caso de no especificar puerto, el sondeo será sobre la lista de 1000 principales según nmap.

Empezamos con un sondeo a todos los scripts de la categoría 'default' que incluye una recopilación de scripts relacionados con la búsqueda de nombres de usuario, riesgo de intrusos por conexión ftp anónima, dominios web, etc

ubuntu@ubuntusrv2:~$ nmap 10.0.0.67  -sC
Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-21 18:28 UTC
Nmap scan report for ubuntusrv2.sub03110851270.masellavcn.oraclevcn.com (10.0.0.67)
Host is up (0.000095s latency).
Not shown: 998 closed ports
PORT    STATE SERVICE
22/tcp  open  ssh
111/tcp open  rpcbind
| rpcinfo:
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  3,4          111/tcp6  rpcbind
|_  100000  3,4          111/udp6  rpcbind

Nmap done: 1 IP address (1 host up) scanned in 0.45 seconds
                        

La siguiente prueba que se me ocurre es ejecutar scripts de la categoría 'intrusive' para detectar fallos de seguridad.

ubuntu@ubuntusrv2:~$ nmap 10.0.0.67  --script=intrusive
Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-21 18:55 UTC
Nmap scan report for ubuntusrv2.sub03110851270.masellavcn.oraclevcn.com (10.0.0.67)
Host is up (0.000084s latency).
Not shown: 998 closed ports
PORT    STATE SERVICE
22/tcp  open  ssh
| ssh-auth-methods:
|   Supported authentication methods:
|_    publickey
|_ssh-brute: Password authentication not allowed
| ssh-publickey-acceptance:
|_  Accepted Public Keys: No public keys accepted
|_ssh-run: Failed to specify credentials and command to run.
111/tcp open  rpcbind

Host script results:
| dns-brute:
|_  DNS Brute-force hostnames: No results.

Nmap done: 1 IP address (1 host up) scanned in 10.80 seconds

                        

Otra forma de agrupar scripts para ejecutar es con el caracter asterisco '*' en su conocido uso de comodín. Si queremos ejecutar todos los scripts que empiecen por 'http':

nmap x.x.x.x --script=http*
                        

Si el comodín da error se debe escapar con la barra invertida 'http\*'. A mi personalmente no me hizo falta en varios equipos Windows y Ubuntu pero he visto casos de otros sistemas o versiones donde era necesario.

También es posible especeficar varios scripts en una sola sentencia nmap añadiendo sus nombres separados por comas:

nmap x.x.x.x --script=acarsd-info, address-info
                        

Algunos scripts requieren argumentos donde se indica algún fichero con diccionario de claves o otros datos. Son los llamados scripts de fuerza bruta que buscan usuarios y contraseñas "fáciles" usando grandes listados de posibles claves. Como experimento, habilito en un ordenador local con Windows el protocolo SNMP con la comunidad por defecto que tiene el nombre "public" con permisos de solo lectura. Ese nombre, al ser sobradamente conocido, es poco seguro si queremos evitar que alguien puede sacar datos del equipo.

En Windows se habilita SNMP desde Herramientas Administrativas -> Servicios -> Servicio SNMP.

Primero voy a ejecutar la sentencia buscando nombres por fuerza bruta usando el diccionario de nombres por defecto que usa el script. En Linux se encuentra en /usr/share/nmap/nselib/data/snmpcommunities.lst. En este caso al ser el diccionario predeterminado no es necesario indicarlo.

Atención a que también ponemos el parámetro -sU porque SNMP va por protocolo UDP, normalmente el 161.

nmap -sU --script snmp-brute 127.0.0.1
Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-23 20:34 Hora de verano romance
Nmap scan report for space1.adminpressure.space (127.0.0.1)
Host is up (0.00077s latency).
Not shown: 991 closed udp ports (port-unreach)
PORT     STATE         SERVICE
123/udp  open|filtered ntp
137/udp  open|filtered netbios-ns
161/udp open           snmp
  | snmp-brute:
  |_  public - Valid credentials
1900/udp open|filtered upnp
3389/udp open|filtered ms-wbt-server
4500/udp open|filtered nat-t-ike
5050/udp open|filtered mmcc
5353/udp open|filtered zeroconf
5355/udp open|filtered llmnr

Nmap done: 1 IP address (1 host up) scanned in 49.85 seconds
                        

Como era de esperar lo ha encontrado porque usamos un nombre demasiado previsible existente en los diccionarios. A continuación cambio el nombre de la comunidad de 'public' al exótico 'tortilladepatata'. y repito la búsquida. En esta segunda ocasión el script no encuentra el nombre de la comunidad.

Puedo crear diccionarios a medida en un archivo .txt. Para ello desde cualquier editor voy poniendo una palabra en cada línea sin comas ni espacios. Aunque los originales son con extensión .lst nuestro diccionario puede ser .txt. Creo una lista de 3 palabras siendo una de ellas el nombre de la comunidad. (El ejemplo es un poco absurdo, es demostrativo de como se pueden encontrar fisuras de seguridad si usamos contraseñas y nombres muy frecuentes). El archivo resultante puede ser algo así como este:

public 
comunidadsecreta
tortilladepatata
                        

Ahora en la sentencia de snmp-brute indicamos como argumento el nombre del listado de comunidades. A estas alturas, imagino que no hace falta decir que si no estamos dentro del directorio del archivo hay que indicar la ruta:

nmap -sU --script snmp-brute --script-args snmp-brute.communitiesdb=lista.txt 127.0.0.1
Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-23 20:48 Hora de verano romance
Nmap scan report for space1.adminpressure.space (127.0.0.1)
Host is up (0.00029s latency).
Not shown: 991 closed udp ports (port-unreach)
PORT STATE SERVICE
123/udp open|filtered ntp
137/udp open|filtered netbios-ns
161/udp open          snmp
  | snmp-brute:
  |_  tortilladepatata - Valid credentials
1900/udp open|filtered upnp
3389/udp open|filtered ms-wbt-server
4500/udp open|filtered nat-t-ike
5050/udp open|filtered mmcc
5353/udp open|filtered zeroconf
5355/udp open|filtered llmnr
                        

Existen también scripts para buscar vulnerabilidades muy peligrosas como permitir conexiones ftp anónimas (Script ftp-anon) o conexiones SSH con diccionarios de parejas usuario y contraseña (Script ssh-brute). Si tienes un servidor con usuario 'admin' y password '12345678' ya estas tardando en cambiarlo porque esa es de las primeras que intentará el script :-)

Como final de este apartado dedicado a Nmap Script o NSE volver a recordar no hacer uso de estas técnicas sobre servidores ajenos. Se puede llegar a ralentizar el servicio o incluso bloquearlos y con todo el "ruido" que genera nuestra IP se puede rastrear y localizarnos. Si se trata de un 'pentesting' (prueba de penetración) de nuestra red también debemos ser cuidadosos porque podemos causar molestias a los usuarios de nuestros servidores.

Detección de sistema operativo

Con el parámetro -O nmap intentará detectar el sistema operativo. Lo que hace es analizar los bits de las respuestas que recibe por TCP y UDP y compara con una base de datos contenida en el archivo nmap-os-fingerprints del directorio /usr/share/nmap. Algunas de las comparaciones que hace es el análisis IPID y el tamaño inicial de ventana, análisis ISN de TCP o compatar opciones TCP y su orden entre otras muchas. El definitiva lo que hace es buscar la huella digital que tiene cada tipo de dispositivo y lo con el archivo nmap-os-fingerprints. Actualmente, el archivo tiene más de 1500 huellas y va creciendo con colaboraciones.

La detección de sistema operativo no es totalmente fiable y precisa. En mis pruebas con los móviles no es capaz de averiguar nada pero como por la MAC Address se sabe el fabricante por ahí podemos deducirlo. En la detección de Linux te informa sobre la versión de kernel, no dice nada sobre de que distribución se trata.

Desde mi red local voy a sondear otro equipo de mi red con Windows 8.

nmap 192.168.1.128 -O
Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-10 13:38 Hora de verano romance
Nmap scan report for 192.168.1.128
Host is up (0.0023s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT      STATE SERVICE
12345/tcp open  netbus
49152/tcp open  unknown
MAC Address: 20:47:47:0B:9F:C4 (Dell)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|specialized
Running (JUST GUESSING): Microsoft Windows XP (92%), AVtech embedded (87%), FreeBSD 6.X|10.X (86%)
OS CPE: cpe:/o:microsoft:windows_xp::sp3 cpe:/o:freebsd:freebsd:6.2 cpe:/o:freebsd:freebsd:10.3
Aggressive OS guesses: Microsoft Windows XP SP3 (92%), AVtech Room Alert 26W environmental monitor (87%), Microsoft Windows XP SP2 (87%), FreeBSD 6.2-RELEASE (86%), FreeBSD 10.3-STABLE (85%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop
OS detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 19.98 seconds
                        

Sondeando mi móvil tampoco supo decir que era.

nmap 192.168.1.184 -O
Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-11 20:46 Hora de verano romance
Nmap scan report for 192.168.1.184
Host is up (0.017s latency).
All 1000 scanned ports on 192.168.1.184 are in ignored states.
Not shown: 1000 closed tcp ports (reset)
MAC Address: FC:94:35:97:9F:00 (Huawei Technologies)
Too many fingerprints match this host to give specific OS details
Network Distance: 1 hop

OS detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 5.92 seconds
                        

Y como última prueba, sondeando un VPS con Linux:

sudo nmap 194.5.159.198 -O
Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-12 18:38 UTC
Nmap scan report for 194.5.159.198
Host is up (0.025s latency).
Not shown: 977 filtered ports
PORT      STATE  SERVICE
20/tcp    closed ftp-data
22/tcp    closed ssh
53/tcp    open   domain
110/tcp   open   pop3
143/tcp   open   imap
161/tcp   closed snmp
443/tcp   open   https
465/tcp   open   smtps
587/tcp   open   submission
993/tcp   open   imaps
995/tcp   open   pop3s
10000/tcp open   snet-sensor-mgmt
10001/tcp closed scp-config
10002/tcp closed documentum
10003/tcp closed documentum_s
10004/tcp closed emcrmirccd
10009/tcp closed swdtp-sv
10010/tcp closed rxapi
10012/tcp closed unknown
10024/tcp closed unknown
10025/tcp closed unknown
10082/tcp closed amandaidx
20000/tcp open   dnp
Aggressive OS guesses: Linux 2.6.32 (91%), Oracle VM Server 3.4.2 (Linux 4.1) (91%), Linux 3.10 - 4.11(91%), 
HP P2000 G3 NAS device (90%), Linux 3.0 (90%), Infomir MAG-250 set-top box (90%), Ubiquiti Air 
Max NanoStation WAP (Linux 2.6.32) (90%), Linux 3.10 (90%), Linux 3.2 (90%), Ubiquiti Pico Station WAP 
(AirOS 5.2.6) (90%)
No exact OS matches for host (test conditions non-ideal).

OS detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.38 seconds

                        

Tampoco me ha podido decir nada con 100% de seguridad. En un caso ideal de detección tendriamos algo así:

Device type: general purpose
Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6.32
OS details: Linux 2.6.32
                        

Para intentar mejorar la precisión en la detección del sistema existe el parámetro adicional --osscan-guess que hace un sondeo más agresivo pero también más lento. En mis pruebas no he tenido mejores resultados.

nmap x.x.x.x -O --osscan-guess  
                        

Para terminar con el apartado de detección de sistema operativo comento un problema sondeando mi propia red con una máquina linux en VirtualBox. Al sondear me aparecía el error:

osscan results may be unreliable because we could not find at least 1 open and 1 closed port

Sin enbargo, yo sabía con seguridad que el equipo sondeado tenía puertos abiertos y cerrados por lo que la causa del error debe ser otra. Investigando un poco en Stackoverflow comentan que este error aparece cuando se usan adaptadores de red NAT (Network Adress Translator).

Una solución es ir a al menú "Adaptadores de red" y seleccionr Opcion puente. Esto hará que la máquina virtual esté dentro del rango de red del anfitrión. Importante: los ajustes propios dentro de máquina Linux deben tener activos la configuración por DHCP o una IP fija del rango de red. Para ello si es una distro actual con Netplan se debe editar el archivo con extensión .yaml que está en /etc/netplan/ y aplicar los cambios.

La configuración de netplan está fuera del alcande de este artículo. Simplemente comentar que en mi caso funcionó y pude sondear equipos de mi red. El archivo .yaml debe quedar muy similar a éste:

network:
  version: 2
  renderer: networkd
  ethernets:
    enp3s0:
      dhcp4: true
                        
Control de tiempo y rendimiento

Si estamos examinando una red con muchos dispositivos se pueden demorar bastante los resultados. Podemos ajustar los intervalos de tiempo que emplea para sondear cada dispositivo para conseguir resultados antes. Un sondeo muy intensivo y rápido o hacer un sondeo más amable y lento consumiendo menos recursos.

Un sondeo rápido solo debe hacerse en redes de confianza porque puede resultar sospechoso para los sistemas de seguridad IDS (Sistemas de detección de intrusos) y los IPS (Intrusion Prevention System). Un IDS puede ser por software o hardware. Cuando detecta que desde una IP se están haciendo conexiones sospechosas salta una alarma que advierte al administrador de sistemas. La diferencia entre un firewall y un IDS es que el firewall impide las conexiones según unas reglas establecidas. El IDS no impide el paso de paquetes, simplemente mandará una alerta al administrador de sistemas para que tome medidas si fuera necesario. También tenemos los IPS que además de lanzar alarmas, pueden descartar paquetes y desconectar conexiones. Para Ubuntu un buen IPS/IDS por software libre y código abierto es Suricata

Hay varios parámetros que ajustan las esperas entre sondeos de puertos, el tiempo de respuesta de un host, número de puertos y dispositivos que sondea en paralelo algunos parámetros mas. Para facilitarnos un poco que parámetros escoger en nmap hay 6 plantillas de ajustes que van de -T0 la mas sigilosa y lenta a -T5 la más rápida y ruidosa. De esta forma, solo debemos preocuparnos de un solo parámetro que engloba a varios de ellos.

Si no especificamos ninguna plantilla, nmap usa el valor -T3. En la siguiente tabla tienes todos los modos de conexión.

Parámetro Ejemplo Descripción
-T0 nmap scanme.nmap.org -T0 Paranoico (0) El más discreto para evitar los IDS
-T1 nmap scanme.nmap.org -T1 Sigiloso (1) Menos silencioso que T0 pero también evita ser descubierto por los IDS
-T2 nmap scanme.nmap.org -T2 Amable (2) Es más lento por usar menos ancho de banda. Consume menos recursos de los equipos
-T3 nmap scanme.nmap.org -T3 Normal (3) Ajuste de velocidad predeterminada
-T4 nmap scanme.nmap.org -T4 Agresivo (4) Para infraestructuras confiables y muy rápidas
-T5 nmap scanme.nmap.org -T5 Loco (5) Velocidades de escaneo extraordinariamente rápidos

En los modos paranoico(-T0) y sigiloso(-T1) los tiempos de escaneo serán de varios minutos por cada dispositivo mientras que del normal(-T3) al loco (-T5) unos pocos segundos. Esto es así para intentar pasar desapercibido distanciando en tiempo los paquetes para no llamar la atención. En el modo -T0 solo se escanea un puerto a la vez y se espera 5 minutos para escanear el siguiente. En el modo -T1 espera 15s, -T2 solo 0.4s, cada vez menos tiempo hasta llegar a -T5 que espera 5ms.

En principio, con las plantillas se cubren suficientes casos de control de tiempo y rendimiento para que un usuario medio elija según sus necesidades. Dejamos para consultar en el manual si un usuario avanzado necesita algo personalizado.

Evasión de IDS y Firewall

Sondear un servidor donde se han puesto protecciones contra sondas tipo nmap no es tarea fácil y puede llevar horas de pruebas hasta encontrar una combinación de tiempos y protocolos para conectar con un servidor. Hasta ahora todas las pruebas de este artículo se han hecho sobre equipos sin especiales protecciones como el servidor que presta nmap para hacer prácticas o algunos VPS que uso para pruebas. Ese es un entorno demasiado ideal que no refleja la realidad. Esto tampoco es un curso de hacking. Aquí se pretende enseñar nmap para conocer el estado de nuestra infrastructura para corregir, si fuera necesario, alguna vulnerabilidad o intentar averiguar las razones por las que un servicio no está funcionando. Casos que pueden darse como montar un servidor web o ftp y no funciona. Nmap nos servirá para comprobar que los puertos de http/https y ftp están abiertos. Desde aquí solo veremos algunos trucos muy básicos para intentar evadir un firewall o IDS pero que están lejos de ser eficaces si queremos sondear una infrastructura protegida correctamente.

Algunos de los parámetros a continuación no aparecen en el manual como técnicas de evasión sino como técnicas de escaneo de puertos y ya los hemos tratado anteriormente en este artículo.

El primer truco que veremos es como saber si un host está vivo si no responde al comando ping. Este comando usa el protocolo ICMP y suele ser habitual filtrarlos desde el firewall para no ser detectados tan fácilmente. Como posible solución podemos poner -PR para que use el protocolo ARP (address resolution protocol). Ejemplo:

nmap scanme.nmap.org -PR

Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-28 08:27 UTC
Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up (0.16s latency).
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f
Not shown: 995 closed ports
PORT      STATE    SERVICE
22/tcp    open     ssh
25/tcp    filtered smtp
80/tcp    open     http
9929/tcp  open     nping-echo
31337/tcp open     Elite

Nmap done: 1 IP address (1 host up) scanned in 3.57 seconds

                        

Si nos en el puerto 25, nmap no puede saber si está abierto o cerrado y lo marca como filtrado. Para intentar saber algo más concreto podemos usar el parámetro -sN que envía paquetes sin flags (recordemos que los flags iban en la cabecera de cada paquete y podían ser SYN, ACK, RST, etc).

nmap scanme.nmap.org -sN -p 25

Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-28 08:48 UTC
Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up (0.15s latency).
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f

PORT   STATE         SERVICE
25/tcp open|filtered smtp

Nmap done: 1 IP address (1 host up) scanned in 1.79 seconds
                        

Tras este sondeo al puerto 25 sin flags responde open|filtered. No hay una garantía de que esté abierto al 100% pero podemos sospechar que es bastante probable.

Otro técnica básica para recordar es el uso del parámetro -sX que ya vimos con la ayuda de Wireshark como enviaba combinaciones de flags. En este caso la respuesta que me da es idéntica al parámetro usado anteriormente -sN

Ahora ya vamos a ver algunos parámetros que el manual oficial de nmap ya clasifica como específicos de evasión. El primero de la lista es -f que divide los paquetes en pequeños fragmentos para intentar engañar a la medidas de seguridad. Una de las formas de detectar sondeos de los IDS es comparando paquetes a nivel de bits con una base de datos de paquetes sospechosos. Si el paquete llega en pequeños fragmentos aleatorios le ponemos un poco más difícil al IDS detectar de que se trata y puede que nos deje pasar.

nmap scanme.nmap.org -f

Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-28 09:13 UTC
Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up (0.15s latency).
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f
All 1000 scanned ports on scanme.nmap.org (45.33.32.156) are filtered

Nmap done: 1 IP address (1 host up) scanned in 154.10 seconds
                        

En esta prueba tras casi 3 minutos de espera con sondeo fragmentado no tenemos resultado. Las técnicas de sondeo no son universales y tenemos que ir probando cual da mejores resultados y hasta incluso hacer combinaciones de escaneo. En el siguiente ejemplo vamos a sondear el puerto 25, que es el que por defecto nmap no puede decirnos como está, con una combinación de técnicas. Usaremos la fragmentación -f, el escaneo nulo -sN, no hacer descubrimiento de host -Pn y tampoco hacer resolución dns -n. Obviamente, esta combinación o cualquier otra que queramos experimentar es para cuando no obtenemos una respuesta concreta. Si con métodos sencillos se consigue no va a variar el resultado por usar combinaciones.

root@ubuntusrv2:/home/ubuntu# nmap scanme.nmap.org -p 25 -f -sN -n -Pn
Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-30 17:27 UTC
Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up.
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f

PORT   STATE         SERVICE
25/tcp open|filtered smtp

Nmap done: 1 IP address (1 host up) scanned in 2.11 seconds
                        

En lo que respecta a los flags, es más probable saltarse el firewall si no enviamos ninguno o alguno del tipo que termina la comunicación como FIN o RST que no enviando uno de reconocimiento de comunicación como el ACK.

Sobre evasión IDS/IPS y firewall no vamos a tratar más en este artículo. Deberás mirar la documentación oficial en inglés (mucho más actualizada y completa que la existente en castellano). En https://nmap.org/book/firewalls.html tenemos explicaciones de varias técnicas para intentar sondear servidores evitando el firewall y también lo contrario, es decir, como proteger nuestros servidores de ataques y sondeos con nmap.

Salida

La respuesta del sondeo se puede redirigir a un archivo en formato texto o XML. Para ello solo es necesario añadir el parámetro -oN para texto o -oX para XML. El archivo en XML se verá muy bien con tablas y títulos como si fuera una página web desde el el viejo Internet Explorer de Windows. Con navegadores actuales como Bing, Chrome, Firefox hay extensiones XML que muestran el código XML estructurado en árbol.

nmap 127.0.0.1 -oN sondeo.txt
nmap 127.0.0.1 -oX sondeo.xml
                        

Aunque nmap no permite exportar en HTML para verlo en un navegador, sí es posible convertir el XML a código HTML añadiendo --webxml. Con esto el resultado desde un navegador será maquetado con hojas de estilo CSS.

nmap 127.0.0.1 --webxml -oX sondeo.xml
                        

Ahora desde navegador se verá así de bien:
(NOTA: Con el viejo Internet Explorer no es necesario añadir --webxml para conseguir el mismo resultado)

En cualquier sentencia de nmap podemos añadir el parámetro -v para que de más información de que paquetes está enviando y recibiendo y otros datos. Si ponemos -vv o -vvv aunmenta la la cantidad de información que mostrará sobre como va la comunicación entre nmap y el objetivo, los flags que usa, el ttl y otros datos.

root@ubuntusrv2:/home/ubuntu# nmap scanme.nmap.org -p 80 -vvv
Starting Nmap 7.80 ( https://nmap.org ) at 2022-10-06 15:08 UTC
Warning: Hostname scanme.nmap.org resolves to 2 IPs. Using 45.33.32.156.
Initiating Ping Scan at 15:08
Scanning scanme.nmap.org (45.33.32.156) [4 ports]
Completed Ping Scan at 15:08, 0.18s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 15:08
Completed Parallel DNS resolution of 1 host. at 15:08, 0.00s elapsed
DNS resolution of 1 IPs took 0.00s. Mode: Async [#: 1, OK: 1, NX: 0, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 15:08
Scanning scanme.nmap.org (45.33.32.156) [1 port]
Discovered open port 80/tcp on 45.33.32.156
Completed SYN Stealth Scan at 15:08, 0.19s elapsed (1 total ports)
Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up, received reset ttl 55 (0.15s latency).
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f
Scanned at 2022-10-06 15:08:09 UTC for 0s

PORT   STATE SERVICE REASON
80/tcp open  http    syn-ack ttl 56

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.45 seconds
           Raw packets sent: 5 (196B) | Rcvd: 2 (84B)
                            

Si esto nos parece poco, podemos jugar con los niveles de depuración -d y el --packet-trace pero nos vamos a encontrar docenas o cientos de líneas con información de datos a bajo nivel y no es posible abarcarlo en este manual de introducción.

MISC

Siguiendo con la respuesta de man --help llegamos al apartado MISC de aquí destacamos la opción -A. Es una forma abreviada de indicar con un solo parámetro que sondeo con las opciones de detecciión de SO, versión detection, escaneo script y mostrar los saltos de ruta (traceroute).

Ejemplos

El último apartado es justamente lo que dice el título. Algunos ejemplos pero pienso que a lo largo de este resumen ya los hemos practicado todos. Hago un copiar/pegar para refrescar la memoria:

nmap -v -A scanme.nmap.org
nmap -v -sn 192.168.0.0/16 10.0.0.0/8
nmap -v -iR 10000 -Pn -p 80
                        
Extra Bonus

Para acabar un enlace a lo que llaman "cheat sheet" de nmap pero que a mi me gusta llamar "chuleta":

https://gist.github.com/rsperl/321aac3d529aa8f8c7924fd12d581b67