miércoles, 12 de abril de 2017

APIs de Censys y Shodan - [How To]


Censys (https://censys.io/) y Shodan (https://shodan.io)... dos poderosos motores de búsqueda cuya base de datos guarda información obtenida a partir de sus continuos escaneos hacia nada más y nada menos que cada dispositivo conectado a internet.  

¿Qué información obtienen estos buscadores por cada IP que escanean? Podríamos decir, que obtienen datos de qué, de quién y en dónde. “De qué” porque podemos llegar a deducir qué tipo de dispositivo se encuentra detrás de cada IP al ver cuáles puertos se encontraron abiertos al momento que shodan/censys lo escanearon. “De quién” porque datos como el hostname, ISP, organización y dominios asociados serán también almacenados si se encuentran disponibles. “En dónde” porque cada dirección IP escaneada es también geolocalizada.

Este tipo de buscadores se utiliza habitualmente para encontrar dispositivos específicos tales como cámaras IP, equipos con determinado S.O/software, sistemas industriales, dispositivos IoT, etc.

Como usuarios, la interfaz web de estos buscadores y sus respectivos filtros, son suficiente para entretenernos un buen rato. Sin embargo, cuando nos vemos involucrados en un proyecto donde se pretende utilizar mucha de la información recopilada por estos buscadores, no queda otra opción más que hacer uso de sus APIs, ya que están para ser utilizadas en esos casos.

En esa última situación me ví yo. Los últimos días he tenido que involucrarme con las APIs tanto de shodan como de censys, y debo decir, que me he peleado mucho MUCHO MUCHO con estos recursos.

 
La API de censys fue publicada recientemente y casi no cuenta con documentación, por lo que no basta con ser programador para que las cosas anden bien, también hay que ser mago y adivinar cómo formar correctamente los requests, adicionalmente un master sobre parseo de JSON mal formateados también serviría :). Por otro lado, los límites de la API tampoco están bien definidos, así que uno se encuentra con ellos cuando ya tenías casi todo terminado y repentinamente “HELLO! LIMIT REACHED!” a buscar otra alternativa…
  
Respecto de shodan, la API cuenta con mucha más documentación. Sin embargo, en la práctica hay varias cuestiones que se deben tener en cuenta. De eso se trata esta nota, mi objetivo es dejarles una serie de TIPs útiles para poder trabajar con estas APIs sin llevarse sorpresas que les traigan fuertes dolores de cabeza (como me pasó a mí :p).


CENSYS API 
La API de censys hasta el momento es gratuita, el token se obtiene registrando un usuario en el sitio, acción que puede realizarse sin costo alguno. El intento de documentación se encuentra aquí: https://censys.io/api.

La API autentica al consumidor por “HTTP basic” y es necesario enviar el token en cada consulta que hagamos al recurso que estemos utilizando. Saber eso nos ahorrará el primer dolor de cabeza, ya que en ningún lado dice que es necesario autenticarse en cada requerimiento, aún aunque previamente hayamos hecho la petición propiamente de autenticación (el primer y casi único ejemplo que se vé en la documentación).

El recurso más práctico y veloz de la API de censys es SEARCH. El mismo recibe por parámetro POST una cadena con la búsqueda que deseemos hacer (tal como la escribiríamos en la interfaz web del buscador).  La información que nos devuelve censys por cada IP es la siguiente:

  • Dirección IP.
  • Continente, país y ciudad.
  • Latitud y Longitud.

A continuación un pequeño ejemplo de cómo sería una consulta a través de este recurso, autenticándonos como corresponde :)


La respuesta a esa petición utilizando SEARCH, es un JSON con los resultados correspondientes a la primera página (100 resultados) de nuestra consulta, cada resultado se encuentra dentro del objeto ['results']. 
Adicionalmente el JSON trae el objeto ['metadata'] donde se expresa el número total de resultados y de páginas, por lo tanto, iterar entre las páginas para lograr recorrer todos los registros de la base de datos es fácil con un simple while:

 

Bueno… lo de “todos los registros” es una manera de decir… la realidad es que la API nos limita a 10.000 resultados por consulta. Eso significa que cuando solicites la página 101, devolverá un error de tipo “LIMIT REACHED!” que jamás nos avisaron, porque en ningún lado dice que solo nos permitirán llegar hasta 10.000 resultados por consulta. Junto a ese error, censys imprime un mensaje de que si quieres superar ese límite, utilices el recurso EXPORT.
 
En mi caso yo estaba consultando por protocolos que devolvían hasta más de 20.000 resultados, por lo que fui a leer la documentación no documentada de este recurso y al intentar usarlo, no hubo forma, no funciona aún (: FUCK! ¿Y AHORA?

El objetivo era llegar a obtener lo que el recurso EXPORT debía devolver, que es un link de descarga de un archivo comprimido con el total de resultados para nuestra consulta. Paseando por la API, encontré una respuesta interesante en la petición de autenticación, allí se devuelve información sobre los archivos que genera censys semanalmente con los resultados obtenidos por cada puerto/protocolo escaneado. Por ejemplo, tenemos un archivo comprimido en lz4 con todos los resultados obtenidos en la presente semana sobre equipos que tengan el puerto 21 abierto.

Al realizar la petición de autenticación, se obtiene un JSON donde por cada protocolo escaneado, se encuentra la clave ['details_url'] que es una URL que si la consultamos, obtenemos otro JSON con más URLs: una por cada escaneo semanal que se ha realizado sobre el protocolo que estamos consultando. Si nos quedamos con el primer registro (URL del último escaneo) y lo consultamos, también obtenemos otro JSON, ahora con los links de descarga en diferentes formatos para ese escaneo ¡Eureka! Tras 3 consultas parseando esos JSON bastante mal formateados, llegamos a lo que queríamos: poder descargarnos un archivo con absolutamente todos los resultados encontrados por censys para el protocolo que nos interesa :)


Pero si creían que las dificultades se terminaron ahí, les cuento que no. Al descargar ese archivo tan deseado y descomprimirlo, nos volvemos a encontrar con otro JSON mal formado, bastante difícil de utilizar. La gente de censys hizo lo siguiente: generó una lista {} por cada registro que tiene en su db y básicamente para generar el archivo que nos descargamos hace un “append” insertando cada lista en el archivo. Eso significa que no existe un objeto JSON en ese “JSON” xD y además, los registros no cuentan siempre con las mismas claves por lo que parsear eso fue también otro dolor de cabeza (: la solución fue levantar ese archivo leyéndolo como si fuera un txt con listas (no como JSON) y luego por cada lista individual sí generar un JSON y extraer las claves interesantes. Una cosa horrible pero funciona :)

En resumen, podemos decir que la API de censys cuenta con las siguientes ventajas y desventajas:
 
Ventajas: 
  • API gratuita.
  • Gran velocidad de respuesta para el recurso SEARCH.
 Desventajas: 
  • Documentación inútil poco útil.
  • Falta de advertencias en cuanto a los límites.
  • JSON mal formados en la mayoría de las respuestas de la API.
  • JSON mal formados en los archivos que se disponen para descarga.


SHODAN API
 
La API de shodan es de pago y su modelo se basa en créditos, es decir, cada consulta que hagamos a la API consumirá un crédito. En la práctica eso no está bueno para los consumidores ya que debemos tener en cuenta que por ejemplo si usamos el recurso SEARCH, tan solo cada página de resultados que solicitemos de una misma búsqueda se consumirá 1 crédito (si, se van rápido). 
La documentación se encuentra aquí: https://developer.shodan.io/api.
 
Si utilizamos el recurso SEARCH podemos pasar por parámetro GET una cadena de búsqueda. La API, en teoría, nos devolvería los primeros 100 resultados (correspondientes a la primera página de nuestra consulta). En la práctica esto no es así, la API siempre devuelve una cantidad de resultados diferente que varía entre los 50 y 70 registros por página. Esto afecta en varios puntos ya que la API, si dice tener 1500 resultados para nuestra consulta, nos permitirá llegar a solicitar hasta la página 15. Ahora bien, como la API nunca llega a traer realmente 100 resultados por página, nunca llegaremos a obtener los 1500 registros que se supone que hay (esto lo podemos ver en la clave “count” de cada respuesta JSON a nuestra consulta). ¿Qué ocurre con todos esos registros que no podemos llegar a obtener? Solo shodan sabe xD



La información que nos brinda shodan por IP es la siguiente:
  • Dirección IP
  • Puerto, Protocolo, Sistema Operativo y banner del servicio.
  • Organización 
  • I.S.P
  • Dominios y hostname.
  • País, ciudad, latitud y longitud.
Respecto de la iteración de páginas desde el código, a diferencia de censys, shodan no devuelve en el JSON la cantidad de páginas para nuestra búsqueda, solo dice la cantidad total de registros, por lo tanto no podremos iterar entre páginas con un simple “while”. Una solución a esto es incrementar de página verificando que en la respuesta el objeto [‘matches’] del JSON no venga vacío (eso es lo que ocurre cuando nos pasamos de rosca con las solicitudes).

Otra cuestión importante a tener en cuenta si usamos shodan, es que la API es realmente MUY lenta. Tan así que recomiendo descartar su uso si se planea utilizar para obtener gran cantidad de resultados. Shodan nos devuelve aproximadamente hasta 6000/7000 registros por hora, muy lento en comparación con otras APIs, incluso con la de censys, que puede devolvernos esa misma cantidad de registros en tan solo 5 minutos o menos.

En resumen, ventajas y desventajas de shodan:

Ventajas:
  • Buena cantidad de información asociada a cada IP.
  • Fácil de utilizar con pycurl.
  • Objetos JSON de respuesta bien formateados.
  • Relativamente buena documentación
Desventajas:
  • API de pago, por créditos.
  • Mucha lentitud para procesar las consultas.

Bueno eso es todo, espero que les sea de mucha utilidad esta nota si desean trabajar con las API's de censys y shodan. Necesitaba escribir esto para descargar mi bronca contra la lucha que tuve con estas API's jajaja y bueno, anotando todo espero, como ya dije, ahorrarles dolores de cabeza :) ¡Nos leemos pronto!.

Author: Sheila A. Berta

No hay comentarios.:

Publicar un comentario