{"id":251,"date":"2021-01-03T19:52:53","date_gmt":"2021-01-03T18:52:53","guid":{"rendered":"https:\/\/www.pythonparatodo.com\/?p=251"},"modified":"2021-01-03T19:52:55","modified_gmt":"2021-01-03T18:52:55","slug":"nmap-con-python-3","status":"publish","type":"post","link":"https:\/\/www.pythonparatodo.com\/?p=251","title":{"rendered":"Nmap con Python 3"},"content":{"rendered":"\n<p>Nmap es una utilidad gratuita para descubrimiento de redes y auditar la seguridad de las mismas. Se puede utilizar para monitorizar los dispositivos de red, comprobar su estado y el estado de sus servicios en funcionamiento, inventariarlos, etc.<\/p>\n\n\n\n<p>Esta utilidad se puede descargar desde su web en&nbsp;<a href=\"https:\/\/nmap.org\/\">https:\/\/nmap.org<\/a>&nbsp;y se puede usar desde la terminal o s\u00edmbolo del sistema usando los par\u00e1metros y valores adecuados, y a trav\u00e9s de una interfaz GUI gracias a Zenmap, utilidad que ayuda en la construcci\u00f3n del comando, par\u00e1metros y valores y que muestra el resultado en un entorno gr\u00e1fico.<\/p>\n\n\n\n<p>Comentaros que lo que voy a explicar es para que pod\u00e1is usarlo en vuestras redes o con permiso escrito del propietario de la misma ya que en algunos pa\u00edses, el uso de estas herramientas en una red que no es vuestra, podr\u00eda considerarse un delito. Daros por tanto por advertidos.<\/p>\n\n\n\n<p>Si no dispon\u00e9is de una red de dispositivos, siempre es posible utilizar alg\u00fan software como VirtualBox o VMware Player para montar un laboratorio donde configurar una switch virtual e instalar m\u00e1quinas virtuales conectadas a este switch.<\/p>\n\n\n\n<p>En cualquier caso, lo que a nosotros nos interesa es poder usarlo con Python, por lo que tras su instalaci\u00f3n en nuestro sistema operativo usando la informaci\u00f3n disponible en su web, haremos uso de un m\u00f3dulo que nos permitir\u00e1 hacerlo y que se llama\u00a0<strong>Python-nmap<\/strong>. Para comenzar a usarlo debemos instalarlo y esto lo conseguiremos escribiendo el siguiente comando en la terminal o s\u00edmbolo del sistema de nuestro sistema operativo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\"># pip3 install python-nmap<\/code><\/pre>\n\n\n\n<p>Para su funcionamiento b\u00e1sico primero hemos de importar el m\u00f3dulo, cosa que hacemos escribiendo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import nmap<\/code><\/pre>\n\n\n\n<p>Vamos a mostrar que versi\u00f3n del m\u00f3dulo estamos usando haciendo uso del m\u00e9todo __version__.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> nmap.__version__\n'0.6.1'<\/code><\/pre>\n\n\n\n<p>Si queremos ver los m\u00e9todos que existen en el m\u00f3dulo\u00a0<strong>nmap<\/strong>\u00a0usamos\u00a0<strong>dir()<\/strong>\u00a0de la siguiente forma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> dir(nmap)\n['ET', 'PortScanner', 'PortScannerAsync', 'PortScannerError', 'PortScannerHostDict', 'PortScannerYield', 'Process', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__last_modification__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'convert_nmap_output_to_encoding', 'csv', 'io', 'nmap', 'os', 're', 'shlex', 'subprocess', 'sys']<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Para mostrar el funcionamiento del m\u00f3dulo nos interesa el m\u00e9todo&nbsp;<strong>PortScanner<\/strong>&nbsp;ya que es el que usaremos para realizar un escaneo de puertos en los dispositivos de nuestra red.<\/p>\n\n\n\n<p>Vamos a ver los m\u00e9todos disponibles usando&nbsp;<strong>dir()<\/strong>&nbsp;de nuevo.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> dir(nmap.PortScanner)\n['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'all_hosts', 'analyse_nmap_xml_scan', 'command_line', 'csv', 'get_nmap_last_output', 'has_host', 'listscan', 'nmap_version', 'scan', 'scaninfo', 'scanstats']<\/code><\/pre>\n\n\n\n<p>Entre otros los m\u00e9todos que nos interesan ahora son\u00a0<strong>nmap_version<\/strong>\u00a0que nos mostrar\u00e1 la versi\u00f3n de\u00a0<strong>nmap<\/strong>\u00a0que estamos usando,\u00a0<strong>scan<\/strong>, que realizar\u00e1 el escaneo de puertos,\u00a0<strong>command_line<\/strong>\u00a0que nos mostrar\u00e1 el comando y par\u00e1metros usados en nuestro escaneo y\u00a0<strong>scaninfo<\/strong>\u00a0para ver la informaci\u00f3n producida por el escaneo.<\/p>\n\n\n\n<p>Escanearemos los puertos 80 (http), 443 (https) buscando servidores web disponibles, el puerto 21 (ftp), 22 (ssh) y 3389 (rdp) para ver que equipos tienen configurado y accesible el escritorio remoto.<\/p>\n\n\n\n<p>Vamos a ver que versi\u00f3n de nmap tenemos instalada.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> nmap.PortScanner().nmap_version()\n(7, 91)<\/code><\/pre>\n\n\n\n<p>Y comenzamos creando un objeto del tipo nmap.PortScanner con el siguiente comando:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">ep = nmap.PortScanner()<\/code><\/pre>\n\n\n\n<p>Y vamos a lanzar el escaneo usando el m\u00e9todo scan de nmap.PortScanner()<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">ep.scan(\u2018192.168.0.1\u2019,\u201921,22,80,443,3389\u2019,\u2019-v\u2019)<\/code><\/pre>\n\n\n\n<p>Hemos usado la opci\u00f3n&nbsp;<strong>verbose<\/strong>&nbsp;<strong>(-v<\/strong>) para mostrar el resultado en la consola, sin esta opci\u00f3n no se habr\u00eda mostrado ning\u00fan resultado. As\u00ed podemos ver que lo que el resultado del escaneo es un diccionario con claves como&nbsp;<strong>command_line<\/strong>,&nbsp;<strong>scaninfo<\/strong>,&nbsp;<strong>service<\/strong>s, etc.<\/p>\n\n\n\n<p>Vamos a observar el comando utilizado para realizar el escaneado con&nbsp;<strong>command_line()<\/strong>&nbsp;el cual nos muestra lo que se ha pasado a nmap para obtener ese resultado.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> ep.command_line()\n'nmap -oX - -p 21,22,80,443,3389 -v 192.168.0.1'<\/code><\/pre>\n\n\n\n<p>Para ver una lista de todos los hosts envueltos en el escaneo usamos el m\u00e9todo\u00a0<strong>all_hosts()<\/strong>, en este caso concreto solo hay uno.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> ep.all_hosts()\n['192.168.0.1']<\/code><\/pre>\n\n\n\n<p>Pero esta lista ser\u00eda diferente si nuestro escaneo hubiera sido otro, por ejemplo:\u00a0<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">ep.scan(\u2018192.168.0.1-10\u2019,\u201921,22,80,443,3389\u2019)<\/code><\/pre>\n\n\n\n<p>&nbsp;En ese caso habr\u00edamos obtenido una lista con los siguientes resultados&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">['192.168.0.1', '192.168.0.10', '192.168.0.2', '192.168.0.3', '192.168.0.4', '192.168.0.5', '192.168.0.6', '192.168.0.7', '192.168.0.8', '192.168.0.9'].<\/code><\/pre>\n\n\n\n<p>Dejando de lado este \u00faltimo dato y volviendo al anterior, podr\u00edamos ver el diccionario obtenido para ese host escribiendo lo siguiente:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> ep[\u2018192.168.0.1\u2019]<\/code><\/pre>\n\n\n\n<p>El resultado ser\u00eda algo parecido a esto que contiene informaci\u00f3n de los puertos, nombres, estados, razones, etc.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">{'hostnames': [{'name': '', 'type': ''}], 'addresses': {'ipv4': '192.168.0.1'}, 'vendor': {}, 'status': {'state': 'up', 'reason': 'syn-ack'}, 'tcp': {21: {'state': 'closed', 'reason': 'conn-refused', 'name': 'ftp', 'product': '', 'version': '', 'extrainfo': '', 'conf': '3', 'cpe': ''}, 22: {'state': 'open', 'reason': 'syn-ack', 'name': 'ssh', 'product': '', 'version': '', 'extrainfo': '', 'conf': '3', 'cpe': ''}, 80: {'state': 'open', 'reason': 'syn-ack', 'name': 'http', 'product': '', 'version': '', 'extrainfo': '', 'conf': '3', 'cpe': ''}, 443: {'state': 'open', 'reason': 'syn-ack', 'name': 'https', 'product': '', 'version': '', 'extrainfo': '', 'conf': '3', 'cpe': ''}, 3389: {'state': 'closed', 'reason': 'conn-refused', 'name': 'ms-wbt-server', 'product': '', 'version': '', 'extrainfo': '', 'conf': '3', 'cpe': ''}}}<\/code><\/pre>\n\n\n\n<p>Aqu\u00ed est\u00e1 toda la informaci\u00f3n para ese host. Por ejemplo podemos saber si el host est\u00e1 vivo revisando el estado del host con&nbsp;<strong>state()<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> ep['192.168.0.1'].state()\n'up'<\/code><\/pre>\n\n\n\n<p>Los protocolos usados:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> ep['192.168.0.1'].all_protocols()\n['tcp']<\/code><\/pre>\n\n\n\n<p>Podemos revisar el estado del puerto tcp 80.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> ep[\u2018192.168.0.1\u2019]['tcp'][80]\n{'state': 'open', 'reason': 'syn-ack', 'name': 'http', 'product': '', 'version': '', 'extrainfo': '', 'conf': '3', 'cpe': ''}<\/code><\/pre>\n\n\n\n<p>Le\u00eddo al rev\u00e9s se entiende mejor, puerto 80, protocolo tcp del host 192.168.0.1.<\/p>\n\n\n\n<p>Tambi\u00e9n vamos a mirar el estado del puerto 80.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> ep[\u2018192.168.0.1\u2019]['tcp'][80]['state']\n'open'<\/code><\/pre>\n\n\n\n<p>La raz\u00f3n de su estado, que indica el m\u00e9todo usado para averiguar si est\u00e1 abierto.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> ep[\u2018192.168.0.1\u2019]['tcp'][80]['reason']\n'syn-ack'<\/code><\/pre>\n\n\n\n<p>Y el nombre del servicio.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> ep[\u2018192.168.0.1\u2019]['tcp'][80]['name']\n'http'<\/code><\/pre>\n\n\n\n<p>Si quisi\u00e9ramos obtener todos estos datos en un formato mas legible podr\u00edamos usar el m\u00e9todo csv de la siguiente forma.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">>>> ep.csv()\n'host;hostname;hostname_type;protocol;port;name;state;product;extrainfo;reason;version;conf;cpe\\r\\n192.168.0.1;;;tcp;21;ftp;closed;;;conn-refused;;3;\\r\\n192.168.0.1;;;tcp;22;ssh;open;;;syn-ack;;3;\\r\\n192.168.0.1;;;tcp;80;http;open;;;syn-ack;;3;\\r\\n192.168.0.1;;;tcp;443;https;open;;;syn-ack;;3;\\r\\n192.168.0.1;;;tcp;3389;ms-wbt-server;closed;;;conn-refused;;3;\\r\\n'<\/code><\/pre>\n\n\n\n<p>El resultado podr\u00edamos importarlo en cualquier hoja de c\u00e1lculo.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><a><strong>host<\/strong><\/a><strong><\/strong><\/td><td><strong>hostname<\/strong><\/td><td><strong>hostname_type<\/strong><\/td><td><strong>protocol<\/strong><\/td><td><strong>port<\/strong><\/td><td><strong>name<\/strong><\/td><td><strong>state<\/strong><\/td><td><strong>product<\/strong><\/td><td><strong>extrainfo<\/strong><\/td><td><strong>reason<\/strong><\/td><td><strong>version<\/strong><\/td><td><strong>conf<\/strong><\/td><td><strong>cpe<\/strong><\/td><\/tr><tr><td>192.168.0.1<\/td><td><\/td><td><\/td><td>tcp<\/td><td>21<\/td><td>ftp<\/td><td>closed<\/td><td><\/td><td><\/td><td>conn-refused<\/td><td><\/td><td>3<\/td><td><\/td><\/tr><tr><td>192.168.0.1<\/td><td><\/td><td><\/td><td>tcp<\/td><td>22<\/td><td>ssh<\/td><td>open<\/td><td><\/td><td><\/td><td>syn-ack<\/td><td><\/td><td>3<\/td><td><\/td><\/tr><tr><td>192.168.0.1<\/td><td><\/td><td><\/td><td>tcp<\/td><td>80<\/td><td>http<\/td><td>open<\/td><td><\/td><td><\/td><td>syn-ack<\/td><td><\/td><td>3<\/td><td><\/td><\/tr><tr><td>192.168.0.1<\/td><td><\/td><td><\/td><td>tcp<\/td><td>443<\/td><td>https<\/td><td>open<\/td><td><\/td><td><\/td><td>syn-ack<\/td><td><\/td><td>3<\/td><td><\/td><\/tr><tr><td>192.168.0.1<\/td><td><\/td><td><\/td><td>tcp<\/td><td>3389<\/td><td>ms-wbt-server<\/td><td>closed<\/td><td><\/td><td><\/td><td>conn-refused<\/td><td><\/td><td>3<\/td><td><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Si te ha sido de utilidad, por favor, deja un comentario.<\/p>\n\n\n\n<p>Gracias \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nmap es una utilidad gratuita para descubrimiento de redes y auditar la seguridad de las mismas. Se puede utilizar para &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21,4],"tags":[],"class_list":["post-251","post","type-post","status-publish","format-standard","hentry","category-networking","category-python"],"_links":{"self":[{"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/posts\/251","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=251"}],"version-history":[{"count":3,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/posts\/251\/revisions"}],"predecessor-version":[{"id":254,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/posts\/251\/revisions\/254"}],"wp:attachment":[{"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=251"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=251"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=251"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}