Busca subdomínios via força bruta ou APIs (como Shodan).
Contexto
No ciclo de um Pentest, a Enumeração de Subdomínios faz parte da fase de Reconhecimento Ativo. O objetivo é descobrir áreas da infraestrutura de uma empresa que não estão documentadas publicamente ou que foram esquecidas (Shadow IT).
Exemplo Real:
Uma empresa protege muito bem o www.alvo.com.br, mas esquece que o jira-dev.alvo.com.br está rodando uma versão antiga e vulnerável de um software de gestão. Encontrar esse subdomínio é a "chave" para entrar na red
Possibilidades de Implementação
Existem duas formas principais de fazer isso com Python:
- Brute Force (Dicionário): O script lê uma lista de nomes comuns (
www,mail,dev,ftp) e tenta resolver o DNS para cada um deles (ex:dev+.alvo.com). Se o DNS responder, o subdomínio existe. - Passive Recon (APIs): Consulta bases de dados externas como Shodan, Censys ou SecurityTrails. A vantagem é que você não "toca" o servidor do alvo, permanecendo invisível nos logs de rede.
Código
Esta implementação utiliza a biblioteca requests para validar se o subdomínio responde via Web (HTTP/S) e a biblioteca dns.resolver (do pacote dnspython) para validar a existência via DNS, o que é mais profissional.
Requisitos:
pip install dnspython requests
import dns.resolver
import requests
def sub_enumerator(target_domain, wordlist_file):
print(f"--- Iniciando Lição: Enumeração de {target_domain} ---")
try:
with open(wordlist_file, 'r') as file:
names = file.read().splitlines()
except FileNotFoundError:
print("Erro: Arquivo de wordlist não encontrado.")
return
for name in names:
subdomain = f"{name}.{target_domain}"
# 1. Tentativa via DNS (Mais rápido e abrange serviços não-web)
try:
answers = dns.resolver.resolve(subdomain, 'A')
for rdata in answers:
print(f"[DNS] Encontrado: {subdomain} -> IP: {rdata.address}")
# 2. Se o DNS existe, tentamos ver se há um servidor Web rodando
try:
url = f"http://{subdomain}"
response = requests.get(url, timeout=1)
print(f" [WEB] Status HTTP: {response.status_code}")
except requests.RequestException:
pass # Existe DNS, mas não é um servidor Web
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
# Subdomínio não existe
continue
except Exception as e:
continue
# Uso:
# sub_enumerator("google.com", "lista_curta.txt")