Pessoal,
Depois de vários anos sem nenhum post no blog resolvi voltar a ativa e publicar algumas dicas que, espero, sejam úteis para alguém.
Esta semana precisei executar uma varredura de portas TCP utilizando a ferramenta Nmap numa subrede muito grande para a qual não havia tempo hábil para varrer todos os IPs. Tive então que optar por trabalhar com amostragem e a escolha aleatória de endereços IP seria muito útil.
No entanto havia um problema: o Nmap não tem uma opção para escolher aleatoriamente um número finito de IPs dentro de um critério de uma subrede específica (o que ele gera com a opção -iR é um IP a partir de todo o endereçamento IP disponível na Internet). Ou seja, mãos a obra!
Aí desenvolvi um script para atender a minha necessidade baseado num artigo que vi no blog do Chad Bibler intitulado Generating a Random, Valid IP Address in Subnet in Python (http://dregsoft.com/blog/?p=24). Meu script randomip.py ficou assim:
#!/usr/bin/env python import socket import struct import random import math import sys def get_max_ips( netmask_length, random_ips ): # define maximum number of IP addresses to be generated netmask_ips = int( math.pow( 2, 32-netmask_length ) ) if ( netmask_ips < random_ips ): winner = int( math.pow( 2, 32-netmask_length ) ) else: winner = random_ips return winner def get_random_ip_in_subnet( ip, netmask_length ): # thanks to Chad Bibler, http://dregsoft.com/blog/?p=24 # change the IP address into its bytes so we can add a number to it n = socket.inet_aton( ip ) ip_bytes = struct.unpack( '!i', n )[0] # we use the netmask_length to get a range of numbers we can add to the IP address max_to_add = int( math.pow( 2, 32-netmask_length ) ) to_add = random.randrange( 0, max_to_add ) ip_bytes += to_add # pack it back up and_back = struct.pack( '!i', ip_bytes ) new_ip = socket.inet_ntoa( and_back ) return new_ip if ( len(sys.argv) != 4 ): print "Command syntax: " print " python randomip.py<# of random IPs from subnet>" print "" print " example: python randomip.py 192.168.0.0 20 100" else: iplist={} max_ips=get_max_ips(int(sys.argv[2]),int(sys.argv[3])) for x in range(0, max_ips): ip=get_random_ip_in_subnet( sys.argv[1], int(sys.argv[2])) while(iplist.has_key(ip)): ip=get_random_ip_in_subnet( sys.argv[1], int(sys.argv[2])) iplist[ip]=1 print ip
Na prática o meu a minha varredura TCP para escolher 1000 endereços IP dentro da subrede 172.16.0.0/12 ficou assim:
python randomip.py 172.16.0.0 12 1000 | nmap -v -n --open -sS -iL - -oA nmap_out
Podem utilizar o script livremente e sugiro para quem quiser se aventurar no desenvolvimento do script três melhorias:
- Fazer com que o script em randomip.py aceite um arquivo de entrada com vários blocos IP (para o caso de subredes descontínuas)
- Fazer com que o script aceite como parâmetro um ASN (autonomous system). Neste caso ele sortearia os IP baseados neste ASN ou lista de ASNs (os blocos IP deste ASN poderiam ser recuperados a partir de site da ripe.net ou de alguma informação de BGP externa).
- Fazer com que o script aceite como parâmetro a sigla de um país (por exemplo sortear IPs que sejam somente da China). A lista poderia ser recuperada de sites como ipdeny.com