• Marcos Pablo Russo

Shodan Console

Shodan es un motor de búsqueda, la diferencia con los buscadores normales es que está enfocada únicamente en buscar dispositivos que se encuentran conectados en Internet, es decir sistemas operativos, cámaras de seguridad, servicios, puertos en los que corren, además de poder analizar ciertos metadatos, encabezados, sistemas de alarmas, teléfonos, impresoras, plantas industriales y muchísimas cosas más.


Está clasificado como un buscador peligros, todo lo que se encuentra conectado el IT de las cosas, por está razón es muy peligroso.


La interfaz de cliente de Shodan nos permite por medio de una consola realizar búsquedas estos tipos de búsquedas, utiliza una librería de Python.


Podemos utilizar dorks para realizar distintos tipos de búsquedas, como por ejemplo country: ar, que nos permite buscar por países, en este caso Argentina.



Shodan


Es un buen instrumento de obtener información para los auditores, para buscar servidores que se estén auditando o buscar cualquier tipo de servicios, y obtener de ellos mucha información para realizar la auditoría.



Instalación

Para realizar la instalación desde la distribución Debian o Ubuntu procedemos de forma muy sencilla.

# apt-get install python3-shodan

Más allá del programa instala la librería para utilizar en Python 3, y realizar lo mismo con el comando, pero a través de un programa nuestro.



Utilización


Ejecutamos simplemente shodan para ver las opciones.




Tenemos que agregar la API Key que la podemos conseguir desde la url https://developer.shodan.io/, tenemos que crearnos una cuenta y luego de ingresar, ir a nuestra cuenta donde veremos la API.



Luego para comenzar ejecutamos el comando, shodan init con la API Key que obtuvimos desde nuestra cuenta, esto nos permite inicializarlo.



Podemos utilizar la opción search para buscar cierta información como también pasarle los parámetros de parseo.


Entre las opciones que podemos utilizar son las siguientes:

  • city: el filtro city (ciudad) es utilizado para encontrar dispositivos en una ciudad específica, como, por ejemplo: city: "Buenos Aires".

  • country: país que le podemos especificar en el cual deseamos realizar la búsqueda, como, por ejemplo: country:AR.

  • port: utilizamos este filtro podremos obtener resultados específicos sobre los puertos que queramos, por ejemplo: port: 80.

  • net: al utilizar este filtro de red, podremos obtener resultados sobre las redes específicas que hayamos indicado, por ejemplo: net:1.1.1.1/8.

  • os: Operating System, es utilizado para realizar búsquedas específicas por sistemas operativos como así también sus versiones. Ejemplo: os: "Windows XP".

  • isp: en caso de querer filtrar las búsquedas por ISP (Internet Service Provider) podemos utilizar este filtro, por ejemplo: isp: telefonica.

  • hostname: si lo que necesitamos es buscar por hostname/dominio podemos utilizar ese filtro. Ejemplo: hostname: www.nfobae.com.ar.

  • after: muestra los resultados obtenidos después de la fecha especificada, por ejemplo: after: 01/01/2019.

  • before: muestra los resultados obtenidos antes de la fecha indicada, por ejemplo: before 01/01/2020.

Listo ahora que tenemos puesto la API Key, podemos empezar a trabajarlo. Lo primero que vamos a hacer obtener la IP de una url determinada con el comando nslookup, luego traemos la información a través de la IP, con el comando shodan host IP.



Como podemos observar no muestra el nombre del host, la organización, continente, el puerto que tiene abierto con su versión.


Si queremos saber cuántos servidores del mundo tiene la version de tomcat 1.1.



Para ver la ayuda del parámetro count y de cualquier parámetro indicamos mediante la opción -h.



Si queremos saber la cantidad de sistemas operativos Windows versión 7 que hay en el mundo.

Podemos obtener un listado de las estaciones de trabajo que tiene el sistema operativo Windows 7, vamos a utilizar la opción download. Esta salida genera un archivo JSON, donde cada línea es un banner JSON. Por defecto descarga 1.000 resultados, si se requiere descargar más, utilizamos la opción --limit CANTIDAD.



Vamos a tener varios campos que componen la información obtenida, como:

  • info

  • product

  • hostname

  • hash

  • ip

  • org

  • isp

  • transport

  • cpe

  • port

  • version

  • ssh

  • vulns

  • etc

Por ejemplo también mediante esta opción podemos buscar la cantidad de puerto 445, en el cual hubo una vulnerabilidad de SMB (CVE-2020-0796) que se conoció por un descuido de Microsoft a primeros días de Marzo.



Otra opción de la que podemos utilizar en el continente. por ejemplo, country:ar.


Si queremos ver de alguna forma más elegante la salida de la información, podemos parsear los campos, utilizando parse --fields Campos NombreDelArchivo también podemos utilizar el subcomando --separator SEPARADOR.



Si queremos saber cuál es nuestra IP, mediante el comando myip.




Podemos buscar cámara web como "ip camare 200", donde el número 200 hace referencia a una petición (OK) del código de estado del protocolo HTTP.



Ahí como observamos nos da la url por ejemplo, athedsl-217455.home.otenet.gr y el puerto 8080, para poder conectarnos.



Si queremos buscar varios modelos de un router Linksys, y bajar la información de los mismos, podemos crear un archivo donde en cada línea podemos indicar los modelos y pasarlo a shodan para que lo tome.



Luego tenemos que ir parseando como vimos los datos que nos interesan. Para realizar esto con varios archivos realizamos el siguiente comando.




Programación en Python utilizando la librería de Shodan

Para esto ejecutamos Python3.

$ python3
   Python 3.8.2 (default, Apr 27 2020, 15:53:34)
   [GCC 9.3.0] on linux
   Type "help", "copyright", "credits" or "license" for more     
   information.


Inicializando la API Key en Python3


Una vez inicializado Python3 vamos a ejecutar nuestro primer programa que nos permite inicializar con nuestra API Key.

import shodan
SHODAN_API_KEY = "NUESTRA_API"
api = shodan.Shodan(SHODAN_API_KEY)


Información de nuestra cuenta


De esta forma mediante la variable api podemos obtener información de nuestra cuenta de Shodan, si tenemos un plan o no, etc.

api.info()
{'scan_credits': 0, 'usage_limits': {'scan_credits': 0, 'query_credits': 0, 'monitored_ips': 0}, 'plan': 'oss', 'https': False, 'unlocked': False, 'query_credits': 0, 'monitored_ips': 0, 'unlocked_left': 0, 'telnet': False}


Realizar una búsqueda con search


Ahora si queremos realizar una búsqueda, vamos a usar el método search e iterar con los resultados obtenidos.

try:
   results = api.search('apache')
   print('Resultados encontrados: {}' .   
   format(results['total']))

   for result in results['matches']:
     print('IP: {}' . format(result['ip_str']))
     print(result['data'])
     print('')
except shodan.APIError as e:
    print('Error: {}' . format(e))

Resultado obtenido:

Resultados encontrados: 16564282
IP: 34.231.224.63
HTTP/1.1 200 OK
Date: Mon, 18 May 2020 23:57:01 GMT
Content-Type: text/html
Content-Length: 13139
Connection: keep-alive
Server: Apache/2.4.29 (Ubuntu)
Last-Modified: Thu, 09 Apr 2020 01:06:47 GMT
ETag: "3353-5a2d13b20b480"
Accept-Ranges: bytes
Vary: Accept-Encoding
IP: 52.166.151.164
HTTP/1.1 301 Moved Permanently
Date: Mon, 18 May 2020 23:57:05 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips
Strict-Transport-Security: max-age=31536000
Location: https://52.166.151.164/
Content-Length: 231
Content-Type: text/html; charset=iso-8859-1


Búsqueda utilizando host y get


Si ahora queremos buscar información en concreto de un host, usaremos el método host y la función get.

results = api.host('8.8.8.8')
# Mostramos la información
print("""
  IP: {}
  Organizacion: {}
  Sistema Operativo: {}
""" . format(results['ip_str'], results.get('org', 'n/a'),
results.get('os', 'n/a')))

El resultado es:

IP: 8.8.8.8
Organizacion: Google
Sistema Operativo: None

Mostrar Banners


Usando el programa anterior podemos obtener los Banners mostrados por los servicios.

results = api.host('8.8.8.8')
for item in results['data']:
print("""
Port: {}
Banner: {}
""" . format(item['port'], item['data']))

El resultado es:

Port: 53
Banner: 0\x84\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00

Port: 53
Banner: HTTP/1.1 302 Found
Location: https://www.google.com/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
Date: Mon, 18 May 2020 10:03:53 GMT
Server: sffe
Content-Length: 220
X-XSS-Protection: 0
Alt-Svc: h3-27=":443"; ma=2592000,h3-25=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"


Script de búsqueda básica


Permite realizar una búsqueda básica con el método que ya vimos search y mostrar las IPs registradas con el patrón indicado. Se le debe pasar como parámetro un valor a buscar.

#!/usr/bin/env python3
# Buscador para imprimir una lista de IPs resultantes de una # consulta.

import shodan
import sys

# Declaro en la variable la API KEY
API_KEY = "API_KEY"

# Validacion de entrada
if len(sys.argv) == 1:
  print('Uso: %s <search query>' % sys.argv[0])
  sys.exit(1)

try:
  # Setup de API
  api = shodan.Shodan(API_KEY)

  # Perform the search
  query = ' '.join(sys.argv[1:])
  result = api.search(query)

  # Loop through the matches and print aeach IP
  for service in result['matches']:
    print (service['ip_str'])
except Exception as e:
   print ('Error: %s' % e)
   sys.exit(1)

El resultado del script:

$./buscar.py
Uso: ./buscar.py <search query>

$ ./buscarod.py apache
107.180.233.79
23.83.62.4
84.146.16.158
207.126.160.61
47.110.80.106
13.208.83.145
13.233.197.248
149.210.195.106
80.149.226.60
142.44.174.87
104.253.48.125
162.241.45.147
146.88.163.26
213.215.247.219
198.143.148.54
168.227.97.43
143.125.234.180
58.191.153.160
47.254.34.150
52.8.171.9
85.90.123.187
107.149.162.51
45.191.30.41
1.51.214.33

Búsqueda con FACETS


Son propiedades de los resultados, como pueden ser organización, dominio, puertos, etc, muy útil para organizar los resultados de una búsqueda. Nos permite también saber qué versiones son las más populares, o qué países son los que más resultados muestran en función de lo especificado en la búsqueda.


Para esto vamos a utilizar el método count() para buscar en Shodan, se muestra por defecto el top 5 del resultado por cada facet, a no ser que indiquemos lo contrario como vamos a poder ver en el siguiente ejemplo.

#!/usr/bin/env python3

# Busqueda en Shodan e impresion del resultado de la query.

import shodan
import sys

# Configuracion
API_KEY = "API_KEY"

# Lista de propiedades que queremos mostrar.
# Por defecto se muestran los primeros 5 resultados.
FACETS = [
  'org',
  'domain',
  'port',
  'asn',
  # Solo queremos mostrar el top 3 de paises.
  # Por defecto se muestran 5!!!
  # Si queremos mostrar mas de 5 indicamos ('country', 1000)
  # para mostrar 1000, por ejemplo.
  ('country', 3),
]

FACET_TITLES = {
  'org': 'Top 5 Organizaciones',
  'domain': 'Top 5 Dominios',
  'port': 'Top 5 Puertos',
  'asn': 'Top 5 Sistemas Autonomos',
  'country': 'Top 3 Paises',
}

# Validacion de entrada.
if len(sys.argv) == 1:
  print ('Usage: %s ' % sys.argv[0])
  sys.exit(1)

try:
  # Setup API
  api = shodan.Shodan(API_KEY)
  
  # Generamos la variable de la query con los argumentos.
  query = ' '.join(sys.argv[1:])

  # Usamos el metoddo count() porque no devuelve
  # resultados y no requiere un plan de pago.
  # Y es mas rapido que ejecutar un search().
  result = api.count(query, facets=FACETS)
  print ('Shodan Summary Information')
  print ('Query: %s' % query)
  print ('Total Results: %s\n' % result['total'])

  # Imprimer la informacion de los facets.
  for facet in result['facets']:
    print (FACET_TITLES[facet])
  
    for term in result['facets'][facet]:
       print ('%s: %s' % (term['value'], term['count']))
    
    # Imprimer una linea en blanco entre el resumen 
    # y la info.
    print('')
except Exception as e:
  print ('Error: %s' % e)
  sys.exit(1)

El resultado:

$ ./query-search.py
Usage: ./query-search.py

$ ./query-search.py apache
Shodan Summary Information
Query: apache
Total Results: 23910847
Top 5 Organizaciones
Amazon.com: 2510938
OVH SAS: 819350
Hangzhou Alibaba Advertising Co.,Ltd.: 814342
GoDaddy.com, LLC: 553518
Digital Ocean: 492741

Top 5 Dominios
amazonaws.com: 2546461
secureserver.net: 558737
unifiedlayer.com: 327209
googleusercontent.com: 269409
hinet.net: 181981

Top 5 Puertos
80: 10952999
443: 7833549
8080: 873549
8081: 395685
8443: 204205

Top 5 Sistemas Autonomos
as16509: 1932171
as16276: 842667
as37963: 814342
as14618: 702045
as14061: 569490

Top 3 Paises
US: 8304752
DE: 2030627
CN: 1589821

Listado de métodos

En el siguiente enlace se pueden consultar todos los métodos publicados para la API. Dependiendo de la licencia adquirida algunos métodos no podrán ser utilizados.

https://shodan.readthedocs.io/en/latest/api.html



Fuentes


Shodan oficial: https://www.shodan.io/

Shodan API: https://developer.shodan.io/api

Shodan Python GitHub: https://github.com/achillean/shodan-python

Shodan Python Doc: https://shodan.readthedocs.io/en/latest/

Info: https://blog.tiraquelibras.com/?p=306

Vídeos de Shodan: https://asciinema.org/~Shodan



Conclusión


Es una excelente herramienta de OSINT y como bien se comentó para auditar, muy sencilla de utilizar y tanto por consola como por algún sistema que hagamos es muy sencillo.