Tenta encontrar pastas ocultas como /admin ou /config.

Contexto

Muitas vezes, desenvolvedores deixam pastas e arquivos sensíveis acessíveis no servidor, mas sem links diretos na página principal. O objetivo deste módulo é realizar um ataque de dicionário (força bruta baseada em lista) contra o servidor web para descobrir diretórios ocultos.

Exemplos de alvos comuns:

  • Painéis de controle: /admin, /phpmyadmin, /controlpanel.
  • Arquivos de configuração/Backup: /config.php.bak, /.env, /.git.
  • Pastas de desenvolvimento: /dev, /test, /old_version.

Possibilidades de Implementação

  • Análise de Status Code: O script foca no código de resposta HTTP. 200 OK significa que o arquivo existe; 403 Forbidden indica que a pasta existe mas o acesso é restrito; 404 Not Found significa que não existe.
  • Multithreading: Testar milhares de palavras sequencialmente é inviável. O uso de threads permite que o Python faça centenas de requisições por segundo.
  • Recursive Discovery: Se o script encontrar uma pasta (ex: /uploads), ele pode iniciar uma nova busca dentro dela (/uploads/images, etc.).

Código

Este módulo utiliza requests para as conexões e concurrent.futures para processamento paralelo, garantindo que o scanner seja rápido o suficiente para wordlists reais.

import requests
from concurrent.futures import ThreadPoolExecutor

# --- CONFIGURAÇÕES DO MÓDULO ---
TARGET_URL = "http://testphp.vulnweb.com/"  # URL alvo (deve terminar com /)
THREADS = 20                                # Velocidade do ataque

# Wordlist reduzida para exemplo (em uso real, carregaria um arquivo .txt)
WORDLIST = [
    "admin", "login", "config", "backup", "db", 
    "setup", "shell", "js", "css", "uploads", 
    "phpmyadmin", ".env", ".git", "test", "api"
]

def request_dir(directory):
    """
    Tenta acessar um diretório e analisa o código de status retornado.
    """
    url = f"{TARGET_URL}{directory}"

    try:
        # allow_redirects=False evita que o script siga para páginas de erro customizadas
        response = requests.get(url, timeout=3, allow_redirects=False)

        # 200 = Sucesso, 403 = Protegido, 301/302 = Redirecionamento
        if response.status_code == 200:
            print(f"[+] ENCONTRADO: /{directory:15} | Status: 200 OK")
        elif response.status_code == 403:
            print(f"[-] PROTEGIDO: /{directory:15} | Status: 403 Forbidden")
        elif response.status_code in [301, 302]:
            print(f"[*] REDIRECT : /{directory:15} | Status: {response.status_code}")

    except requests.exceptions.RequestException:
        pass

def main():
    print("=" * 60)
    print("Módulo: Directory Buster | Projeto: 30 Lessons in Python")
    print("=" * 60)
    print(f"[*] Alvo: {TARGET_URL}")
    print(f"[*] Testando {len(WORDLIST)} caminhos com {THREADS} threads...\n")

    # Execução paralela das requisições
    with ThreadPoolExecutor(max_workers=THREADS) as executor:
        executor.map(request_dir, WORDLIST)

    print("\n" + "=" * 60)
    print("[*] Scan de diretórios finalizado.")

if __name__ == "__main__":
    main()

Observações

  • User-Agent: Muitos servidores bloqueiam o User-Agent padrão do requests. Em versões mais robustas, você deve adicionar um cabeçalho que simule um navegador real (Chrome/Firefox).
  • Falsos Positivos (Wildcards): Alguns servidores são configurados para retornar 200 OK para qualquer página (página de erro customizada). O script precisaria validar se o conteúdo retornado é realmente o que se busca.
  • Wordlists Profissionais: Para o seu projeto, recomendo mencionar que este script deve ser usado com listas como a SecLists ou a Common.txt do DIRB.