ZMap es un escáner de red open source que permite a investigadores realizar estudios de red a nivel Internet de forma simple. Con sólo una simple computadora y un buen uplink a Internet, ZMap es capaz de realizar un escaneo completo del espacio de direcciones IPv4 en menos de 5 minutos, aproximándose al límite teórico de 10 Gigabit Ethernet. ZMap puede ser utilizado para estudiar la adopción de protocolos a lo largo del tiempo, monitorear la disponibilidad de servicios, y ayudar a entender mejor grandes sistemas distribuidos a lo largo de Internet. Está disponible un paper que explica en detalle la arquitectura del escáner, realiza una comparación con nmap, e incluye una guía de buenas prácticas a la hora de llevar a cabo experimentos con esta herramienta (cómo ser un buen ciudadano de Internet).



Este artículo explica cómo compilar ZMap desde sus fuentes y está orientado a sistemas FreeBSD, aunque el procedimiento es exactamente igual en sistemas GNU/Linux.

El código fuente de ZMap está hospedado en GitHub, entonces, el primer paso consiste en clonar una copia del repositorio en nuestro sistema local:

# git clone https://github.com/zmap/zmap.git

Al finalizar la descarga se crea el directorio "zmap":

cd zmap/

El proceso de compilación e instalación es trivial y se encuentra documentado en el archivo "INSTALL":

# less INSTALL

Configurar el paquete utilizando cmake:

root@hal9000:/usr/home/emi/packages/zmap # cmake ./
-- The C compiler identification is Clang 3.4.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found PkgConfig: /usr/local/bin/pkg-config (found version "0.28") 
-- checking for module 'json-c'
--   package 'json-c' not found
CMake Error at CMakeLists.txt:71 (message):
  Did not find libjson


-- Configuring incomplete, errors occurred!
See also "/usr/home/emi/packages/zmap/CMakeFiles/CMakeOutput.log".

En caso de errores, instalar las dependencias faltantes, en este caso json-c:

pkg install json-c

Volver a configurar hasta que no arroje errores de dependencias:

root@hal9000:/usr/home/emi/packages/zmap # cmake ./
-- checking for module 'json-c'
--   found json-c, version 0.12
-- Configuring done
-- Generating done
-- Build files have been written to: /usr/home/emi/packages/zmap

Luego simplemente compilar e instalar:

make
make install

EL paquete no incluye una página de manual, pero es posible obtener ayuda ejecutando zmap --help:

root@hal9000:/usr/home/emi/packages/zmap # zmap --help
zmap 2.1.0-RC1

A fast Internet-wide scanner.

Usage: zmap [OPTIONS]... [SUBNETS]...

Basic arguments:
  -p, --target-port=port        port number to scan (for TCP and UDP scans)
  -o, --output-file=name        Output file
  -b, --blacklist-file=path     File of subnets to exclude, in CIDR notation,
                                  e.g. 192.168.0.0/16
  -w, --whitelist-file=path     File of subnets to constrain scan to, in CIDR
                                  notation, e.g. 192.168.0.0/16

Scan options:
  -r, --rate=pps                Set send rate in packets/sec
  -B, --bandwidth=bps           Set send rate in bits/second (supports suffixes
                                  G, M and K)
  -n, --max-targets=n           Cap number of targets to probe (as a number or
                                  a percentage of the address space)
  -t, --max-runtime=ses         Cap length of time for sending packets
  -N, --max-results=n           Cap number of results to return
  -P, --probes=n                Number of probes to send to each IP
                                  (default=`1')
  -c, --cooldown-time=secs      How long to continue receiving after sending
                                  last probe  (default=`8')
  -e, --seed=n                  Seed used to select address permutation
      --retries=n               Max number of times to try to send packet if
                                  send fails  (default=`10')
  -d, --dryrun                  Don't actually send packets
      --shards=N                Set the total number of shards  (default=`1')
      --shard=n                 Set which shard this scan is (0 indexed)
                                  (default=`0')

Network options:
  -s, --source-port=port|range  Source port(s) for scan packets
  -S, --source-ip=ip|range      Source address(es) for scan packets
  -G, --gateway-mac=addr        Specify gateway MAC address
      --source-mac=addr         Source MAC address
  -i, --interface=name          Specify network interface to use
  -X, --vpn                     Sends IP packets instead of Ethernet (for VPNs)

Probe Modules:
  -M, --probe-module=name       Select probe module  (default=`tcp_synscan')
      --probe-args=args         Arguments to pass to probe module
      --list-probe-modules      List available probe modules

Data Output:
  -f, --output-fields=fields    Fields that should be output in result set
  -O, --output-module=name      Select output module  (default=`default')
      --output-args=args        Arguments to pass to output module
      --output-filter=filter    Specify a filter over the response fields to
                                  limit what responses get sent to the output
                                  module
      --list-output-modules     List available output modules
      --list-output-fields      List all fields that can be output by selected
                                  probe module

Logging and Metadata:
  -v, --verbosity=n             Level of log detail (0-5)  (default=`3')
  -l, --log-file=name           Write log entries to file
  -L, --log-directory=directory Write log entries to a timestamped file in this
                                  directory
  -m, --metadata-file=name      Output file for scan metadata (JSON)
  -u, --status-updates-file=name
                                Write scan progress updates to CSV file
  -q, --quiet                   Do not print status updates
      --disable-syslog          Disables logging messages to syslog
      --notes=notes             Inject user-specified notes into scan metadata
      --user-metadata=json      Inject user-specified JSON metadata into scan
                                  metadata

Additional options:
  -C, --config=filename         Read a configuration file, which can specify
                                  any of these options
                                  (default=`/etc/zmap/zmap.conf')
      --max-sendto-failures=n   Maximum NIC sendto failures before scan is
                                  aborted  (default=`-1')
      --min-hitrate=n           Minimum hitrate that scan can hit before scan
                                  is aborted  (default=`0.0')
  -T, --sender-threads=n        Threads used to send packets  (default=`1')
      --cores=STRING            Comma-separated list of cores to pin to
      --ignore-invalid-hosts    Ignore invalid hosts in whitelist/blacklist
                                  file
  -h, --help                    Print help and exit
  -V, --version                 Print version and exit

Examples:
    zmap -p 80 (scan the Internet for hosts on tcp/80 and output to stdout)
    zmap -N 5 -B 10M -p 80 (find 5 HTTP servers, scanning at 10 Mb/s)
    zmap -p 80 10.0.0.0/8 192.168.0.0/16 -o (scan both subnets on tcp/80)
    zmap -p 80 1.2.3.4 10.0.0.3 (scan 1.2.3.4, 10.0.0.3 on tcp/80)

Probe-module (tcp_synscan) Help:
Probe module that sends a TCP SYN packet to a specific port. Possible 
classifications are: synack and rst. A SYN-ACK packet is considered a success 
and a reset packet is considered a failed response.

Output-module (csv) Help:
By default, ZMap prints out unique, successfulIP addresses (e.g., SYN-ACK from 
a TCP SYN scan) in ASCII form (e.g., 192.168.1.5) to stdout or the specified 
output file. Internally this is handled by the "csv" output module and is 
equivalent to running zmap --output-module=csv --output-fields=saddr 
--output-filter="success = 1 && repeat = 0".

Se observa que las opciones son simples y están muy bien detalladas.

A modo de prueba, se me ocurrió escanear todos los puertos 80 abiertos escuchando peticiones dentro de mi red de trabajo:

root@hal9000:/usr/home/emi/packages/zmap # zmap -i em0 -p 80 192.168.100.0/20 -o ~/scan80.txt
Aug 19 10:59:12.103 [WARN] blacklist: ZMap is currently using the default blacklist located at /etc/zmap/blacklist.conf. By default, this blacklist excludes locally scoped networks (e.g. 10.0.0.0/8, 127.0.0.1/8, and 192.168.0.0/16). If you are trying to scan local networks, you can change the default blacklist by editing the default ZMap configuration at /etc/zmap/zmap.conf.
Aug 19 10:59:12.109 [INFO] zmap: output module: csv
 0:00 0%; send: 0 0 p/s (0 p/s avg); recv: 0 0 p/s (0 p/s avg); drops: 0 p/s (0 p/s avg); hitrate: 0.00%
 0:01 13%; send: 4096 done (291 Kp/s avg); recv: 156 155 p/s (154 p/s avg); drops: 0 p/s (0 p/s avg); hitrate: 3.81%
 0:02 25%; send: 4096 done (291 Kp/s avg); recv: 158 1 p/s (78 p/s avg); drops: 0 p/s (0 p/s avg); hitrate: 3.86%
 0:03 38%; send: 4096 done (291 Kp/s avg); recv: 160 1 p/s (53 p/s avg); drops: 0 p/s (0 p/s avg); hitrate: 3.91%
 0:04 50%; send: 4096 done (291 Kp/s avg); recv: 160 0 p/s (39 p/s avg); drops: 0 p/s (0 p/s avg); hitrate: 3.91%
 0:05 63% (3s left); send: 4096 done (291 Kp/s avg); recv: 160 0 p/s (31 p/s avg); drops: 0 p/s (0 p/s avg); hitrate: 3.91%
 0:06 75% (2s left); send: 4096 done (291 Kp/s avg); recv: 161 0 p/s (26 p/s avg); drops: 0 p/s (0 p/s avg); hitrate: 3.93%
 0:07 88% (1s left); send: 4096 done (291 Kp/s avg); recv: 161 0 p/s (22 p/s avg); drops: 0 p/s (0 p/s avg); hitrate: 3.93%
Aug 19 10:59:20.147 [INFO] zmap: completed

Con el parámetro -i se especifica una interfaz Ethernet de salida a Internet, -p indica el puerto a testear y con -o el nombre del archivo de salida. El parámetro restante consiste en las subredes a escanear.

Se observa que en apenas 8 segundos escaneó los puertos 80 de todas las direcciones IP de una subred con máscara 20, loo que equivale a 16 redes clase C (más de 4000 direcciones IPv4).

El archivo de salida posee una línea por cada dirección IP que acepta peticiones en el puerto especificado (en este caso el 80):

root@hal9000:/usr/home/emi/packages/zmap # head ~/scan80.txt
192.168.100.54
192.168.100.233
192.168.101.38
192.168.100.127
192.168.101.171
192.168.102.10
192.168.100.224
192.168.101.173
192.168.101.188
192.168.100.120

En total encontró 161 direcciones IPv4 escuchando pedidos en el puerto 80:

root@hal9000:/usr/home/emi/packages/zmap # wc -l scan80.txt 
     161 scan80.txt

Es claro que esta herramienta es muchísimo más limitada que Nmap en cuanto a funcionalidades respecta. Cabe destacar que Nmap está orientada a tareas específicas de seguridad informática y administración de sistemas, mientras que ZMap está optimizada para alcanzar la máxima velocidad posible, es decir, minimizar el tiempo de escaneo.

(Nunca he escrito un artículo dedicado a Nmap, una de mis herramientas favoritas. Algún día lo haré, me desmotiva un poco que existan millones de artículos al respecto.)

A pesar de que ZMap es una herramienta poderosa para investigadores, se debe tener en cuenta que, al correr ZMap, se está escaneando potencialmente todo el espacio de direcciones IPv4. Muchos usuarios (administradores de sistemas en particular) pueden no apreciar dicho comportamiento. Los usuarios de ZMap deben honrar las solicitudes de detención de escaneo y excluir las redes involucradas en futuros escaneos. Además es recomendable notificar a los administradores de los nodos de red locales antes de ejecutar escaneos sobre subredes externas, ya que esto puede traer consecuencias negativas en lo que respecta a spam, malware y listas negras de direcciones IP.

Referencias

ZMap Internet Scanner

ZMap on GitHub

ZMap Documentation


Tal vez pueda interesarte


Compartí este artículo