Descubriendo la red con Python y Nmap – Parte 1

Nuestro compañero Miguel, nos enseñó cómo descubrir el terreno de juego con Nmap (Parte 1, Parte 2) ahora que ya sabemos, ¿Por qué no automatizamos, gracias a nuestro amigo Python, los proceso de Nmap con la librería de Python-nmap y descubrimos la red de manera automatizada?

python nmap

Para ello lo primero que vamos a hacer es instalar las librerías necesarias, en mi caso lo realizo bajo Ubuntu, pero al usar pip todo el mundo lo tiene que tener disponible bajo su plataforma, recordad que necesitamos también tener instalado Nmap, alguno dirá que por qué no instalamos directamente desde los repositorios la librería, por la mera razón que en pip disponemos de la ultima versión y en los repositorios de Ubuntu no.

sudo apt-get install python-pip nmap

 

 

Una vez instalado pip y Nmap en nuestro sistema pasamos a instalar la librería que nos comunicará Python con Nmap.

sudo pip install python-nmap

 

 

Ahora que lo tenemos todo instalado ya podemos empezar a jugar con ella.

Lo primero que tenemos que hacer es importar la librería de Nmap y crearnos nuestro objeto para empezar a interactuar con PortScanner().

Lanzamos nuestro primer escaneo con scan(‘ip/rango’,’puertos’) el segundo parámetro es opcional, si no lo definimos realiza un escaneo estándar de Nmap.

$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import nmap
nm = nmap.PortScanner()
results = nm.scan('127.0.0.1', '22,25,80,443')

 

 

Ahora ya tenemos nuestro resultado guardado en una variable que es una diccionario estándar de Python.

{'nmap': {'scanstats': {'uphosts': u'1', 'timestr': u'Thu Mar 5 13:50:38 2015', 'downhosts': u'0', 'totalhosts': u'1', 'elapsed': u'6.16'}, 'scaninfo': {u'tcp': {'services': u'22,25,80,443', 'method': u'connect'}}, 'command_line': u'nmap -oX - -p 22,25,80,443 -sV 127.0.0.1'}, 'scan': {u'127.0.0.1': {'status': {'state': u'up', 'reason': u'syn-ack'}, 'hostname': u'localhost', 'addresses': {u'ipv4': u'127.0.0.1'}, u'tcp': {80: {'product': u'Apache httpd', 'state': u'open', 'version': u'2.4.7', 'name': u'http', 'conf': u'10', 'extrainfo': u'(Ubuntu)', 'reason': u'syn-ack', 'cpe': u'cpe:/a:apache:http_server:2.4.7'}, 25: {'product': '', 'state': u'closed', 'version': '', 'name': u'smtp', 'conf': u'3', 'extrainfo': '', 'reason': u'conn-refused', 'cpe': ''}, 443: {'product': '', 'state': u'closed', 'version': '', 'name': u'https', 'conf': u'3', 'extrainfo': '', 'reason': u'conn-refused', 'cpe': ''}, 22: {'product': '', 'state': u'closed', 'version': '', 'name': u'ssh', 'conf': u'3', 'extrainfo': '', 'reason': u'conn-refused', 'cpe': ''}}}}}

El cual podemos podemos recorrer de manera normal accediendo al dato que queramos.

nm['127.0.0.1']['tcp'][80]
{'product': u'Apache httpd', 'state': u'open', 'version': u'2.4.7', 'name': u'http', 'conf': u'10', 'extrainfo': u'(Ubuntu)', 'reason': u'syn-ack', 'cpe': u'cpe:/a:apache:http_server:2.4.7'}

Si queremos visualizar de una manera fácil y cómoda el diccionario disponemos de la función csv(), el cual nos devolverá la información en formato csv que lo separa por punto y coma.

print(nm.csv())
host;protocol;port;name;state;product;extrainfo;reason;version;conf;cpe
127.0.0.1;tcp;22;ssh;closed;;;conn-refused;;3;
127.0.0.1;tcp;25;smtp;closed;;;conn-refused;;3;
127.0.0.1;tcp;80;http;open;Apache httpd;(Ubuntu);syn-ack;2.4.7;10;cpe:/a:apache:http_server:2.4.7
127.0.0.1;tcp;443;https;closed;;;conn-refused;;3;

También podemos ver si un host está levantado o no con la función state().

nm['127.0.0.1'].state()
u'up'

Con esto ya podemos empezar a jugar 😀 por lo que ahora os dejo investigar a vosotros un poco hasta la siguiente entrega, donde veremos cómo pasarles argumentos, escaneo asíncrono y iremos poco a poco pudiendo construir nuestra herramienta de escaneado :).

Espero que os haya gustado y para cualquier duda sugerencia o jamón que me queríais enviar aquí estoy.

@goldrak