Obtener registros NS inversos (DNS pasivos) para una lista de IP en Python | Reverse IP/DNS API | WhoisXML API

Obtenga registros NS inversos (también conocidos como DNS pasivos) de una lista de IP en Python

El DNS pasivo, introducido por Florian Weimer en 2005, es ahora un recurso central en las investigaciones sobre seguridad IP, seguridad del funcionamiento del sistema de nombres de dominio (DNS) y muchas otras. Una base de datos de DNS pasivos contiene eventos observados cada vez que una IP resuelve a un nombre de dominio en una comunicación DNS. Por lo tanto, es una base de datos independiente del estado actual, así como de la infraestructura física del propio DNS. Además, contiene información temporal: la fecha y hora en que se observó por primera y última vez una resolución de este tipo; esto no puede averiguarse a partir del DNS. 

Una de las formas más sencillas de obtener estos datos es utilizando los servicios de WhoisXML API. En el presente blog, nos centramos en la búsqueda inversa: utilizando una dirección IPv4 queremos revelar los nombres de dominio a los que pertenecían esas IP en determinadas fechas. 

Trabajaremos en Python en una línea de comandos de Linux o Mac OS X, pero también es fácil hacer lo mismo en un entorno de línea de comandos de Windows, siempre que Python sea funcional. Nuestra descripción está pensada para principiantes; solo se asumen conocimientos muy básicos de Python y script de shell. Utilizaremos la reverse IP API y el paquete Python suministrado que hace que el uso de la API sea muy sencillo. Esta biblioteca se puede instalar con el gestor de paquetes de Python, pip. El siguiente comando, cuando se ejecuta desde el shell, lo descargará e instalará:

pip3 install reverse-ip

(Existe la opción de que quiera hacerlo como usuario root para que la biblioteca esté disponible en todo su sistema, o hacerlo en un entorno virtual Python para limitar el alcance de la instalación).  

El paquete reverse-ip está ahora técnicamente listo para su uso, pero también se necesita una suscripción a la API, hay una suscripción gratuita disponible. Tras la suscripción, recibirá una clave API, un string, que se denominará YOUR_API_KEY en lo que sigue. 

Teniendo todos los prerrequisitos a mano, ahora podemos llevar a cabo nuestra tarea. Supongamos que tenemos una lista de direcciones IP en un archivo llamado ips_demo.csv. Para la demostración, utilizaremos el siguiente ejemplo: 

172.67.155.63
104.21.20.75

Se trata de direcciones IP pertenecientes a los servicios web de WhoisXML API, pero también son compartidas con otros servicios por nuestro proveedor web. 

Vamos a implementar un script que lea direcciones IP de la entrada estándar y escriba la salida en formato de valores separados por comas (csv) en la salida estándar. Así pues, vamos a editar el script, get_reverse_ip_of_a_list.py con un editor de texto adecuado para programadores. Primero, leamos las IP y repitámoslas en la salida estándar, y este código inicial reza:

#!/usr/bin/env python3 import sys   for line in sys.stdin.readlines():     ip = line.strip()     sys.stdout.write('"%s",'%ip)       sys.stdout.write("\n")

Podríamos optar por una forma más sofisticada de leer nuestras IP, pero hagamos que sea sencillo. Simplemente leemos las líneas que vienen de la entrada estándar y eliminamos cualquier carácter adicional como nuevas líneas con .strip(), y escribimos la IP a la salida estándar, entre comillas dobles seguidas de una coma; los resultados seguirán aquí. Luego escribimos una nueva línea, puesto que ya hemos guardado el espacio entre las dos llamadas a sys.stdout.write para la parte principal del script. 

Pero antes de ampliarlo, vamos a probarlo: en la línea de comandos del intérprete de comandos hagamos

chmod +x get_reverse_ip_of_a_list.py
get_reverse_ip_of_a_list.py < ips_demo.csv

El resultado es el siguiente:

"172.67.155.63",
"104.21.20.75",

como era de esperar. 

Extendamos ahora nuestro script para que haga su trabajo. Será:

#!/usr/bin/env python3   import datetime from time import sleep from reverseip import Client   reverseip = Client('YOUR_API_KEY')   for line in sys.stdin.readlines():     ip = line.strip()     sys.stdout.write('"%s",'%ip)       data = reverseip.data(ip)     for record in data['result']: sys.stdout.write('"%s","%s","%s",'%(record['name'],     datetime.datetime.fromtimestamp( int(record['first_seen'])).strftime('%c'),     datetime.datetime.fromtimestamp( int(record['last_visit'])).strftime('%c')))     sys.stdout.write("\n")     sleep(.1)

No olvide sustituir YOUR_API_KEY por su clave API real para que funcione. Lo que hacemos es muy sencillo: simplemente importamos la clase Cliente del módulo, y creamos la instancia reverseip, a la cual le pasamos la clave API. Entonces el resultado se obtendrá con la llamada de reverseip.data, fácilmente consultabe en un diccionario de Python; para los detalles del formato de los datos de salida, por favor, consulte la documentación de la API

Por el momento basta con saber que el campo de resultado de la salida, es decir, data['result'] es un iterador para los registros encontrados. (Más concretamente, para un máximo de 300 registros. En general, siempre que el número de nombres de dominio para una IP sea superior a 50 ó 100, la infraestructura es compartida y posiblemente no tenga tanto sentido disponer de todos los registros. No obstante, si los necesita todos, los documentos de la API describen cómo hacerlo). 

Así pues, iteramos a través de los registros si los hay. Cada registro tiene 3 campos, name es el nombre de dominio real, mientras que first_seen y last_visit dan la fecha y hora de la primera y última observación de este par IP-nombre. Esto lo proporciona la API en forma de marca temporal; nosotros lo convertimos en fechas legibles en el formato de fecha y la zona horaria del sistema local mediante las funciones aparentemente engorrosas pero lógicas de la biblioteca standard datetime de Python. Añadimos cada tripleta a la línea de salida dada. 

Por último, esperamos 0,1 segundos para evitar toparnos con cualquier límite que desborde la API. (En realidad, el número máximo de peticiones por segundo es 30, así que esto puede incluso omitirse). Veamos lo que hemos hecho:

./get_reverse_ip_of_a_list.py < ips_demo.csv

dará como resultado

"172.67.155.63","labbry.com","Fri Jul 26 07:03:05 2019","Fri May  7 11:09:07 2021","livitte.com","Fri Sep 13 07:15:39 2019","Fri May ... "104.21.20.75","taalmedia.com","Fri Jun 21 13:50:38 2019","Fri Apr 23 18:12:27 2021",

al menos en el momento de escribir el presente blog. (Hemos truncado la segunda línea por razones tipográficas.) Es posible que desee dirigir la salida estándar a un archivo:

./get_reverse_ip_of_a_list.py < ips_demo.csv > ips_pdns.csv

para poder importar ips_pdns.csv con su hoja de cálculo ofimática favorita. 

En conclusión, hemos demostrado cómo obtener datos DNS pasivos muy fácilmente en Python; incluso si acaba de empezar a trabajar con Python, el aprendizaje es rápido. Mientras tanto, para el programador avanzado de Python el mensaje es simplemente que después de instalar el paquete reverse-ip Python y hacerse con una clave API de WhoisXML API,

from reverseip import Client   reverseip = Client('YOUR_API_KEY')   data = reverseip.data(ip)

le da un diccionario Python con registros DNS pasivos para una dirección IP. Y esta es quizás la forma más sencilla de obtener esos datos con una sola llamada de función.