Herramientas de usuario

Herramientas del sitio


informatica:programacion:cursos:python_avanzado_proyectos_seguridad:ejecutar_scripts_nmap_detectar_servicios_vulnerabilidades

Ejecutar scripts de nmap para detectar servicios y vulnerabilidades

Módulo perteneciente al curso Python avanzado para proyectos de seguridad

Nmap es una herramienta muy conocida en el mundo de seguridad informática por su funcionalidad de escaneo de redes, puertos y servicios. Una de las características más interesantes que tiene nmap es la posibilidad de ejecutar scripts que siguen la especificación NSE (Nmap Scripting Engine).

NSE es una herramienta que permite extender los tipos de escaneos que se pueden realizar e incluso realizar tareas de detección de vulnerabilidades en los servicios. De esta forma, a parte de detectar si un determinado puerto está abierto o cerrado, también podemos ejecutar rutinas más complejas que permiten filtrar información sobre un determinado objetivo.

Actualmente incorpora el uso de scripts para comprobar algunas de las vulnerabilidades más conocidas. Estos scripts están ordenados por categorías de la siguiente manera:

  • Auth: scripts disponibles para autenticación.
  • Default: ejecuta los scripts básicos por defecto.
  • Discovery: scripts disponibles para recupera información del objetivo.
  • External: script que contactan con fuentes externas.
  • Intrusive: scripts que son considerados intrusivos para el objetivo.
  • Malware: scripts que comprueban la presencia de conexiones abiertas por códigos maliciosos o backdoors (puertas traseras)
  • Safe: ejecuta scripts que no son intrusivos.
  • Vuln: scripts que comprueban vulnerabilidades más conocidas y comummente explotadas.
  • All: ejecuta absolutamente todos los scripts con extensión NSE disponibles.

Por lo general, el motor de scripts de NMAP puede ejecutar diferentes funcionalidades entre las que podemos destacar:

  • Descubrimiento de redes: Esta es la función básica de NMAP. Los ejemplos incluyen encontrar la información whois del nombre de dominio de destino, encontrar puertos abiertos, consultas SNMP y enumerar los recursos y servicios NFS / SMB / RPC disponibles.
  • Detección de vulnerabilidades: Cuando se descubre una nueva vulnerabilidad, sería importante escanear la red para identificar los sistemas vulnerables antes que los atacantes los encuentren. En este aspecto, NSE nos podría ayudar a realizar comprobaciones de vulnerabilidades que podemos encontrar en los diferentes servicios que exponen los servidores.

Para detectar posibles vulnerabilidades en los servicios de los puertos que están abiertos podemos hacer uso de los scripts de nmap que están disponibles cuando se instala el módulo. En el caso de distribuciones basadas en Linux, los scripts se encuentran en la ruta:

/usr/share/nmap/scripts

Los scripts permiten la programación de rutinas para encontrar posibles vulnerabilidades en determinado host.

Ejecución scripts de nmap

Hay una gran cantidad de scripts para cada tipo de servicio del cual queramos conocer más. Hay incluso algunos que permiten realizar ataques por diccionario o fuerza bruta y explotar determinadas vulnerabilidades en algunos de los servicios y puertos que exponen las máquinas.

Para ejecutar estos scripts es necesario pasar la opción --script dentro del comando de nmap.

La sintaxis para ejecutar un script determinado o incluso una determinada categoría es la siguiente:

$ nmap --script (nombre del script) {target}
$ nmap --script (categoría) {target}

En este ejemplo ejecutamos nmap con la opción por defecto (default) para hacer un escaneo de puertos con los scripts por defecto.

$ nmap --script default scanme.nmap.org
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
| ssh-hostkey: 
|   1024 ac:00:a0:1a:82:ff:cc:55:99:dc:67:2b:34:97:6b:75 (DSA)
|   2048 20:3d:2d:44:62:2a:b0:5a:9d:b5:b3:05:14:c2:a6:b2 (RSA)
|   256 96:02:bb:5e:57:54:1c:4e:45:2f:56:4c:4a:24:b2:57 (ECDSA)
|_  256 33:fa:91:0f:e0:e1:7b:1f:6d:05:a2:b0:f1:54:41:56 (EdDSA)
80/tcp    open     http
|_http-title: Go ahead and ScanMe!
646/tcp   filtered ldp
9929/tcp  open     nping-echo
31337/tcp open     Elite  

Lanzar script categoría discovery

Por ejemplo, si quisiéramos ejecutar todos los scripts de la categoría discovery para un determinado target, lo podríamos ejecutar con el comando:

$ nmap -script discovery scanme.nmap.org
Not shown: 995 closed ports
PORT      STATE    SERVICE
22/tcp    open     ssh
|_banner: SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.13
| ssh-hostkey: 
|   1024 ac:00:a0:1a:82:ff:cc:55:99:dc:67:2b:34:97:6b:75 (DSA)
|   2048 20:3d:2d:44:62:2a:b0:5a:9d:b5:b3:05:14:c2:a6:b2 (RSA)
|   256 96:02:bb:5e:57:54:1c:4e:45:2f:56:4c:4a:24:b2:57 (ECDSA)
|_  256 33:fa:91:0f:e0:e1:7b:1f:6d:05:a2:b0:f1:54:41:56 (EdDSA)
| ssh2-enum-algos: 
|   kex_algorithms: (8)
|   server_host_key_algorithms: (4)
|   encryption_algorithms: (16)
|   mac_algorithms: (19)
|_  compression_algorithms: (2)
80/tcp    open     http
| http-affiliate-id: 
|   Google Adsense ID: pub-0078565546631069
|_  Google Analytics ID: UA-11009417-1
|_http-apache-negotiation: mod_negotiation enabled.
|_http-chrono: Request times for /; avg: 534.02ms; min: 452.24ms; max: 657.39ms
| http-comments-displayer: 
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=scanme.nmap.org
|     
|     Path: http://scanme.nmap.org/shared/css/insecdb.css
|     Line number: 394
|     Comment: 
|         /* For comment forms. */
|     
|     Path: http://scanme.nmap.org/shared/css/insecdb.css
|     Line number: 214
|     Comment: 
|         /* SecTools style */
|     
|     Path: http://scanme.nmap.org/shared/css/insecdb.css
|     Line number: 172
|     Comment: 
|         /* Style for the left navigation sidebar. */
|     
|     Path: http://scanme.nmap.org/
|     Line number: 109
|     Comment: 
|         &amp;<!-- Begin Sidebar Banner Code -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 32
|     Comment: 
|         &amp;<!--End Google Custom Site Search boilerplate Javascript-->
|     
|     Path: http://scanme.nmap.org/shared/css/insecdb.css
|     Line number: 11
|     Comment: 
|         /* Wikipedai uses 5a3696 for visited links, which is similar to the default.  Since my
|            visited links are not underlined, I think I'll make them brighter to stand out more from
|            the text */
|     
|     Path: http://scanme.nmap.org/
|     Line number: 41
|     Comment: 
|         &amp;<!-- Begin TopBanner Code -->
|     
|     Path: http://scanme.nmap.org/shared/css/insecdb.css
|     Line number: 88
|     Comment: 
|         /* Make the whole table call clickable. */
|     
|     Path: http://scanme.nmap.org/
|     Line number: 101
|     Comment: 
|         &amp;<!-- These can come back if I ever update them ...
|         &amp;<li&amp;>&<a href="http://insecure.org/links.html">Exceptional Links&</a&amp;>&</li&amp;>
|         &amp;<li&amp;>&<a href="http://insecure.org/reading.html">Good Reading&</a&amp;>&</li&amp;>
|         &amp;<li&amp;>&<a href="http://insecure.org/sploits.html">Exploit World&</a&amp;>&</li&amp;>
|         --&amp;>
|     
|     Path: http://scanme.nmap.org/shared/css/insecdb.css
|     Line number: 165
|     Comment: 
|         /* Makes a purple box with big bold text */
|     
|     Path: http://scanme.nmap.org/
|     Line number: 99
|     Comment: 
|         &amp;<!-- End SiteSearch Google -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 111
|     Comment: 
|         &amp;<!-- End Sidebar Banner Code -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 125
|     Comment: 
|         &amp;<!-- End Bottom (Google) Sidebar Banner Code -->
|     
|     Path: http://scanme.nmap.org/shared/css/insecdb.css
|     Line number: 66
|     Comment: 
|         /* SecLists style */
|     
|     Path: http://scanme.nmap.org/
|     Line number: 170
|     Comment: 
|         &amp;<!-- End Bottom Banner -->
|     
|     Path: http://scanme.nmap.org/shared/css/insecdb.css
|     Line number: 7
|     Comment: 
|         /* A stylesheet for Insecure.Org pages generated by XSL translation of
|            DocBook XML to HTML */
|     
|     Path: http://scanme.nmap.org/shared/css/insecdb.css
|     Line number: 1
|     Comment: 
|         /*
|            "Insecure purple" colors
|            dark: #2a0d45;
|            pale: #f5f1f9;
|         */
|     
|     Path: http://scanme.nmap.org/
|     Line number: 51
|     Comment: 
|         &amp;<!-- SECWIKI PORTAL INSERT -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 162
|     Comment: 
|         &amp;<!-- PageBottom728x90 -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 160
|     Comment: 
|         &amp;<!-- Adsense -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 9
|     Comment: 
|         &amp;<!--Google Analytics Code-->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 20
|     Comment: 
|         &amp;<!--END Google Analytics Code-->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 159
|     Comment: 
|         &amp;<!-- Bottom Banner -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 117
|     Comment: 
|         &amp;<!-- SidebarSkyScraper -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 44
|     Comment: 
|         &amp;<!-- AdSpeed.com End -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 89
|     Comment: 
|         &amp;<!-- SiteSearch Google -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 42
|     Comment: 
|         &amp;<!-- AdSpeed.com Serving Code 7.9.6 for [Zone] TopBanner [Any Dimension] -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 45
|     Comment: 
|         &amp;<!-- End Banner Code -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 115
|     Comment: 
|         &amp;<!-- Begin Bottom (Google) Sidebar Banner Code -->
|     
|     Path: http://scanme.nmap.org/
|     Line number: 22
|     Comment: 
|         &amp;<!--Google Custom Site Search boilerplate Javascript-->
|     
|     Path: http://scanme.nmap.org/shared/css/insecdb.css
|     Line number: 48
|     Comment: 
|_        /*  background-color: #FFFFFF; */
|_http-date: Tue, 04 Aug 2020 13:29:31 GMT; 0s from local time.
|_http-devframework: Couldn't determine the underlying framework or CMS. Try increasing 'httpspider.maxpagecount' value to spider more pages.
| http-enum: 
|   /images/: Potentially interesting directory w/ listing on 'apache/2.4.7 (ubuntu)'
|_  /shared/: Potentially interesting directory w/ listing on 'apache/2.4.7 (ubuntu)'
| http-errors: 
| Spidering limited to: maxpagecount=40; withinhost=scanme.nmap.org
|   Found the following error pages: 
|   
|   Error Code: 404
|       http://scanme.nmap.org/(document.location.protocol
|   
|   Error Code: 404
|_      http://scanme.nmap.org/g;m.parentNode.insertBefore(a,m)
|_http-feed: Couldn't find any feeds.
| http-headers: 
|   Date: Tue, 04 Aug 2020 13:29:31 GMT
|   Server: Apache/2.4.7 (Ubuntu)
|   Accept-Ranges: bytes
|   Vary: Accept-Encoding
|   Connection: close
|   Content-Type: text/html
|   
|_  (Request type: HEAD)
|_http-mobileversion-checker: No mobile version detected.
| http-referer-checker: 
| Spidering limited to: maxpagecount=30
|_  http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js
|_http-security-headers: 
| http-sitemap-generator: 
|   Directory structure:
|     /
|       Other: 1
|     /images/
|       png: 1
|     /shared/css/
|       css: 1
|     /shared/images/
|       gif: 1; png: 1
|     /shared/images/Acunetix/
|       gif: 1
|   Longest directory structure:
|     Depth: 3
|     Dir: /shared/images/Acunetix/
|   Total files found (by extension):
|_    Other: 1; css: 1; gif: 2; png: 2
|_http-title: Go ahead and ScanMe!
| http-useragent-tester: 
|   Status for browser useragent: 200
|   Allowed User Agents: 
|     Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)
|     libwww
|     lwp-trivial
|     libcurl-agent/1.0
|     PHP/
|     Python-urllib/2.5
|     GT::WWW
|     Snoopy
|     MFC_Tear_Sample
|     HTTP::Lite
|     PHPCrawl
|     URI::Fetch
|     Zend_Http_Client
|     http client
|     PECL::HTTP
|     Wget/1.13.4 (linux-gnu)
|_    WWW-Mechanize/1.34
| http-vhosts: 
|_127 names had status 200
|_http-xssed: No previously reported XSS vuln.
646/tcp   filtered ldp
9929/tcp  open     nping-echo
|_banner: \x01\x01\x00\x18\xDB\xC6\xEBD_)b\xB7\x00\x00\x00\x00+\xA4\x8...
31337/tcp open     Elite
Host script results:
| asn-query: 
| BGP: 45.33.32.0/24 and 45.33.32.0/19 | Country: US
|   Origin AS: 63949 - LINODE-AP Linode, LLC, US
|_    Peer AS: 1299 2914 3257
| dns-brute: 
|   DNS Brute-force hostnames: 
|     ipv6.nmap.org - 2600:3c01:0:0:f03c:91ff:fe70:d085
|     chat.nmap.org - 45.33.32.156
|     chat.nmap.org - 2600:3c01:0:0:f03c:91ff:fe18:bb2f
|     *A: 45.33.49.119
|_    *AAAA: 2600:3c01:0:0:f03c:91ff:fe98:ff4e
|_fcrdns: PASS (scanme.nmap.org)
| hostmap-ip2hosts: 
|   hosts: 
|     &amp;<html&amp;>&<head&amp;>&<title&amp;>Object moved&</title&amp;>&</head&amp;>&<body&amp;>\x0D
| &<h2>Object moved to &<a href="huanqiucaipiaotouzhupingtai.com/register?id=17436000">here&</a&amp;>.<!--<span class='sc_word_block'-->h2>\x0D
|_&</body&amp;>&</html&amp;>\x0D
|_hostmap-robtex: ERROR: Script execution failed (use -d to debug)
| ip-geolocation-geoplugin: 
|_45.33.32.156 (scanme.nmap.org)
| resolveall: 
|   Host 'scanme.nmap.org' also resolves to:
|_  Use the 'newtargets' script-arg to add the results as targets
| whois-domain: 
| 
| Domain name record found at whois.pir.org
| NOT FOUND\x0D
| >>> Last update of WHOIS database: 2020-08-04T13:28:33Z &<&<&<\x0D
| \x0D
| Access to Public Interest Registry WHOIS information is provided to assist persons in determining the contents of a domain name registration record in the Public Interest Registry registry database. The data in this record is provided by Public Interest Registry for informational purposes only, and Public Interest Registry does not guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Registry Operator, a Registrar, or Afilias except as reasonably necessary to register domain names or modify existing registrations. All rights reserved. Public Interest Registry reserves the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.
| 
|_The Registrar of Record identified in this output may have an RDDS service that can be queried for additional information on how to contact the Registrant, Admin, or Tech contact of the queried domain name.\x0D
| whois-ip: Record found at whois.arin.net
| netrange: 45.33.0.0 - 45.33.127.255
| netname: LINODE-US
| orgname: Linode
| orgid: LINOD
|_country: US stateprov: PA

Lanzar script obtener cabeceras

Con la opción --script-help podríamos ver una descripción de un script determinado. De esta forma podríamos obtener una descripción de lo que realmente hace, por ejemplo, para el script de obtener las cabeceras http podríamos obtener la siguiente información:</p>

$ nmap --script-help http-headers

http-headers
Categories: discovery safe
https://nmap.org/nsedoc/scripts/http-headers.html
Performs a HEAD request for the root folder ("/") of a web server and displays the HTTP headers returned.

El siguiente comando le permitirá ver las cabeceras HTTP configuradas en el servidor web en el host de destino.

$ nmap --script http-headers scanme.nmap.org

Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up (0.27s latency).
Not shown: 996 closed ports
PORT      STATE    SERVICE
22/tcp    open     ssh
80/tcp    open     http
| http-headers: 
|   Date: Wed, 15 Nov 2017 05:10:04 GMT
|   Server: Apache/2.4.7 (Ubuntu)
|   Accept-Ranges: bytes
|   Vary: Accept-Encoding
|   Connection: close
|   Content-Type: text/html
|   
|_  (Request type: HEAD)
179/tcp   filtered bgp
31337/tcp open     Elite      
Nmap done: 1 IP address (1 host up) scanned in 20.96 seconds

Obtener subdominios con script de nmap

Los subdominios normalmente se utilizan para alojar sitios web adicionales para un subconjunto específico de usuarios.

El script dns-brute que podemos encontrar dentro los scripts de Nmap permite obtener subdominios y las direcciones IP de servidor correspondientes.

$ nmap -p80,443 --script dns-brute scanme.nmap.org

Nuestro sitio web en particular tiene varios subdominios configurados tanto en IPv4 como en IPv6.

Esta sería la salida del comando anterior:

PORT    STATE  SERVICE
80/tcp  open   http
443/tcp closed https
Host script results
| dns-brute: 
|   DNS Brute-force hostnames: 
|     ipv6.nmap.org - 2600:3c01:0:0:f03c:91ff:fe70:d085
|     chat.nmap.org - 45.33.32.156
|     chat.nmap.org - 2600:3c01:0:0:f03c:91ff:fe18:bb2f
|     *AAAA: 2600:3c01:0:0:f03c:91ff:fe98:ff4e
|_    *A: 45.33.49.119

En este punto, un pentester o analista de seguridad podría utilizar esta información para analizar de forma recursiva los diferentes subdominios encontrados.

Lanzar scripts para un determinado servicio

Podríamos ejecutar los scripts correspondientes al servicio ssh para el caso de que el puerto 22 esté abierto. De esta forma estamos ejecutando todos los scripts con nombres que comiencen con ssh:

$ nmap --script "ssh-*" <ip_dominio>

Los scripts que podríamos utilizar para testear el servicio ssh serían los siguientes localizados dentro del directorio de scripts de nmap:

/usr/share/nmap/scripts/ssh-auth-methods.nse
/usr/share/nmap/scripts/ssh-brute.nse
/usr/share/nmap/scripts/ssh-hostkey.nse
/usr/share/nmap/scripts/ssh-publickey-acceptance.nse
/usr/share/nmap/scripts/ssh-run.nse
/usr/share/nmap/scripts/ssh2-enum-algos.nse
/usr/share/nmap/scripts/sshv1.nse

En el siguiente ejemplo ejecutamos el script ssh-hostkey en el puerto 22 de SSH que obtiene información de la clave pública del servidor.

$ nmap -sV --script ssh-hostkey scanme.nmap.org
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    VERSION
22/tcp    open     ssh        OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   1024 ac:00:a0:1a:82:ff:cc:55:99:dc:67:2b:34:97:6b:75 (DSA)
|   2048 20:3d:2d:44:62:2a:b0:5a:9d:b5:b3:05:14:c2:a6:b2 (RSA)
|   256 96:02:bb:5e:57:54:1c:4e:45:2f:56:4c:4a:24:b2:57 (ECDSA)
|_  256 33:fa:91:0f:e0:e1:7b:1f:6d:05:a2:b0:f1:54:41:56 (EdDSA)
80/tcp    open     http       Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
646/tcp   filtered ldp
9929/tcp  open     nping-echo Nping echo
31337/tcp open     tcpwrapped
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Al pasarle el parámetro -SV le estamos indicando que también muestre información relacionada con la versión del sistema operativo.

También podríamos obtener más información acerca de los algoritmos de cifrado soportados por el servidor usando el script ssh2-enum-algos sobre el puerto 22:

$ nmap -sV -p22 --script ssh2-enum-algos scanme.nmap.org
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.13 (Ubuntu Linux; protocol 2.0)
| ssh2-enum-algos: 
|   kex_algorithms: (8)
|       curve25519-sha256@libssh.org
|       ecdh-sha2-nistp256
|       ecdh-sha2-nistp384
|       ecdh-sha2-nistp521
|       diffie-hellman-group-exchange-sha256
|       diffie-hellman-group-exchange-sha1
|       diffie-hellman-group14-sha1
|       diffie-hellman-group1-sha1
|   server_host_key_algorithms: (4)
|       ssh-rsa
|       ssh-dss
|       ecdsa-sha2-nistp256
|       ssh-ed25519
|   encryption_algorithms: (16)
|       aes128-ctr
|       aes192-ctr
|       aes256-ctr
|       arcfour256
|       arcfour128
|       aes128-gcm@openssh.com
|       aes256-gcm@openssh.com
|       chacha20-poly1305@openssh.com
|       aes128-cbc
|       3des-cbc
|       blowfish-cbc
|       cast128-cbc
|       aes192-cbc
|       aes256-cbc
|       arcfour
|       rijndael-cbc@lysator.liu.se
|   mac_algorithms: (19)
|       hmac-md5-etm@openssh.com
|       hmac-sha1-etm@openssh.com
|       umac-64-etm@openssh.com
|       umac-128-etm@openssh.com
|       hmac-sha2-256-etm@openssh.com
|       hmac-sha2-512-etm@openssh.com
|       hmac-ripemd160-etm@openssh.com
|       hmac-sha1-96-etm@openssh.com
|       hmac-md5-96-etm@openssh.com
|       hmac-md5
|       hmac-sha1
|       umac-64@openssh.com
|       umac-128@openssh.com
|       hmac-sha2-256
|       hmac-sha2-512
|       hmac-ripemd160
|       hmac-ripemd160@openssh.com
|       hmac-sha1-96
|       hmac-md5-96
|   compression_algorithms: (2)
|       none
|_      zlib@openssh.com
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Analizar el servicio FTP con scripts de nmap

Nmap proporciona usa serie de scripts que podríamos utilizar para analizar posibles vulnerabilidades sobre un servidor FTP que tenga abierto el puerto 21.

Por ejemplo, el script ftp-anon, si lo ejecutamos sobre la máquina objetivo en el puerto 21 podemos saber si el servicio FTP permite la autenticación de forma anónima sin tener que introducir usuario y pasword.</p>

Podríamos ejecutar dicho script para comprobar si el servidor FTP que estamos analizando soporta autenticación anónima.

$ nmap -sV -p21 --script ftp-anon ftp.be.debian.org
Nmap scan report for ftp.be.debian.org (195.234.45.114)
Host is up (0.038s latency).
Other addresses for ftp.be.debian.org (not scanned): 2a05:7300:0:100::2
rDNS record for 195.234.45.114: mirror.as35701.net
PORT   STATE SERVICE VERSION
21/tcp open  ftp     ProFTPD
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| lrwxrwxrwx   1 ftp      ftp            16 May 14  2011 backports.org -> /backports.org/debian-backports
| drwxr-xr-x   9 ftp      ftp          4096 Aug  4 14:41 debian
| drwxr-sr-x   5 ftp      ftp          4096 Mar 13  2016 debian-backports
| drwxr-xr-x   5 ftp      ftp          4096 Aug  2 10:16 debian-cd
| drwxr-xr-x   7 ftp      ftp          4096 Aug  4 08:32 debian-security
| drwxr-sr-x   5 ftp      ftp          4096 Jan  5  2012 debian-volatile
| drwxr-xr-x   5 ftp      ftp          4096 Oct 13  2006 ftp.irc.org
| -rw-r--r--   1 ftp      ftp           419 Nov 17  2017 HEADER.html
| drwxr-xr-x  10 ftp      ftp          4096 Aug  4 14:05 pub
| drwxr-xr-x  20 ftp      ftp          4096 Aug  4 14:14 video.fosdem.org
|_-rw-r--r--   1 ftp      ftp           377 Nov 17  2017 welcome.msg

Actividad práctica: Completa el siguiente script que realizar un escaneo con python-nmap con el objetivo de lanzar diferentes scripts de nmap y detectar servicios vulnerables en una máquina

Completa el siguiente script que realiza un escaneo con python-nmap de forma asíncrona de forma que se solicita por parámetros de entrada el dominio y el puerto a analizar. Lo que tiene que hacer el script es realizar un escaneo en el puerto de FTP (21) de forma asíncrona y ejecutar los scripts de nmap disponibles para el servicio de FTP. Sustituir las xxx por variables o clases definidas en el módulo python-nmap.

#!/usr/bin/env python3
 
import nmap
import argparse
 
def callbackFTP(host, result):
    try:
        script = result['scan'][xxx]['tcp'][21]['script']
        print("Command line"+ xxx['nmap']['command_line'])
        for key, value in script.xxx():
            print('Script {0} --> {1}'.format(xxx, xxx))
    except KeyError:
        pass
 
 
class NmapScannerAsyncFTP:
    def __init__(self):
        self.portScanner = nmap.xxx()
        self.portScannerAsync = nmap.xxx()
 
    def scanning(self):
        while self.xxx.xxx():
            print("Scanning >>>")
            self.xxx.xxx(10)    
 
    def nmapScanAsync(self, hostname, port):
        try:
            print("Checking port "+ port +" ..........")
            self.portScanner.xxx(xxx, xxx)
            self.state = self.xxx[hostname]['tcp'][int(port)]['state']
            print(" [+] "+ hostname + " tcp/" + port + " " + self.state)
            #checking FTP service
            if (port=='21') and self.xxx[hostname]['tcp'][int(port)]['state']=='open':
                print('Checking ftp port with nmap scripts......')
                print('Checking ftp-anon.nse .....')
                self.xxx.xxx(hostname,arguments="-A -sV -p21 --script ftp-anon.nse",callback=xxx)
                self.scanning()
                print('Checking ftp-bounce.nse  .....')
                self.xxx.xxx(hostname,arguments="-A -sV -p21 --script ftp-bounce.nse",callback=xxx)
                self.scanning()
                print('Checking ftp-libopie.nse  .....')
                self.xxx.xxx(hostname,arguments="-A -sV -p21 --script ftp-libopie.nse",callback=xxx)
                self.scanning()
                print('Checking ftp-proftpd-backdoor.nse  .....')
                self.xxx.xxx(hostname,arguments="-A -sV -p21 --script ftp-proftpd-backdoor.nse",callback=xxx)
                self.scanning()
                print('Checking ftp-vsftpd-backdoor.nse   .....')
                self.xxx.xxx(hostname,arguments="-A -sV -p21 --script ftp-vsftpd-backdoor.nse",callback=xxx)
                self.scanning()
 
        except Exception as exception:
            print("Error to connect with " + hostname + " for port scanning",str(exception))
 
 
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Nmap scanner async')
    parser.add_argument("--host", dest="host", help="target IP / domain", required=True)
    parser.add_argument("--ports", dest="ports", help="Please, specify the target port(s) separated by comma[80,8080 by default]", default="80,8080")
    parsed_args = parser.parse_args()
    port_list = parsed_args.ports.split(',')
    ip_address = parsed_args.host
    for port in port_list:
        NmapScannerAsyncFTP().xxx(xxx, xxx)
usage: NmapScannerAsyncFTP.py [-h] --host HOST [--ports PORTS]<br>
	NmapScannerAsyncFTP.py: error: the following arguments are required: --host

Ejemplo de ejecución:

$ python3 NmapScannerAsyncFTP.py --host 195.234.45.114 --ports 21

Checking port 21 ..........
[+] 195.234.45.114 tcp/21 open
Checking ftp port with nmap scripts......
Checking ftp-anon.nse .....
Scanning >>>
Scanning >>>
Command linenmap -oX - -A -sV -p21 --script ftp-anon.nse 195.234.45.114
Script ftp-anon --> Anonymous FTP login allowed (FTP code 230)
lrwxrwxrwx   1 ftp      ftp            16 May 14  2011 backports.org -> /backports.org/debian-backports
drwxr-xr-x   9 ftp      ftp          4096 Aug  4 14:57 debian
drwxr-sr-x   5 ftp      ftp          4096 Mar 13  2016 debian-backports
drwxr-xr-x   5 ftp      ftp          4096 Aug  2 10:16 debian-cd
drwxr-xr-x   7 ftp      ftp          4096 Aug  4 16:32 debian-security
drwxr-sr-x   5 ftp      ftp          4096 Jan  5  2012 debian-volatile
drwxr-xr-x   5 ftp      ftp          4096 Oct 13  2006 ftp.irc.org
-rw-r--r--   1 ftp      ftp           419 Nov 17  2017 HEADER.html
drwxr-xr-x  10 ftp      ftp          4096 Aug  4 18:05 pub
drwxr-xr-x  20 ftp      ftp          4096 Aug  4 18:14 video.fosdem.org
-rw-r--r--   1 ftp      ftp           377 Nov 17  2017 welcome.msg
Checking ftp-bounce.nse  .....
Scanning >>>
Scanning >>>
Checking ftp-libopie.nse  .....
Scanning >>>

Solución

#!/usr/bin/env python3
 
import nmap
import argparse
 
def callbackFTP(host, result):
    try:
        script = result['scan'][host]['tcp'][21]['script']
        print("Command line"+ result['nmap']['command_line'])
        for key, value in script.items():
            print('Script {0} --> {1}'.format(key, value))
    except KeyError:
        pass
 
 
class NmapScannerAsyncFTP:
    def __init__(self):
        self.portScanner = nmap.PortScanner()
        self.portScannerAsync = nmap.PortScannerAsync()
 
    def scanning(self):
        while self.portScannerAsync.still_scanning():
            print("Scanning >>>")
            self.portScannerAsync.wait(10)    
 
    def nmapScanAsync(self, hostname, port):
        try:
            print("Checking port "+ port +" ..........")
            self.portScanner.scan(hostname, port)
            self.state = self.portScanner[hostname]['tcp'][int(port)]['state']
            print(" [+] "+ hostname + " tcp/" + port + " " + self.state)
            #checking FTP service
            if (port=='21') and self.portScanner[hostname]['tcp'][int(port)]['state']=='open':
                print('Checking ftp port with nmap scripts......')
                print('Checking ftp-anon.nse .....')
                self.portScannerAsync.scan(hostname,arguments="-A -sV -p21 --script ftp-anon.nse",callback=callbackFTP)
                self.scanning()
                print('Checking ftp-bounce.nse  .....')
                self.portScannerAsync.scan(hostname,arguments="-A -sV -p21 --script ftp-bounce.nse",callback=callbackFTP)
                self.scanning()
                print('Checking ftp-libopie.nse  .....')
                self.portScannerAsync.scan(hostname,arguments="-A -sV -p21 --script ftp-libopie.nse",callback=callbackFTP)
                self.scanning()
                print('Checking ftp-proftpd-backdoor.nse  .....')
                self.portScannerAsync.scan(hostname,arguments="-A -sV -p21 --script ftp-proftpd-backdoor.nse",callback=callbackFTP)
                self.scanning()
                print('Checking ftp-vsftpd-backdoor.nse   .....')
                self.portScannerAsync.scan(hostname,arguments="-A -sV -p21 --script ftp-vsftpd-backdoor.nse",callback=callbackFTP)
                self.scanning()
 
        except Exception as exception:
            print("Error to connect with " + hostname + " for port scanning",str(exception))
 
 
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Nmap scanner async')
    parser.add_argument("--host", dest="host", help="target IP / domain", required=True)
    parser.add_argument("--ports", dest="ports", help="Please, specify the target port(s) separated by comma[80,8080 by default]", default="80,8080")
    parsed_args = parser.parse_args()
    port_list = parsed_args.ports.split(',')
    ip_address = parsed_args.host
    for port in port_list:
        NmapScannerAsyncFTP().nmapScanAsync(ip_address, port)
informatica/programacion/cursos/python_avanzado_proyectos_seguridad/ejecutar_scripts_nmap_detectar_servicios_vulnerabilidades.txt · Última modificación: por tempwin