O que Todo Dev Deve Saber sobre Metodologia de Pentest: Fases, Regras de Engajamento e Relatórios Já leu

Introdução à Metodologia de Pentest Penetration Testing, ou Pentest, é o processo de avaliação de segurança onde um profissional autorizado simula ataques contra um sistema, aplicação ou infraestrutura para identificar vulnerabilidades antes que atacantes maliciosos o façam. Diferente de testes de segurança passivos, o Pentest é agressivo e intencional, buscando explorar falhas reais que poderiam ser exploradas por agentes maliciosos. A metodologia estruturada garante que o teste seja completo, documentado e alinhado com os objetivos do cliente. Uma das razões pelas quais a metodologia é crucial é simples: testes desordenados geram resultados incompletos, expõem riscos desnecessários e frequentemente violam a lei. Ao seguir um framework estabelecido — como OWASP, PTES (Penetration Testing Execution Standard) ou NIST — você garante que cada fase seja executada de forma controlada, rastreável e com valor real para a organização testada. Fases da Metodologia de Pentest Fase 1: Reconhecimento e Coleta de Informações O reconhecimento é a fundação de qualquer Pentest bem-sucedido. Nesta fase, você

Introdução à Metodologia de Pentest

Penetration Testing, ou Pentest, é o processo de avaliação de segurança onde um profissional autorizado simula ataques contra um sistema, aplicação ou infraestrutura para identificar vulnerabilidades antes que atacantes maliciosos o façam. Diferente de testes de segurança passivos, o Pentest é agressivo e intencional, buscando explorar falhas reais que poderiam ser exploradas por agentes maliciosos. A metodologia estruturada garante que o teste seja completo, documentado e alinhado com os objetivos do cliente.

Uma das razões pelas quais a metodologia é crucial é simples: testes desordenados geram resultados incompletos, expõem riscos desnecessários e frequentemente violam a lei. Ao seguir um framework estabelecido — como OWASP, PTES (Penetration Testing Execution Standard) ou NIST — você garante que cada fase seja executada de forma controlada, rastreável e com valor real para a organização testada.

Fases da Metodologia de Pentest

Fase 1: Reconhecimento e Coleta de Informações

O reconhecimento é a fundação de qualquer Pentest bem-sucedido. Nesta fase, você coleta informações sobre o alvo sem tentar explorar nada — apenas mapeia o que está lá. Isso inclui identificar domínios, servidores, funcionários, tecnologias usadas e potenciais pontos de entrada. Existem duas abordagens: Passive Reconnaissance (sem contato direto) e Active Reconnaissance (com tráfego direto ao alvo).

Durante a fase passiva, ferramentas como WHOIS, DNS recon e busca em mecanismos de busca revelam informações públicas. Na fase ativa, ferramentas como Nmap começam a sondar a infraestrutura. Um exemplo prático usando Python com a biblioteca socket:

import socket

def reconhecer_hosts(dominio):
    """Coleta informações básicas de DNS e resolução IP"""
    try:
        # Resolve o domínio para IP
        ip = socket.gethostbyname(dominio)
        print(f"Domínio: {dominio}")
        print(f"IP Resolvido: {ip}")

        # Tenta fazer reverse DNS
        hostname, aliaslist, ipaddrlist = socket.gethostbyaddr(ip)
        print(f"Hostname Reverso: {hostname}")
        print(f"IPs Associados: {ipaddrlist}")
    except socket.gaierror as e:
        print(f"Erro na resolução: {e}")
    except socket.herror as e:
        print(f"Erro no reverse DNS: {e}")

# Uso
reconhecer_hosts("google.com")

Este código simples executa o reconhecimento passivo. Na prática, você complementaria com Nmap para escanear portas abertas (nmap -sV target.com), ferramentas OSINT para e-mails e funcionários, e análise de tecnologias web.

Fase 2: Varredura (Scanning) e Enumeração

Após mapear o perímetro, você executa varreduras ativas para identificar serviços rodando, versões de software e portas abertas. Esta fase é onde você começa a produzir "barulho" detectável — por isso é crítica a validação prévia das regras de engajamento. A enumeração vai além de simplesmente abrir conexões: você interage com serviços para extrair banners, versões e configurações.

Usando Python com a biblioteca nmap (pyNmap), você pode automatizar varreduras de forma controlada:

import nmap

def escanear_portas(host, argumentos='-sV -sC -p-'):
    """
    Escaneia um host usando Nmap.
    -sV: Detecção de versão
    -sC: Scripts padrão
    -p-: Todas as portas
    """
    nm = nmap.PortScanner()
    print(f"Iniciando scan em {host}...")
    nm.scan(host, arguments=argumentos)

    # Analisa resultados
    for host_encontrado in nm.all_hosts():
        print(f"\nHost: {host_encontrado}")
        print(f"Status: {nm[host_encontrado].state()}")

        for proto in nm[host_encontrado].all_protocols():
            print(f"Protocolo: {proto}")
            puertos = nm[host_encontrado][proto].keys()

            for port in puertos:
                state = nm[host_encontrado][proto][port]['state']
                name = nm[host_encontrado][proto][port].get('name', 'unknown')
                version = nm[host_encontrado][proto][port].get('version', 'unknown')
                print(f"  Porta {port}: {state} | Serviço: {name} | Versão: {version}")

# Uso (requer Nmap instalado)
# escanear_portas("192.168.1.1")

Durante essa fase você também mapeia serviços como SMB, HTTP, SSH, etc., buscando banners que revelam versões vulneráveis. O objetivo é criar uma lista completa de alvos potenciais para a próxima fase.

Fase 3: Análise de Vulnerabilidades

Com a superfície de ataque mapeada, você agora busca identificar vulnerabilidades específicas. Isso inclui pesquisar CVEs (Common Vulnerabilities and Exposures) para versões identificadas, testar configurações inseguras e procurar por fraquezas lógicas. Ferramentas como OpenVAS, Qualys e Nessus automatizam esse processo, mas entender manualmente o que procurar é crucial.

Um exemplo de como verificar uma vulnerabilidade conhecida — como o CVE-2021-3129 em Laravel (Remote Code Execution via debug mode):

import requests
import json

def verificar_laravel_debug(url):
    """
    Verifica se uma aplicação Laravel está com debug mode ativo.
    Isso é uma vulnerabilidade crítica (RCE).
    """
    # Tenta acessar o arquivo config em cache (informação sensível)
    response = requests.get(f"{url}/_debugbar/cache", verify=False)

    if response.status_code == 200:
        print("[!] VULNERABILIDADE ENCONTRADA: Debug mode ativo!")
        print(f"Response: {response.text[:200]}")
        return True

    # Tenta outro endpoint que vaza informações com debug ativo
    response = requests.get(f"{url}/telescope", verify=False)
    if response.status_code == 200:
        print("[!] VULNERABILIDADE: Laravel Telescope exposto!")
        return True

    print("[+] Debug mode não detectado (ou está protegido)")
    return False

# Uso
# verificar_laravel_debug("http://target.local")

Nesta fase, você documenta cada vulnerabilidade encontrada com seu nível de severidade, impacto potencial e possível remediação. A severidade deve ser classificada usando o CVSS (Common Vulnerability Scoring System).

Fase 4: Exploração

A exploração é onde você demonstra o impacto real das vulnerabilidades. Não é apenas "encontrar" uma falha — é provar que ela pode ser explorada para ganhar acesso, extrair dados ou causar dano. Esta é a fase mais sensível e requer os maiores cuidados com as regras de engajamento. Você só explora vulnerabilidades que foram explicitamente aprovadas pelo cliente.

Um exemplo prático de exploração de uma SQL Injection simples em uma aplicação web:

import requests
from urllib.parse import quote

def testar_sql_injection(url, parametro, payload_base="' OR '1'='1"):
    """
    Testa SQL Injection básica em um parâmetro.
    Exemplo: http://target.com/search.php?q=AQUI
    """
    # Constrói a URL com o payload
    payload = f"{payload_base}"
    params = {parametro: payload}

    try:
        response = requests.get(url, params=params, timeout=5)

        # Indicadores de sucesso (muito básico, real seria mais sofisticado)
        if "unexpected token" in response.text.lower() or len(response.text) > 50000:
            print(f"[!] Possível SQL Injection detectada!")
            print(f"Payload: {payload}")
            print(f"Response preview: {response.text[:300]}")
            return True
        else:
            print("[+] Nenhuma indicação de SQL Injection")
            return False

    except requests.RequestException as e:
        print(f"Erro na requisição: {e}")
        return False

# Uso
# testar_sql_injection("http://target.local/search.php", "q")

A exploração deve ser cuidadosa: mude dados de teste sem afetar dados reais, mantenha logs de tudo que fez, e recue imediatamente se começar a causar impacto não autorizado.

Fase 5: Pós-Exploração e Análise

Após explorar com sucesso uma vulnerabilidade, você entra na fase de pós-exploração, onde busca aprofundar o acesso, escalbar privilégios, mover-se lateralmente pela rede ou extrair dados sensíveis. O objetivo é demonstrar o impacto completo de uma cadeia de exploração realista.

Nesta fase você também documenta:
- Comandos executados
- Dados acessados
- Mudanças feitas (se houver)
- Evidências de comprometimento

Um exemplo simples de enumeração após ganhar shell em um sistema Linux:

import subprocess
import platform

def enumerar_sistema():
    """
    Enumeração básica pós-exploração em Linux/Unix.
    Obtém informações do sistema comprometido.
    """
    if platform.system() != "Linux":
        print("Este script foi feito para Linux")
        return

    comandos = {
        "ID do Usuário": "id",
        "Sudoers": "sudo -l 2>/dev/null",
        "Kernel": "uname -a",
        "Processos Rodando": "ps aux | head -20",
        "Conexões Abertas": "netstat -tuln 2>/dev/null || ss -tuln",
        "Arquivos no Home": "ls -la ~",
        "Variáveis de Ambiente": "env"
    }

    for descricao, comando in comandos.items():
        print(f"\n===== {descricao} =====")
        try:
            resultado = subprocess.run(comando, shell=True, capture_output=True, text=True, timeout=5)
            print(resultado.stdout if resultado.stdout else resultado.stderr)
        except subprocess.TimeoutExpired:
            print(f"Comando expirou: {comando}")
        except Exception as e:
            print(f"Erro: {e}")

# Uso (apenas em ambientes autorizados!)
# enumerar_sistema()

Regras de Engajamento (Rules of Engagement)

Importância e Escopo

As Regras de Engajamento (RoE) são o documento legal e técnico que define exatamente o que você pode e não pode fazer durante um Pentest. Sem isso, você está operando cegamente e pode cometer crimes inadvertidamente. O RoE estabelece o escopo técnico (quais sistemas testar), escopo legal (qual jurisdição, leis aplicáveis), métodos permitidos (tipos de teste), dados que podem ser tocados e janelas de tempo.

Um RoE bem definido protege tanto o testador quanto o cliente. Deve ser assinado por ambas as partes antes de qualquer trabalho começar. Qualquer desvio do escopo aprovado é uma violação contratual e potencialmente uma violação legal.

Elementos Essenciais de um RoE

Um RoE profissional contém:

  • Escopo Técnico: Quais IPs, domínios, aplicações serão testados; quais estão fora do escopo
  • Período de Teste: Datas, horários específicos (não teste em plena produção sem aviso)
  • Métodos Proibidos: O que absolutamente não fazer (ex: DoS, modificar dados, remover arquivos)
  • Métodos Permitidos: Quais técnicas podem ser usadas (ex: phishing, força bruta, exploração de código)
  • Contatos de Emergência: Número para parar o teste imediatamente se algo der errado
  • Dados Sensíveis: Como lidar com dados encontrados (criptografar relatórios, descartar cópias)
  • Limitações: Não tocar em sistemas críticos de pacientes, sistemas financeiros não autorizados, etc.
  • Liabilidade e Indenização: Quem é responsável por danos acidentais

Um template básico seria:

RULES OF ENGAGEMENT - PENTEST

Cliente: Acme Corp
Testador: João da Segurança
Data: 15 de Janeiro a 20 de Janeiro de 2024

ESCOPO TÉCNICO:
✓ Incluído:
  - Domínio: acmecorp.com.br (todos os subdomínios)
  - IPs: 192.168.1.0/24
  - Aplicação Web: portal.acmecorp.local
  - Testes de Engenharia Social: E-mail phishing (pré-aprovado)

✗ Excluído:
  - Sistema de Backup (192.168.100.0/24)
  - Banco de Dados de Produção (toques leitura apenas)
  - Dados de Pacientes/PII (não extrair/armazenar)
  - Infraestrutura de Telecomunicações

MÉTODOS:
✓ Permitido:
  - Network scanning (Nmap)
  - Exploit de vulnerabilidades conhecidas (CVEs)
  - Testes de autenticação
  - Brute force em contas de teste (não contas reais)

✗ Proibido:
  - Denial of Service (DoS/DDoS)
  - Modificação de dados em produção
  - Violação física de propriedade
  - Qualquer atividade fora do período aprovado

CONTATOS DE EMERGÊNCIA:
- PARAR TESTE: gerente.ti@acmecorp.com.br / +55 11 98765-4321
- Resposta desejada em: 15 minutos máximo

RESPONSABILIDADE:
- Testador indeniza danos causados por desvio do escopo
- Cliente aceita riscos inerentes ao pentest

Assinado:
___________________  ___________________
Cliente             Testador
Data: ___________    Data: ___________

Elaboração de Relatórios Profissionais

Estrutura e Objetivos do Relatório

O relatório é o produto final do Pentest e deve comunicar claramente para públicos diferentes: executivos, gerentes de TI e desenvolvedores. Não é suficiente dizer "encontrei 50 vulnerabilidades" — você precisa contextualizar cada uma, explicar o impacto e propor remediação prática. Um bom relatório transforma achados técnicos em decisões de negócio.

A estrutura típica de um relatório profissional inclui:

  1. Executive Summary (1-2 páginas): Achados críticos, impacto de negócio, recomendações de alto nível
  2. Metodologia: Como o teste foi conduzido, ferramentas usadas, período
  3. Achados Detalhados: Cada vulnerabilidade com evidências, severidade, remediação
  4. Evidências Técnicas: Screenshots, logs, outputs de ferramentas
  5. Recomendações: Plano de ação priorizado
  6. Conclusões: Postura de segurança geral

Exemplo de Relatório Estruturado

Aqui um exemplo em Python que gera um relatório automatizado em HTML:

from datetime import datetime
from enum import Enum

class Severidade(Enum):
    CRITICA = 5
    ALTA = 4
    MEDIA = 3
    BAIXA = 2
    INFORMACAO = 1

class Vulnerabilidade:
    def __init__(self, titulo, severidade, descricao, impacto, remediacao, evidencia=""):
        self.titulo = titulo
        self.severidade = severidade
        self.descricao = descricao
        self.impacto = impacto
        self.remediacao = remediacao
        self.evidencia = evidencia
        self.data_encontrada = datetime.now().strftime("%d/%m/%Y %H:%M")

class RelatorioPentest:
    def __init__(self, cliente, testador, data_inicio, data_fim):
        self.cliente = cliente
        self.testador = testador
        self.data_inicio = data_inicio
        self.data_fim = data_fim
        self.vulnerabilidades = []
        self.resumo_executivo = ""

    def adicionar_vulnerabilidade(self, vuln):
        self.vulnerabilidades.append(vuln)

    def gerar_html(self, caminho_saida="relatorio.html"):
        """Gera relatório em HTML formatado"""

        # Ordena por severidade
        vulns_ordenadas = sorted(self.vulnerabilidades, 
                                key=lambda x: x.severidade.value, 
                                reverse=True)

        # Conta por severidade
        contagemPorSeveridade = {}
        for severidade in Severidade:
            contagemPorSeveridade[severidade.name] = len([v for v in vulns_ordenadas if v.severidade == severidade])

        html = f"""
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Relatório de Pentest - {self.cliente}</title>
    <style>
        body {{ font-family: Arial, sans-serif; margin: 20px; color: #333; }}
        .header {{ background: #1a1a2e; color: white; padding: 20px; border-radius: 5px; }}
        .summary {{ background: #f0f0f0; padding: 15px; margin: 20px 0; border-left: 4px solid #d9534f; }}
        .vulnerabilidade {{ margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }}
        .critica {{ border-left: 4px solid #d9534f; background: #fff5f5; }}
        .alta {{ border-left: 4px solid #f0ad4e; background: #fffaf0; }}
        .media {{ border-left: 4px solid #5bc0de; background: #f0f9fc; }}
        .baixa {{ border-left: 4px solid #5cb85c; background: #f5fff5; }}
        .informacao {{ border-left: 4px solid #999; background: #f9f9f9; }}
        .titulo-vulner {{ font-size: 18px; font-weight: bold; margin-bottom: 10px; }}
        .severidade {{ display: inline-block; padding: 5px 10px; border-radius: 3px; color: white; font-weight: bold; }}
        .sev-critica {{ background: #d9534f; }}
        .sev-alta {{ background: #f0ad4e; }}
        .sev-media {{ background: #5bc0de; }}
        .sev-baixa {{ background: #5cb85c; }}
        .sev-info {{ background: #999; }}
        .stats {{ display: flex; gap: 20px; margin: 20px 0; }}
        .stat-box {{ background: white; border: 1px solid #ddd; padding: 15px; border-radius: 5px; text-align: center; }}
        .stat-numero {{ font-size: 32px; font-weight: bold; }}
        pre {{ background: #f5f5f5; padding: 10px; overflow-x: auto; }}
    </style>
</head>
<body>
    <div class="header">
        <h1>Relatório de Penetration Testing</h1>
        <p><strong>Cliente:</strong> {self.cliente}</p>
        <p><strong>Testador:</strong> {self.testador}</p>
        <p><strong>Período:</strong> {self.data_inicio} a {self.data_fim}</p>
        <p><strong>Data do Relatório:</strong> {datetime.now().strftime("%d/%m/%Y")}</p>
    </div>

    <h2>Resumo Executivo</h2>
    <div class="summary">
        <p>Este Pentest identificou <strong>{len(vulns_ordenadas)} vulnerabilidades</strong> na infraestrutura testada.</p>
        <div class="stats">
            <div class="stat-box">
                <div class="stat-numero" style="color: #d9534f;">{contagemPorSeveridade['CRITICA']}</div>
                <div>Críticas</div>
            </div>
            <div class="stat-box">
                <div class="stat-numero" style="color: #f0ad4e;">{contagemPorSeveridade['ALTA']}</div>
                <div>Altas</div>
            </div>
            <div class="stat-box">
                <div class="stat-numero" style="color: #5bc0de;">{contagemPorSeveridade['MEDIA']}</div>
                <div>Médias</div>
            </div>
            <div class="stat-box">
                <div class="stat-numero" style="color: #5cb85c;">{contagemPorSeveridade['BAIXA']}</div>
                <div>Baixas</div>
            </div>
        </div>
        <p><strong>Recomendação:</strong> Todas as vulnerabilidades críticas e altas devem ser remediadas em até 30 dias.</p>
    </div>

    <h2>Vulnerabilidades Encontradas</h2>
"""

        for i, vuln in enumerate(vulns_ordenadas, 1):
            classe_severidade = vuln.severidade.name.lower()
            html += f"""
    <div class="vulnerabilidade {classe_severidade}">
        <div class="titulo-vulner">
            {i}. {vuln.titulo}
            <span class="severidade sev-{classe_severidade}">{vuln.severidade.name}</span>
        </div>

        <h4>Descrição:</h4>
        <p>{vuln.descricao}</p>

        <h4>Impacto de Negócio:</h4>
        <p>{vuln.impacto}</p>

        <h4>Remediação Recomendada:</h4>
        <p>{vuln.remediacao}</p>

        <h4>Data Encontrada:</h4>
        <p>{vuln.data_encontrada}</p>
"""
            if vuln.evidencia:
                html += f"""
        <h4>Evidência Técnica:</h4>
        <pre>{vuln.evidencia}</pre>
"""
            html += "    </div>\n"

        html += """
    <hr>
    <p><strong>Documento Confidencial - Restrito ao Cliente</strong></p>
    <p>Este relatório contém informações sensíveis sobre vulnerabilidades de segurança e deve ser protegido adequadamente.</p>
</body>
</html>
"""

        with open(caminho_saida, 'w', encoding='utf-8') as f:
            f.write(html)

        print(f"Relatório gerado: {caminho_saida}")

# Uso prático
if __name__ == "__main__":
    # Criar relatório
    relatorio = RelatorioPentest("Acme Corp", "João Silva", "15/01/2024", "20/01/2024")

    # Adicionar vulnerabilidades
    relatorio.adicionar_vulnerabilidade(Vulnerabilidade(
        titulo="SQL Injection em Formulário de Login",
        severidade=Severidade.CRITICA,
        descricao="A aplicação não sanitiza entrada de usuário no campo 'email' do formulário de login, permitindo SQL injection.",
        impacto="Um atacante pode acessar dados de todos os usuários, modificar permissões ou deletar registros no banco de dados.",
        remediacao="Implementar prepared statements (parametrized queries) em todas as queries de banco de dados. Use ORMs como SQLAlchemy.",
        evidencia="Payload: ' OR '1'='1\nResposta: Acesso concedido para user_id=1 (administrador)"
    ))

    relatorio.adicionar_vulnerabilidade(Vulnerabilidade(
        titulo="Senhas Padrão em Serviço SSH",
        severidade=Severidade.ALTA,
        descricao="O servidor SSH está usando credenciais padrão (admin:admin) no sistema de backup.",
        impacto="Um atacante com acesso à rede pode ganhar acesso ao servidor e copiar todos os backups.",
        remediacao="Altere a senha do usuário 'admin' para uma senha forte e única. Implemente autenticação por chave SSH.",
        evidencia="SSH 192.168.1.10 - Login bem-sucedido com admin:admin"
    ))

    relatorio.adicionar_vulnerabilidade(Vulnerabilidade(
        titulo="Informação Sensível em Comentários HTML",
        severidade=Severidade.BAIXA,
        descricao="Comentários HTML contêm nomes de desenvolvedores, IPs internos e tecnologias usadas.",
        impacto="Exposição de informações que podem ser usadas em ataques direcionados.",
        remediacao="Remova comentários sensíveis de código antes de deployment. Use minificação automática.",
        evidencia="<!-- API backend rodando em 10.0.0.5:8080 - Desenvolvido por Carlos -->"
    ))

    # Gerar HTML
    relatorio.gerar_html("relatorio_pentest.html")

Este código gera um relatório HTML profissional com visualização clara de cada vulnerabilidade, agrupada por severidade e com evidências técnicas.

Boas Práticas na Redação

Ao escrever um relatório, lembre-se que:

  • Linguagem Clara: Evite jargão técnico desnecessário. Se usar, explique.
  • Prova Concreta: Cada achado deve ter evidência — screenshot, log, output de ferramenta.
  • Remediação Prática: Não diga "corrija a vulnerabilidade". Diga "implemente validação de entrada com regex pattern ^[a-zA-Z0-9@.]{1,50}$".
  • Priorização: Vulnerabilidades críticas no topo. Recomende plano de ação com prazos.
  • Confidencialidade: Marque como "Confidencial", armazene criptografado, destrua rascunhos e logs após entregar.

Conclusão

Ao longo deste artigo, cobrimos três pilares essenciais da metodologia de Pentest profissional. Primeiro, as cinco fases estruturadas — reconhecimento, varredura, análise, exploração e pós-exploração — garantem cobertura completa do escopo sem deixar brechas. Cada fase construi sobre a anterior, transformando informações em descobertas tangíveis. Segundo, as Regras de Engajamento são o contrato que protege legalmente ambas as partes e define exatamente onde e como você pode testar — negligenciar isso é negligência profissional. Terceiro, o relatório não é um documento técnico desconectado da realidade; é uma ferramenta de persuasão que converte achados em decisões executivas de negócio, por isso deve ser claro, priorizado e acionável.

Domine essas três áreas e você terá a base de um Pentester profissional. A prática vem com o tempo, mas a metodologia é o que diferencia um testador amador de um profissional reconhecido.

Referências


Artigos relacionados