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")