{"id":306,"date":"2018-11-30T13:27:24","date_gmt":"2018-11-30T12:27:24","guid":{"rendered":"https:\/\/tiraquelibras.com\/blog\/?p=306"},"modified":"2019-12-26T17:00:46","modified_gmt":"2019-12-26T16:00:46","slug":"shodan-python-api","status":"publish","type":"post","link":"https:\/\/blog.tiraquelibras.com\/?p=306","title":{"rendered":"Shodan &#8211; Python API"},"content":{"rendered":"<p>Durante el pasado <strong><em>Black Friday<\/em><\/strong>\u00a0el portal de consulta de cualquier dispositivo conectado a Internet\u00a0<a href=\"https:\/\/www.shodan.io\/\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"external external_icon\">Shodan<\/a>\u00a0puso de oferta el upgrade de las cuentas <em>free<\/em>\u00a0por <del>\u00a049\u00a0<\/del>\u00a05 \u20ac, oferta que aprovech\u00e9 para actualizar mi cuenta actual.<\/p>\n<p>Con esta cuenta se obtienen una serie de beneficios a la hora de realizar consultas, evitando algunas limitaciones que tiene la versi\u00f3n gratuita. Estas ventajas, a su vez, se limitan a unos umbrales anuales, a diferencia de las cuentas de pago mensual cuyos contadores se reinician todos los meses.<\/p>\n<p>Con esta actualizaci\u00f3n podemos probar ciertas funcionalidades, tanto en la web como desde cualquiera de sus APIs. Desde la web oficial podemos acceder a la informaci\u00f3n de las APIs (pincha\u00a0<a href=\"https:\/\/developer.shodan.io\/api\/clients\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"external external_icon\">aqu\u00ed<\/a>). Me he centrado en la API de <strong>Python,<\/strong>\u00a0publicado en el enlace <a href=\"https:\/\/shodan.readthedocs.io\/en\/latest\/\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">https:\/\/shodan.readthedocs.io\/en\/latest\/<\/a>, y estos son los comandos que me resultaron de m\u00e1s inter\u00e9s.<\/p>\n<hr \/>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_76 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Tabla de contenidos<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a00aef4b0cd0\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a00aef4b0cd0\"  aria-label=\"Alternar\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\/#Instalacion\"  rel=\"nofollow\" target=\"_blank\">Instalaci\u00f3n<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\/#Conectar_con_la_cuenta\"  rel=\"nofollow\" target=\"_blank\">Conectar con la cuenta<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\/#Informacion_de_la_cuenta\"  rel=\"nofollow\" target=\"_blank\">Informaci\u00f3n de la cuenta<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\/#Busqueda_basica\"  rel=\"nofollow\" target=\"_blank\">B\u00fasqueda b\u00e1sica<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\/#Busqueda_de_host\"  rel=\"nofollow\" target=\"_blank\">B\u00fasqueda de host<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\/#Mostrar_Banners\"  rel=\"nofollow\" target=\"_blank\">Mostrar Banners<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\/#Script_busqueda_basica\"  rel=\"nofollow\" target=\"_blank\">Script b\u00fasqueda b\u00e1sica<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\/#Busqueda_con_FACETS\"  rel=\"nofollow\" target=\"_blank\">B\u00fasqueda con FACETS<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\/#Listado_de_metodos\"  rel=\"nofollow\" target=\"_blank\">Listado de m\u00e9todos<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\/#Fuentes\"  rel=\"nofollow\" target=\"_blank\">Fuentes<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Instalacion\"><\/span>Instalaci\u00f3n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Para instalar la librer\u00eda de <strong>Shodan<\/strong>\u00a0usamos el comando <strong><em>pip<\/em><\/strong>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\"># pip search shodan\r\nshodan (1.10.4)   - Python library and command-line utility for Shodan (https:\/\/developer.shodan.io)\r\n  INSTALLED: 1.10.4 (latest)\r\nRoboShodan (1.2)  - Robot Framework Library for Shodan\r\n<\/pre>\n<p>En mi caso ya lo ten\u00eda instalado, de lo contrario ejecutar\u00edamos el siguiente comando.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">pip install shodan<\/pre>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Conectar_con_la_cuenta\"><\/span>Conectar con la cuenta<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Para conectar con la cuenta debemos de consultar la <em><strong>API_KEY<\/strong><\/em> publicada en la secci\u00f3n <em><strong>MyAccount<\/strong><\/em> de Shodan.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-310\" src=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2018\/11\/API_KEY-300x184.jpg\" alt=\"\" width=\"300\" height=\"184\" \/><\/p>\n<p>Ahora importamos la librer\u00eda y cargamos la aplicaci\u00f3n con la <em><strong>API_KEY<\/strong><\/em>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import shodan\r\nSHODAN_API_KEY = \"XXX\"\r\napi = shodan.Shodan(SHODAN_API_KEY)<\/pre>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Informacion_de_la_cuenta\"><\/span>Informaci\u00f3n de la cuenta<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Una vez conectado con la cuenta podemos conocer su informaci\u00f3n actual con el m\u00e9tido\u00a0<em><strong>info()<\/strong><\/em>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">api.info()<\/pre>\n<p>Resultado.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">{u'https': False,\r\n u'plan': u'dev',\r\n u'query_credits': 100,\r\n u'scan_credits': 98,\r\n u'telnet': False,\r\n u'unlocked': True,\r\n u'unlocked_left': 100}\r\n<\/pre>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Busqueda_basica\"><\/span>B\u00fasqueda b\u00e1sica<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Para realizar una b\u00fasqueda debemos de usar el m\u00e9todo <em><strong>search<\/strong> <\/em>e iterar con todos los resultados usando un bucle <em><strong>for<\/strong><\/em>. Por ejemplo, vamos a realizar una b\u00fasqueda por el servidor web <strong>Apache<\/strong>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">try:\r\n  results = api.search('apache')\r\n  print(\"Resultados encontrados: {}' . format(results['total']))\r\n  for result in results['matches']:\r\n    print('IP: {}' . format(result['ip_str']))\r\n    print(result['data'])\r\n    print('')\r\n\r\nexcept shodan.APIError, e:\r\n  print('Error: {}' . format(e))<\/pre>\n<p>Resultado.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">Resultados encontrados: 25504866\r\n IP: 213.226.249.184\r\nHTTP\/1.1 302 Moved Temporarily\r\nDate: Fri, 30 Nov 2018 11:36:15 GMT\r\nServer: Apache\r\nCache-Control: no-cache, no-store, must-revalidate\r\nPragma: no-cache\r\nExpires: 0\r\nLocation: http:\/\/213.226.249.184:5000\/\r\nContent-Length: 0\r\nContent-Type: text\/plain\r\n\r\n\r\n\r\nIP: 1.51.246.132\r\nHTTP\/1.1 200 OK\r\nDate: Fri, 30 Nov 2018 11:27:18 GMT\r\nServer: Apache\r\nX-Frame-Options: SAMEORIGIN\r\nLast-Modified: Thu, 19 Jul 2018 08:41:31 GMT\r\nETag: \"2a0-5715625581d4b\"\r\nAccept-Ranges: bytes\r\nContent-Length: 672\r\nContent-Type: text\/html\r\n\r\n...<\/pre>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Busqueda_de_host\"><\/span>B\u00fasqueda de host<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Para buscar informaci\u00f3n de un host concreto usamos el m\u00e9todo\u00a0<em><strong>host<\/strong><\/em> y la funci\u00f3n\u00a0<em><strong>get<\/strong><\/em><em>.<\/em><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">results = api.host('8.8.8.8')\r\n\r\n# Mostramos la informacion.\r\nprint(\"\"\"\r\n  IP: {}\r\n  Oganization: {}\r\n  Operative Sistem: {}\r\n\"\"\" . format(results['ip_str'], results.get('org', 'n\/a'), results.get('os', 'n\/a')))<\/pre>\n<p>Resultado.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">IP: 8.8.8.8\r\nOrganization: Google\r\nOperative Sistem: None\r\n<\/pre>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Mostrar_Banners\"><\/span>Mostrar Banners<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Usando el comando anterior podemos obtener los <strong>Banners<\/strong> mostrados por los servicios cuando se realiza una conexi\u00f3n, y registrados en <strong>Shodan<\/strong>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">for item in results['data']:\r\n  print(\"\"\"\r\n    Port: {}\r\n    Banner: {}\r\n    \"\"\".format(item['port'], item['data']))<\/pre>\n<p>Resultado.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">  Port: 53\r\n  Banner:\r\nRecursion: enabled\r\n<\/pre>\n<p>Como el resultado anterior es muy simple, a continuaci\u00f3n se muestra el resultado tras consultar otra IP diferente.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">  Port: 443\r\n  Banner: HTTP\/1.1 200 OK\r\nDate: Wed, 28 Nov 2018 07:09:50 GMT\r\nContent-Type: text\/html; charset=utf-8\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nKeep-Alive: timeout=10\r\nVary: Accept-Encoding\r\nX-Powered-By: PHP\/5.6.38-0+deb8u1\r\nServer: RainLoop\r\nStrict-Transport-Security: max-age=15768000\r\n\r\n\r\n\r\n\r\n  Port: 993\r\n  Banner: * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] Dovecot ready.\r\n* CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN\r\nA001 OK Pre-login capabilities listed, post-login capabilities have more.\r\n* ID (\"name\" \"Dovecot\")\r\nA002 OK ID completed.\r\nA003 BAD Error in IMAP command received by server.\r\n* BYE Logging out\r\nA004 OK Logout completed.\r\n\r\n<\/pre>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Script_busqueda_basica\"><\/span>Script b\u00fasqueda b\u00e1sica<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>El siguiente script, que llamaremos <em><strong>busquedaBasica.py<\/strong><\/em><em>,\u00a0<\/em>permite realizar una b\u00fasqueda b\u00e1sica con el m\u00e9todo\u00a0<em><strong>search<\/strong><\/em> y mostrar las IPs registradas con el patr\u00f3n indicado.\u00a0Se debe de indicar alg\u00fan par\u00e1metro tras ejecutar el script.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">#!\/usr\/bin\/env python\r\n#\r\n# Buscador para imprimir una lista de IPs resultantes de una consulta.\r\n\r\nimport shodan, sys\r\n\r\nAPI_KEY = \"XXX\"\r\n\r\n# Validacion de entrada\r\nif len(sys.argv) == 1:\r\n        print 'Uso: %s &lt;search query&gt;' % sys.argv[0]\r\n        sys.exit(1)\r\n\r\ntry:\r\n        # Setup de API\r\n        api = shodan.Shodan(API_KEY)\r\n\r\n        # Perform the search\r\n        query = ' '.join(sys.argv[1:])\r\n        result = api.search(query)\r\n\r\n        # Loop through the matches and print aeach IP\r\n        for service in result['matches']:\r\n                print service['ip_str']\r\n\r\nexcept Exception as e:\r\n        print 'Error: %s' % e\r\n        sys.exit(1)<\/pre>\n<p>Resultados.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\"># .\/basicSearch.py\r\nUso: .\/basicSearch.py &lt;search query&gt;\r\n\r\n# .\/basicSearch.py postfix\r\n110.164.188.212\r\n107.170.209.96\r\n194.49.99.178\r\n107.6.142.228\r\n91.134.112.234\r\n....<\/pre>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Busqueda_con_FACETS\"><\/span>B\u00fasqueda con FACETS<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Los\u00a0<em><strong>FACETS<\/strong><\/em><em>\u00a0<\/em>son propiedades de los resultados, como pueden ser organizaci\u00f3n, dominio, puerto, &#8230;, muy \u00fatiles para organizar los resultados de una b\u00fasqueda. Nos permite, entre otras cosas, conocer qu\u00e9 versiones son las m\u00e1s populares, o qu\u00e9 pa\u00edses son los que m\u00e1s resultados muestran en funci\u00f3n de lo especificado en la b\u00fasqueda.<\/p>\n<p>Para ello usamos el m\u00e9todo\u00a0<em><strong>count()<\/strong><\/em> para buscar en Shoddan sin devolver cualquier resultado. Preguntamos por informaci\u00f3n concreta, acotando la b\u00fasqueda, y por consiguiente el resultado. Por defecto se muestra el top 5 del resultado de cada\u00a0<em><strong>facet<\/strong><\/em>, a no ser que indiquemos lo contrario como vamos a poder ver en el siguiente ejemplo (facet <em><strong>country<\/strong><\/em>).<\/p>\n<p>En el siguiente script, que llamaremos <em><strong>query-search.py<\/strong> <\/em>indicamos el patr\u00f3n por el que queremos buscar.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">#!\/usr\/bin\/env python\r\n#\r\n# Busqueda en Shodan e impresion del resultado de la query.\r\n\r\nimport shodan, sys\r\n\r\n# Configuracion\r\nAPI_KEY = \"XXX\"\r\n\r\n# Lista de propiedades que queremos mostrar.\r\n# Por defecto se muestran los primeros 5 resultados.\r\nFACETS = [\r\n        'org',\r\n        'domain',\r\n        'port',\r\n        'asn',\r\n        # Solo queremos mostrar el top 3 de paises.\r\n        # Por defecto se muestran 5!!!\r\n        # Si queremos mostrar mas de 5 indicamos ('country', 1000) para mostrar 1000, por ejemplo.\r\n        ('country', 3),\r\n]\r\n\r\nFACET_TITLES = {\r\n        'org': 'Top 5 Organizaciones',\r\n        'domain': 'Top 5 Dominios',\r\n        'port': 'Top 5 Puertos',\r\n        'asn': 'Top 5 Sistemas Autonomos',\r\n        'country': 'Top 3 Paises',\r\n}\r\n\r\n# Validacion de entrada.\r\nif len(sys.argv) == 1:\r\n        print 'Usage: %s &lt;search query&gt;' % sys.argv[0]\r\n        sys.exit(1)\r\n\r\ntry:\r\n        # Setup API\r\n        api = shodan.Shodan(API_KEY)\r\n\r\n        # Generamos la variable de la query con los argumentos.\r\n        query = ' '.join(sys.argv[1:])\r\n\r\n        # Usamos el metoddo count() porque no devuelve resultados y no requiere un plan de pago.\r\n        # Y es mas rapido que ejecutar un search().\r\n        result = api.count(query, facets=FACETS)\r\n\r\n        print 'Shodan Summary Information'\r\n        print 'Query: %s' % query\r\n        print 'Total Results: %s\\n' % result['total']\r\n\r\n        # Imprimer la informacion de los facets.\r\n        for facet in result['facets']:\r\n                print FACET_TITLES[facet]\r\n\r\n                for term in result['facets'][facet]:\r\n                        print '%s: %s' % (term['value'], term['count'])\r\n\r\n                # Imprimerr una linea en blanco entre el resumen y la info.\r\n                print ''\r\n\r\nexcept Exception, e:\r\n\r\n        print 'Error: %s' % e\r\n        sys.exit(1)\r\n<\/pre>\n<p>Resultado.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">.\/query-summary.py apache\r\nShodan Summary Information\r\nQuery: apache\r\nTotal Results: 34612043\r\n\r\nTop 5 Organizations\r\nAmazon.com: 808061\r\nEcommerce Corporation: 788704\r\nVerio Web Hosting: 760112\r\nUnified Layer: 627827\r\nGoDaddy.com, LLC: 567004\r\n\r\nTop 5 Domains\r\nsecureserver.net: 562047\r\nunifiedlayer.com: 494399\r\nt-ipconnect.de: 385792\r\nnetart.pl: 194817\r\nwanadoo.fr: 151925\r\n\r\nTop 5 Ports\r\n80: 24118703\r\n443: 8330932\r\n8080: 1479050\r\n81: 359025\r\n8443: 231441\r\n\r\nTop 5 Autonomous Systems\r\nas32392: 580002\r\nas2914: 465786\r\nas26496: 414998\r\nas48030: 332000\r\nas8560: 255774\r\n\r\nTop 3 Countries\r\nUS: 13227366\r\nDE: 2900530\r\nJP: 2014506<\/pre>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Listado_de_metodos\"><\/span>Listado de m\u00e9todos<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>En el siguiente enlace se pueden consultar todos los m\u00e9todos publicados para la API. Dependiendo de la licencia adquirida algunos m\u00e9todos no podr\u00e1n ser utilizados.<\/p>\n<p><a href=\"https:\/\/shodan.readthedocs.io\/en\/latest\/api.html\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">https:\/\/shodan.readthedocs.io\/en\/latest\/api.html<\/a><\/p>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Fuentes\"><\/span>Fuentes<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Shodan oficial pincha <a href=\"https:\/\/www.shodan.io\/\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"external external_icon\">aqu\u00ed<\/a>.<\/p>\n<p>Shodan API reference pincha <a href=\"https:\/\/developer.shodan.io\/api\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"external external_icon\">aqu\u00ed<\/a>.<\/p>\n<p>Shodan Python GitHub pincha <a href=\"https:\/\/github.com\/achillean\/shodan-python\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"external external_icon\">aqu\u00ed<\/a>.<\/p>\n<p>Shodan Python doc pincha <a href=\"https:\/\/shodan.readthedocs.io\/en\/latest\/\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"external external_icon\">aqu\u00ed<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Durante el pasado Black Friday\u00a0el portal de consulta de cualquier dispositivo conectado a Internet\u00a0Shodan\u00a0puso de oferta el upgrade de las cuentas free\u00a0por \u00a049\u00a0\u00a05 \u20ac, oferta<span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/blog.tiraquelibras.com\/?p=306\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":308,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,21],"tags":[27,33],"class_list":["post-306","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ciberseguridad","category-iot","tag-python","tag-shodan"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=306"}],"version-history":[{"count":0,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/306\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/media\/308"}],"wp:attachment":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}