
Escanea redes en busca de servidores Microsoft Exchange vulnerables a CVE-2020-0688, utilizando zmap para el descubrimiento de hosts y la toma de huellas TLS/versión para identificar instancias sin parchear.
CVE-2020-0688 es una vulnerabilidad crítica en Microsoft Exchange debido al uso de claves estáticas. Aunque la explotación requiere credenciales válidas (a nivel de usuario de correo electrónico) y el riesgo de explotación masiva es bajo, esta vulnerabilidad podría ser muy útil en ataques dirigidos, ya que conduce a RCE a nivel de SYSTEM.
Más información:
Existen varias fuentes conocidas de falsos negativos (servidores Exchange vulnerables que este script pasará por alto):
Los posibles servidores Exchange se preseleccionan identificando hosts que tengan tanto el puerto 25 como el 443 abiertos. Si hay configuraciones que bloqueen alguno de estos, se omitirán.
zmap está optimizado para velocidad y escalabilidad a expensas de la precisión. Normalmente, múltiples ejecuciones consecutivas de zmap arrojan resultados ligeramente diferentes. Como resultado, múltiples ejecuciones de este script mostrarán resultados ligeramente diferentes también.
No estamos seguros de si esto se debe puramente a la congestión de la red o a código con errores. ¡Sin duda se aceptan Pull-request con parches/soluciones alternativas!
No estamos tratando de ser sigilosos aquí, por lo que algunos firewalls podrían simplemente bloqueamos como un robot.
Dado que no estamos haciendo ningún fingerprinting sofisticado y solo confiamos en la versión que el servidor Exchange informa de sí mismo, estamos limitados a los primeros tres campos del número de versión.
Por ejemplo, la última actualización acumulativa para Exchange Server 2019 es 15.2.529.5, que se lanzó en diciembre y es vulnerable. La última actualización que contiene el parche es 15.2.529.8. Ambos informan su versión como 15.2.529, por lo que el script asumirá que el servidor está parcheado incluso si no tiene el último parche instalado y es vulnerable.
En la práctica, parece que hay administradores de Exchange que actualizan sus sistemas tan pronto como salen los parches, o aquellos que viven según el principio de "si funciona, no lo toques". No hay término medio.
zmap, Python >= 3.5, módulos:
Puedes instalarlos globalmente con:
$ sudo dnf install zmap python3-gevent python3-dns python3-pyOpenSSL
o:
$ sudo apt install zmap python3-gevent python3-dns python3-openssl
Los módulos de Python también se pueden instalar localmente, a través de virtualenv:
$ virtualenv -p python3 CVE-2020-0688
$ . ./CVE-2020-0688/bin/activate
$ pip install -r ./requirements.txt
Para un escaneo básico, solo necesitas un archivo con IPs/subredes (en formato CIDR) para escanear:
$ ./scan.py ~/my_networks.txt output.csv
La salida se escribirá en formato CSV con las siguientes columnas:
| IP | Versión de Exchange | Nombre del servidor | PTR | Nombre común (del certificado TLS) |
|---|
Opcionalmente, puedes solicitar que se muestre información de todos los servidores Exchange encontrados:
$ ./scan.py -f ~/my_networks.txt output.csv
En ese caso, habrá una columna más para indicar si el servidor es vulnerable o no:
| IP | Versión de Exchange | ¿Vulnerable? | Nombre del servidor | PTR | Nombre común (del certificado TLS) |
|---|
También puedes proporcionar un archivo con IPs/subredes en lista negra (opción -b), cambiar el número de tareas paralelas (-p) o la duración de los tiempos de espera (-t):
$ # ./scan.py -h
usage: scan.py [-h] [-b BLACKLIST] [-f] [-p PARALLEL] [-t TIMEOUT]
input output
Identify Exchange servers vulnerable to CVE-2020-0688.
positional arguments:
input Input file, each line contains one IP/subnet
output File to save the results (in CSV format)
optional arguments:
-h, --help show this help message and exit
-b BLACKLIST, --blacklist BLACKLIST
File containing IPs/subnets to avoid
-f, --full Don't filter seemingly up-to-date Exchange servers
-p PARALLEL, --parallel PARALLEL
How many requests to send in parallel (default: 1000)
-t TIMEOUT, --timeout TIMEOUT
Timeout (seconds) to use for network connections
(default: 5)