Obtenha registros reverse NS (também conhecidos como DNS passivo) para uma lista de IPs em Python
O DNS passivo, introduzido por Florian Weimer em 2005, é agora um recurso central em investigações de segurança de IP, segurança da operação do sistema de nomes de domínio (DNS) e muito mais. Um banco de dados de DNS passivo contém eventos observados sempre que um IP é resolvido para um nome de domínio em uma comunicação de DNS. Portanto, é um banco de dados independente do estado atual, bem como da infraestrutura física do próprio DNS. Além disso, ele contém informações de tempo: a data e a hora em que essa resolução foi observada pela primeira e pela última vez; isso não pode ser descoberto pelo DNS.
Uma das maneiras mais fáceis de obter esses dados é usar os serviços da API WhoisXML. Neste blog, vamos nos concentrar na pesquisa reversa: usando um endereço IPv4, queremos revelar os nomes de domínio aos quais esses IPs pertenciam em determinadas datas.
Trabalharemos com Python em uma linha de comando do Linux ou do Mac OS X, mas é fácil fazer o mesmo em um ambiente de linha de comando do Windows, desde que o Python seja funcional. Nossa descrição é destinada a iniciantes; pressupõe-se apenas habilidades muito básicas em Python e shell-script. Usaremos a API de IP reverso e o pacote Python fornecido que simplifica muito o uso da API. Essa biblioteca pode ser instalada com o pip, o gerenciador de pacotes do Python. O comando a seguir, quando executado a partir do shell, fará o download e a instalação:
pip3 install reverse-ip
(Opcionalmente, talvez você queira fazer isso como usuário root para disponibilizar a biblioteca em todo o sistema ou fazê-lo em um ambiente virtual Python para limitar o escopo da instalação).
O pacote reverse-ip agora está tecnicamente pronto para ser usado, mas também é necessária uma assinatura da API; uma assinatura gratuita também está disponível. Após a assinatura, você receberá uma chave de API, uma cadeia de caracteres, que será chamada de YOUR_API_KEY no que se segue.
Com todos os pré-requisitos em mãos, agora podemos realizar nossa tarefa. Então, vamos supor que temos uma lista de endereços IP em um arquivo chamado ips_demo.csv. Para fins de demonstração, usaremos o exemplo a seguir:
172.67.155.63 104.21.20.75
Esses são endereços IP pertencentes aos serviços da Web da API WhoisXML, mas também são compartilhados com outros serviços pelo nosso provedor da Web.
Implementaremos um script que lê endereços IP da entrada padrão e grava a saída em um formato de valores separados por vírgula (csv) na saída padrão. Portanto, vamos editar o script, get_reverse_ip_of_a_list.py, com um editor de texto adequado para programadores. Primeiro, vamos apenas ler os IPs e repeti-los na saída padrão, e esse código inicial será lido:
#!/usr/bin/env python3 importar sys for line in sys.stdin.readlines(): ip = line.strip() sys.stdout.write('"%s",'%ip) sys.stdout.write("\n")
Poderíamos optar por uma maneira mais sofisticada de ler nossos IPs, mas vamos manter as coisas simples. Apenas lemos as linhas provenientes da entrada padrão e removemos todos os caracteres adicionais, como novas linhas, com .strip(), e escrevemos o IP na saída padrão, entre aspas duplas seguidas por uma vírgula; os resultados serão apresentados aqui. Em seguida, escrevemos uma nova linha, pois já mantivemos o espaço entre as duas chamadas sys.stdout.write para a parte principal do script.
Mas antes de estendê-lo, vamos tentar: na linha de comando do shell, vamos fazer
chmod +x get_reverse_ip_of_a_list.py get_reverse_ip_of_a_list.py < ips_demo.csv
resultando no seguinte resultado:
"172.67.155.63", "104.21.20.75",
o que é exatamente o esperado.
Vamos agora estender nosso script para fazer seu trabalho. Ele será lido:
#!/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) dados = reverseip.data(ip) para registro em dados['resultado']: sys.stdout.write('"%s","%s","%s",'%(record['name'], datetime.datetime.fromtimestamp( int(record['first_seen'])).strftime('%c'), datetime.datetime.fromtimestamp( int(registro['última_visita'])).strftime('%c'))) sys.stdout.write("\n") sleep(.1)
Não se esqueça de substituir YOUR_API_KEY por sua chave de API real para que funcione. O que fazemos é muito simples: apenas importamos a classe Client do módulo e criamos a instância reverseip, na qual passamos a chave da API. Em seguida, o resultado será obtido com a chamada de reverseip.data, prontamente em um dicionário Python; para obter detalhes sobre o formato dos dados de saída, consulte a documentação da API.
Por enquanto, é suficiente saber que o campo de resultado da saída, ou seja, data['result'] é um iterador para os registros encontrados. (Mais precisamente, para até 300 registros. Em geral, sempre que o número de nomes de domínio de um IP for superior a 50 ou 100, a infraestrutura é compartilhada e, possivelmente, não é tão significativo ter todos os registros. No entanto, se você precisar de todos eles, os documentos da API descrevem como fazer isso).
Portanto, iteramos pelos registros, se houver algum. Cada registro tem três campos: name é o nome de domínio real, enquanto first_seen e last_visit fornecem a data e a hora da primeira e da última observação desse par IP-nome. Isso é fornecido pela API na forma de timestamp; nós o convertemos em datetimes legíveis no formato de data e no fuso horário do sistema local por meio das funções aparentemente complicadas, mas lógicas, da biblioteca Python padrão datetime. Anexamos cada tripleto à linha de saída fornecida.
Por fim, esperamos 0,1 segundo para não esbarrar em nenhum limite de limitação da API. (O número máximo de solicitações por segundo é, na verdade, 30, portanto, isso pode até ser omitido). Vamos ver o que fizemos:
./get_reverse_ip_of_a_list.py < ips_demo.csv
agora resultará em
"172.67.155.63", "labbry.com", "Sex Jul 26 07:03:05 2019", "Sex May 7 11:09:07 2021", "livitte.com", "Sex Sep 13 07:15:39 2019", "Sex May ... "104.21.20.75", "taalmedia.com", "Sex 21 Jun 13:50:38 2019", "Sex 23 Abr 18:12:27 2021",
pelo menos no momento em que este blog foi escrito. (Truncamos a segunda linha por motivos tipográficos.) Talvez você queira direcionar a saída padrão para um arquivo:
./get_reverse_ip_of_a_list.py < ips_demo.csv > ips_pdns.csv
para que o arquivo ips_pdns.csv possa ser importado com sua planilha de escritório favorita.
Concluindo, demonstramos como obter dados de DNS passivos com muita facilidade em Python. Mesmo que você tenha acabado de começar a trabalhar com Python, poderá fazer isso rapidamente. Enquanto isso, para o programador Python avançado, a mensagem é simplesmente a seguinte: depois de instalar o pacote Python reverse-ip e obter uma chave de API da API WhoisXML, você pode obter dados de DNS passivos,
from reverseip import Client reverseip = Client('YOUR_API_KEY') dados = reverseip.data(ip)
fornece um dicionário Python com registros DNS passivos para um endereço IP. E essa talvez seja a maneira mais fácil de obter esses dados com uma única chamada de função.