CVE-2025-59287 (WSUS — Windows Server Update Services) zafiyeti
Ekim 2025'te ortaya çıkan CVE-2025-59287, Microsoft’un Windows Server Update...
 
        Enterprise ortamında bir pazartesi sabahı:
adminCount=1 ile işaretlenmiş!"Active Directory (AD) ile ilgili en yaygın hatalardan biri, yönetim delegasyonunun güvensiz ve kaotik yapılması, bunun sonucunda:
adminCount, Active Directory'de bir hesabın veya bilgisayarın Protected Groups (Korunan Gruplar) içinde bulunup bulunmadığını gösteren bir boolean flag'idir.
adminCount = 1  ➜  Bu nesne korumalı grup üyesi (veya olmuş) demektir
adminCount = 0  ➜  Bu nesne korumalı grup üyesi değil
Active Directory, aşağıdaki grupları otomatik olarak korur:
| Grup | RID | Açıklama | 
|---|---|---|
| Domain Admins | 512 | Etki alanı yöneticileri (çoğu zaman kötü amaçlı hedef) | 
| Enterprise Admins | 519 | Orman yöneticileri (Tier 0 erişim) | 
| Schema Admins | 518 | Şema değişikliği yetkisi (çok tehlikeli) | 
| Account Operators | 548 | Kullanıcı/grup yönetimi (yerel gruplara erişebilir) | 
| Backup Operators | 551 | Yedekleme ve geri yükleme yetkisi | 
| Print Operators | 550 | Yazıcı yönetimi | 
| Server Operators | 549 | Sunucu yönetimi (yerel) | 
| Replicator | 552 | Replikasyon (nadiren kullanılır) | 
Active Directory, SDProp adlı bir arka plan işlemi çalıştırır:
   SDProp Döngüsü (Her 3600 sn)      
 1. Korunan grupları tarar           
 2. Üyeleri tespit eder              
 3. adminCount=1 atanır              
 4. AdminSDHolder ACL'ini kopyalar   
 5. Üyelerin Permission'ını günceller
SENARYO 1: Grup Üyesi Ekleme (Doğru Davranış)
─────────────────────────────────────────
User1 ➜ (Domain Admins'e eklenir) ➜ adminCount=1 otomatik atanır
User1 ➜ (Domain Admins'den çıkarılır) ➜ adminCount AYNEN KALIR 
SENARYO 2: Grup Üyesi Çıkarma (SİZİN İŞİNİZ!)
─────────────────────────────────────────
User1'in adminCount=1 kaldırılması için ➜ El ile `Set-ADObject -Clear adminCount` çalıştırmanız gerekir!
SENARYO 3: Korunan Gruba Doğrudan Üye Ekleme (Hata!)
─────────────────────────────────────────
Grup1 ➜ (Domain Admins'in nesne üyesi olmuş) ➜ adminCount=1 + ACL koruması ➜ O grupta herkes korunuyor!# Tüm adminCount=1 olan kullanıcıları listele
Get-ADUser -LDAPFilter "(adminCount=1)" -Properties adminCount, MemberOf | 
    Select-Object Name, adminCount, @{
        L='Gruplar'; 
        E={($_.MemberOf | ForEach-Object {$_ -replace '^CN=|,.*$'}) -join ', '}
    }
# Çıktı Örneği:
# Name          adminCount    Gruplar
# ─────────────────────────────────────
# Admin1        1             Domain Admins, Enterprise Admins
# User2         1             (boş - ORFANlanmış!)
# ServiceAcc1   1             (boş - ORFANlanmış!)
# SORULU ZAMAN ÇİZELGESİ
─────────────────────────────────────────
T=0     : User ➜ Domain Admins'e eklenir ➜ adminCount=1 atanır
T=1 gün : User ➜ Domain Admins'den çıkarılır ➜ adminCount AYNEN 1 kalır!
T=30 gün: Denetçi raporunda User hâlâ "admin" olarak görünüyor
T=60 gün: Hiç kimse bunun fark etmediğine güveniyor
T=∞     : Yeni denetçi raporunda "500+ gizli yönetici var!" yazıyor
AdminSDHolder, Active Directory'de CN=AdminSDHolder,CN=System konumunda bulunan orman düzeyinde bir container'dır. Bu nesnenin ACL'i (Access Control List), tüm korunan grup üyelerine otomatik olarak uygulanır.
    AdminSDHolder Container         
    (CN=System,DC=contoso,DC=com)    
  ACL (Erişim Kontrol Listesi):      
  ├─ SYSTEM: FullControl            
  ├─ CREATOR OWNER: FullControl     
  ├─ Domain Admins: FullControl     
  └─ Enterprise Admins: FullControl 
⬇ (Her 3600 sn kopyalanır)
    Domain Admins Group               
    (Üye: Admin1, Admin2, ...)        
# AdminSDHolder'ın ACL'ini görüntüle
$AdminSD = Get-ADObject -Identity "CN=AdminSDHolder,CN=System,DC=contoso,DC=com" -Properties ntSecurityDescriptor
$AdminSD.ntSecurityDescriptor.Access | Format-Table IdentityReference, ActiveDirectoryRights, AccessControlType -AutoSize
# Çıktı Örneği:
# IdentityReference              ActiveDirectoryRights                    AccessControlType
# ─────────────────────────────────────────────────────────────────────────────────────────
# NT AUTHORITY\SYSTEM            FullControl                              Allow
# BUILTIN\Administrators         FullControl                              Allow
# CONTOSO\Domain Admins          FullControl                              Allow
# CONTOSO\Enterprise Admins      FullControl                              Allow
Bir yönetici şöyle düşünüyor:
"Domain Admins grubu bize çok fazla yetki veriyor. Sadece belirli nesneleri yönetebilmeleri için ACL'ini düzelteyim."
# ❌ YANLIŞ YAP! ❌
$AdminSDPath = "CN=AdminSDHolder,CN=System,DC=contoso,DC=com"
$AdminSDObj = Get-ADObject -Identity $AdminSDPath
$ACL = Get-Acl "AD:\$AdminSDPath"
# ... ACL'den permission'ları kaldırır ...
Set-Acl -Path "AD:\$AdminSDPath" -AclObject $ACL
T=0     : ACL değiştirilir
T=5 min : SDProp çalışır, değişikliği geri yazmaya çalışır
T=10 min: Hatalı davranış ortaya çıkıyor:
          ├─ Domain Admins'lar birbirini yönetememaya başlar
          ├─ Policy uygulanmamaya başlar
          ├─ Yetkilendirme kontrolleri bozulur
          └─ Denetim izleri tutarsız hale gelir
T=∞     : Etki alanı düzeyinde uyum problemi
Kurallar:
Get-Acl kullanabilirsiniz# AdminSDHolder'ı OKUMAK (izin verilen)
Get-ADObject -Identity "CN=AdminSDHolder,CN=System,DC=contoso,DC=com" `
    -Properties ntSecurityDescriptor | 
    Select-Object -ExpandProperty ntSecurityDescriptor | 
    Select-Object -ExpandProperty Access
# Eğer kısıtlama istiyorsanız, bu şekilde yapın:
# ✅ OU Delegasyonu ile "Tier 2 Yöneticiler" grubu oluştur
# ✅ Bu gruba sadece belirli OU'daki nesneleri değiştir yetkisi ver
# ✅ AdminSDHolder'ı AYNEN BIRAK
Microsoft, AD ortamlarında güvenlik katmanlarını sınıflandırmıştır:
┌─────────────────────────────────────────────────────────────────┐
│                       TIER MODEL                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  TIER 0 (En Kritik - Çok Az Kişi)                              │
│  ├─ Enterprise Admins                                           │
│  ├─ Schema Admins                                               │
│  ├─ Domain Admins (kısıtlı)                                     │
│  └─ Kriti orman kurtarma hesapları                              │
│                                                                  │
│  ↕ (Tek yönlü güven - Tier 0 hiçbir şeye güvenmesin)           │
│                                                                  │
│  TIER 1 (Etki Alanı Yönetimi)                                   │
│  ├─ OU Yöneticileri                                             │
│  ├─ Grup Politikası Yöneticileri                                │
│  └─ Sunucu Yöneticileri (sınırlı)                               │
│                                                                  │
│  ↕ (Güven yönetilmeli)                                          │
│                                                                  │
│  TIER 2 (İş Birimi Yönetimi)                                    │
│  ├─ Yerel Yöneticiler                                           │
│  ├─ Uygulama Yöneticileri                                       │
│  └─ Destek Personeli (sınırlı)                                  │
│                                                                  │
│  ↕ (Geniş erişim, ancak yönetilmeli)                            │
│                                                                  │
│  TIER 3 (Son Kullanıcılar)                                      │
│  ├─ Standart Kullanıcılar                                       │
│  └─ Konuk Hesapları                                             │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
Amaç: Şema, orman yapısı, kritik yapılandırma
Kişi Sayısı: 2-3 (hatta 2 de az değildir!)
Gruplar:
Delegasyon Modeli:
┌──────────────────────────────────────┐
│  TIER 0 Delegasyon Akışı             │
├──────────────────────────────────────┤
│ 1. Değişiklik Talep Formu            │
│ 2. Üst Yönetim Onayı                 │
│ 3. 2 Kişi Aynı Anda Hazır (4 Göz)   │
│ 4. Değişiklik + Denetim Kaydı        │
│ 5. Test Ortamında Öncesi Simülasyon  │
│ 6. Raporlama (Zorunlu)               │
└──────────────────────────────────────┘
PowerShell Kontrol:
# TIER 0 üyelerini listele
$Tier0Groups = @('Administrators', 'Domain Admins', 'Enterprise Admins', 'Schema Admins')
foreach ($Group in $Tier0Groups) {
    Get-ADGroupMember -Identity $Group -Recursive | 
        Where-Object { $_.objectClass -eq 'user' } |
        Select-Object Name, samAccountName, @{L='Grup'; E={$Group}}
}
# Aylık rapor: TIER 0 değişiklikleri
Get-ADUser -LDAPFilter "(adminCount=1)" -Properties WhenChanged, LastLogonDate |
    Where-Object { $_.WhenChanged -gt (Get-Date).AddDays(-30) } |
    Select-Object Name, WhenChanged, LastLogonDate
Amaç: GPO, OU, Kullanıcı/Bilgisayar yönetimi
Kişi Sayısı: 5-10
Gruplar:
Delegasyon Modeli:
# TIER 1: OU Delegasyonu Örneği
─────────────────────────────────────
OU=Tier1_Servers,DC=contoso,DC=com
├─ Server1
├─ Server2
└─ Server3
# "Tier1_ServerAdmins" grubu sadece bu OU'da işlem yapabilir
# Delegasyon adımları:
1. Grup oluştur
   New-ADGroup -Name "Tier1_ServerAdmins" -GroupScope Global
2. OU'ya erişim ver (dışarıdan değil!)
   # GUI: Delegation of Control Wizard
   # veya
   dsacls.exe "OU=Tier1_Servers,DC=contoso,DC=com" `
       /G "CONTOSO\Tier1_ServerAdmins:CCCCDC"
3. PowerShell ile kontrol
   Get-ADUser -LDAPFilter "(memberOf=CN=Tier1_ServerAdmins,CN=Users,DC=contoso,DC=com)" `
       -Properties MemberOf | Select Name, MemberOf
Amaç: Yerel uygulama, grup yönetimi, hizmet hesapları
Kişi Sayısı: 20+
Gruplar:
Delegasyon Modeli:
# TIER 2: Grup ve Hizmet Hesabı Yönetimi
─────────────────────────────────────
# "Tier2_AppAdmins" grubu
# ├─ SharePoint_Admins grubunu yönetebilir
# ├─ App_ServiceAccounts OU'sunda hesap oluşturabilir
# └─ Kendi gruplarını yönetebilir (recursively yönetemesin!)
# OU Delegasyonu: Tier 2 için daha geniş izinler
$OU = "OU=Tier2_Applications,DC=contoso,DC=com"
$Group = "Tier2_AppAdmins"
# Delegasyon GUI aracı
# Delegated Tasks: User Accounts Creation, Modification
#                  Reset Password
#                  Group Management
# PowerShell ile doğrula
dsacls.exe $OU /G "CONTOSO\$Group:CCCCDA"
# ❌ YANLIŞ
Get-ADGroup -Identity "Account Operators" -Properties members |
    Select-Object -ExpandProperty members
# Sorun: Account Operators eski, standartlaştırılmamış ve kötü amaçlı hedef
# ✅ DOĞRU: Özel OU delegasyonu grup oluştur
New-ADGroup -Name "Tier1_UserAdmins" -GroupScope DomainLocal
# ❌ YANLIŞ
# TIER 2 admin'i doğrudan Domain Admins grubuna eklenir
Add-ADGroupMember -Identity "Domain Admins" -Members "CONTOSO\Tier2_Admin"
# ✅ DOĞRU
# TIER 2 admin'i, Tier 2 OU'sunda sınırlı yetkiye sahiptir
# TIER 1'de yardım isterse, bir ticket oluşturur ve TIER 1 admin tarafından yapılır
# ✅ DOĞRU YÖNETİM
# Delegasyon logu tut
$DelegationLog = @{
    Date = Get-Date
    Admin = $env:USERNAME
    Action = "Tier1_UserAdmins grubuna User5 eklendi"
    Reason = "Ticket #12345 - Yeni OU Yöneticisi"
    Approved = "Manager (email)"
}
# JSON olarak kaydet
$DelegationLog | ConvertTo-Json | Out-File -Path "C:\Logs\delegations_$(Get-Date -Format yyyyMM).json" -Append
# Script: AD_AdminCount_Report.ps1
$ReportPath = "C:\Reports\AD_AdminCount_$(Get-Date -Format yyyyMMdd).csv"
$Results = @()
# Tüm adminCount=1 nesneleri bul
$AdminUsers = Get-ADUser -LDAPFilter "(adminCount=1)" `
    -Properties adminCount, MemberOf, WhenChanged, LastLogonDate
foreach ($User in $AdminUsers) {
    $Groups = ($User.MemberOf | ForEach-Object {
        ($_ -split ',')[0] -replace 'CN='
    }) -join '; '
    
    $Results += [PSCustomObject]@{
        Name = $User.Name
        SamAccountName = $User.samAccountName
        adminCount = $User.adminCount
        Grup_Uyeligikleri = $Groups
        Son_Degistirilme = $User.WhenChanged
        Son_Giris = $User.LastLogonDate
        Aktif_Mi = if ($User.LastLogonDate -gt (Get-Date).AddDays(-30)) { "Evet" } else { "Hayir" }
    }
}
$Results | Export-Csv -Path $ReportPath -Encoding UTF8 -NoTypeInformation
Write-Host "Rapor: $ReportPath"
Kontrol Listesi:
# Script: Cleanup_adminCount.ps1
# ÖNEMLİ: Bu script'i çalıştırmadan ÖNCE
# 1. Backup al
# 2. Test ortamında dene
# 3. İş saati dışında çalıştır
function Remove-OrphanedAdminCount {
    param(
        [switch]$WhatIf
    )
    
    $AdminUsers = Get-ADUser -LDAPFilter "(adminCount=1)" `
        -Properties adminCount, MemberOf
    
    $ProtectedGroups = @(
        'Domain Admins',
        'Enterprise Admins',
        'Schema Admins',
        'Account Operators',
        'Backup Operators',
        'Print Operators',
        'Server Operators',
        'Replicator'
    )
    
    $Cleaned = 0
    
    foreach ($User in $AdminUsers) {
        # Kullanıcının korunan grup üyeliğini kontrol et
        $InProtectedGroup = $false
        
        foreach ($Group in $ProtectedGroups) {
            try {
                $GroupMembers = Get-ADGroupMember -Identity $Group -Recursive -ErrorAction Stop
                if ($GroupMembers | Where-Object { $_.objectGUID -eq $User.objectGUID }) {
                    $InProtectedGroup = $true
                    break
                }
            } catch {
                # Grup bulunamadı, devam et
            }
        }
        
        # Eğer korunan grupta değilse, adminCount'u kaldır
        if (-not $InProtectedGroup) {
            Write-Host "Temizleniyor: $($User.Name) (adminCount kaldırılacak)"
            
            if ($WhatIf) {
                Write-Host "  [PREVIEW] Set-ADObject -Identity $($User.DistinguishedName) -Clear adminCount"
            } else {
                Set-ADObject -Identity $User.DistinguishedName -Clear adminCount -Confirm:$false
                $Cleaned++
            }
        }
    }
    
    Write-Host "Toplam temizlenen: $Cleaned"
}
# Kullanım:
# 1. Önce WhatIf ile göz at
Remove-OrphanedAdminCount -WhatIf
# 2. Sonra gerçekten çalıştır
Remove-OrphanedAdminCount
Kontrol Listesi:
# Script: Audit_AdminSDHolder.ps1
function Audit-AdminSDHolder {
    $AdminSDPath = "CN=AdminSDHolder,CN=System,DC=$(($env:USERDNSDOMAIN -split '\.' | ForEach-Object { "DC=$_" }) -join ',')"
    
    Write-Host "AdminSDHolder Denetimi: $AdminSDPath" -ForegroundColor Green
    
    # 1. AdminSDHolder'ın ACL'ini oku
    $AdminSDObj = Get-ADObject -Identity $AdminSDPath -Properties nTSecurityDescriptor
    $ACL = $AdminSDObj.nTSecurityDescriptor
    
    Write-Host "`n=== ACL İçeriği ===" -ForegroundColor Cyan
    $ACL.Access | Format-Table @{
        L='Kimlik'; E={$_.IdentityReference}
    }, @{
        L='Haklar'; E={$_.ActiveDirectoryRights}
    }, @{
        L='Tür'; E={$_.AccessControlType}
    } -AutoSize
    
    # 2. ACL'in varsayılan olup olmadığını kontrol et
    $DefaultACEs = @(
        'NT AUTHORITY\SYSTEM',
        'BUILTIN\Administrators',
        'OWNER RIGHTS'
    )
    
    $UnexpectedACEs = $ACL.Access | Where-Object {
        -not ($_.IdentityReference.Value -match ($DefaultACEs -join '|'))
    }
    
    if ($UnexpectedACEs) {
        Write-Host "`n UYARI: Beklenmeyen ACL'ler bulundu!" -ForegroundColor Red
        $UnexpectedACEs | Format-Table IdentityReference, ActiveDirectoryRights
    } else {
        Write-Host "`n ACL normal görünüyor" -ForegroundColor Green
    }
    
    # 3. SDProp çalıştırıldığını kontrol et
    $SDPropTime = (Get-ADDomainController | Get-ADReplicationPartnerMetadata -Target (Get-ADDomain).DNSRoot).ReplicationSchedule
    Write-Host "`nSDProp Periyodu: Varsayılan 3600 saniye (1 saat)" -ForegroundColor Cyan
    
    # 4. Korunan grup üyelerinin ACL'ini kontrol et
    Write-Host "`n=== Korunan Grup Üyelerinin ACL Kontrolü ===" -ForegroundColor Cyan
    
    $DomainAdmins = Get-ADGroup -Identity "Domain Admins"
    $DomainAdminsACL = Get-ADObject -Identity $DomainAdmins.DistinguishedName -Properties nTSecurityDescriptor
    
    $ACLsSame = $null -eq (Compare-Object -ReferenceObject $AdminSDObj.nTSecurityDescriptor.Access `
                                          -DifferenceObject $DomainAdminsACL.nTSecurityDescriptor.Access)
    
    if ($ACLsSame) {
        Write-Host "✅ Domain Admins ACL'i, AdminSDHolder ile eşleşiyor (normal)" -ForegroundColor Green
    } else {
        Write-Host "⚠️ UYARI: Domain Admins ACL'i farklı! SDProp'u yeniden çalıştırmayı deneyin." -ForegroundColor Red
    }
}
# Kullanım
Audit-AdminSDHolder
Kontrol Listesi:
# Script: Setup_OU_Delegation.ps1
function New-OUWithDelegation {
    param(
        [Parameter(Mandatory)][string]$OUName,
        [Parameter(Mandatory)][string]$ParentOU,
        [Parameter(Mandatory)][string]$DelegateGroupName,
        [string[]]$Permissions = @('User Accounts', 'Reset Password')
    )
    
    # 1. OU oluştur
    $OUPath = "OU=$OUName,$ParentOU"
    try {
        New-ADOrganizationalUnit -Name $OUName -Path $ParentOU -ProtectedFromAccidentalDeletion $true
        Write-Host "✅ OU oluşturuldu: $OUPath"
    } catch {
        Write-Host " OU oluşturma hatası: $_"
        return
    }
    
    # 2. Delegasyon Grubu oluştur
    try {
        New-ADGroup -Name $DelegateGroupName -GroupScope DomainLocal -GroupCategory Security -Path $ParentOU
        Write-Host " Delegasyon Grubu oluşturuldu: $DelegateGroupName"
    } catch {
        Write-Host " Grup oluşturma hatası: $_"
        return
    }
    
    # 3. Delegasyon Yap (GUI ile veya dsacls ile)
    Write-Host "`n Delegasyon Adımları:"
    Write-Host "   1. Active Directory Users and Computers'ı aç"
    Write-Host "   2. $OUPath - Sağ Tıkla - 'Delegate Control'"
    Write-Host "   3. $DelegateGroupName'i seç"
    Write-Host "   4. Aşağıdaki izinleri seç:"
    foreach ($Perm in $Permissions) {
        Write-Host "      - $Perm"
    }
    
    # Alternatif: dsacls ile (ileri kullanıcılar için)
    # dsacls.exe "$OUPath" /G "CONTOSO\$DelegateGroupName:CCCCDA"
}
# Örnek Kullanım:
# Tier 1 Sunucu OU'su
New-OUWithDelegation `
    -OUName "Servers" `
    -ParentOU "OU=Tier1,DC=contoso,DC=com" `
    -DelegateGroupName "Tier1_ServerAdmins" `
    -Permissions @('User Accounts', 'Reset Password', 'Manage Group Membership')
# Tier 2 Aplikasyon OU'su
New-OUWithDelegation `
    -OUName "Applications" `
    -ParentOU "OU=Tier2,DC=contoso,DC=com" `
    -DelegateGroupName "Tier2_AppAdmins" `
    -Permissions @('User Accounts', 'Reset Password')
Kontrol Listesi:
# Script: Generate_Monthly_Report.ps1
function Get-ADMonthlyReport {
    param(
        [int]$Days = 30
    )
    
    $StartDate = (Get-Date).AddDays(-$Days)
    $ReportPath = "C:\Reports\AD_Monthly_Report_$(Get-Date -Format yyyyMM).html"
    
    # 1. adminCount Raporu
    $AdminCountUsers = Get-ADUser -LDAPFilter "(adminCount=1)" `
        -Properties adminCount, MemberOf, WhenChanged, LastLogonDate
    
    # 2. Yeni Eklenmiş Admins
    $NewAdmins = $AdminCountUsers | Where-Object { $_.WhenChanged -gt $StartDate }
    
    # 3. Orfa Kalan Admins
    $OrphanedAdmins = $AdminCountUsers | Where-Object {
        ($_.MemberOf -join '').Length -eq 0
    }
    
    # 4. Etkinlik Olmayan Admins (30+ gün)
    $InactiveAdmins = $AdminCountUsers | Where-Object {
        $_.LastLogonDate -lt $StartDate
    }
    
    # HTML Rapor
    $HTML = @"
    
    
    
        
        
    
    
        
        Raporlama Tarihi: $(Get-Date -Format 'dd.MM.yyyy')
        Dönem: Son $Days Gün
        
        
        
        
        
        
            $(
                $OrphanedAdmins | ForEach-Object {
                    ""
                }
            )
        | İsim | Hesap | Son Değişiklik | 
|---|---|---|
| $($_.Name) | $($_.samAccountName) | $($_.WhenChanged) | 
        
        
        
            $(
                $NewAdmins | ForEach-Object {
                    $Groups = ($_.MemberOf | ForEach-Object { ($_ -split ',')[0] -replace 'CN=' }) -join '; '
                    ""
                }
            )
        | İsim | Grup | Eklenme Tarihi | 
|---|---|---|
| $($_.Name) | $Groups | $($_.WhenChanged) | 
        
        
        
            $(
                $InactiveAdmins | ForEach-Object {
                    $DaysInactive = ((Get-Date) - $_.LastLogonDate).Days
                    ""
                }
            )
        | İsim | Son Giriş | Gün Sayısı | 
|---|---|---|
| $($_.Name) | $($_.LastLogonDate) | $DaysInactive | 
        
        
        Rapor otomatik olarak oluşturulmuştur. Kontrol ve onay gereklidir.
    
    
"@
    
    $HTML | Out-File -Path $ReportPath -Encoding UTF8
    Write-Host "Rapor oluşturuldu: $ReportPath"
    
    # Email ile gönder (isteğe bağlı)
    # Send-MailMessage -From 'ad-reports@contoso.com' -To 'admins@contoso.com' ...
}
# Kullanım
Get-ADMonthlyReport -Days 30
Shadow Admin, resmi olmayan yönetim yetkilerine sahip hesaptır:
┌────────────────────────────────────────────┐
│    SHADOW ADMIN ÖRNEKLERI                  │
├────────────────────────────────────────────┤
│ ❌ User1 - Domain Admins'de gözükmüyor    │
│    ✓ Ama OrgUnit'te "Yazma" yetkisine     │
│      sahip (Delegasyon aracılığıyla)      │
│                                             │
│ ❌ ServiceAccount - Resmi admin değil      │
│    ✓ Ama GenericAll hakkı nedeniyle       │
│      Domain Admins'e ekleyebiliyor         │
│                                             │
│ ❌ Printer Admin - Sadece yazıcı yönetmeli │
│    ✓ Ama Schema Admins grubunun ACL'ini   │
│      değiştirebildi (hata mı?)            │
└────────────────────────────────────────────┘
BloodHound, AD'de yetki yollarını görselleştirir. Kurulum:
# 1. BloodHound Community Edition'ı indir
# https://github.com/BloodHoundAD/BloodHound/releases
# 2. Neo4j Graph Database kur
docker run --name neo4j -p 7474:7474 -p 7687:7687 \
    -e NEO4J_AUTH=neo4j/password \
    neo4j:5.10
# 3. SharpHound Collector çalıştır (AD sunucusunda)
# SharpHound.exe -c All -d contoso.com -OutputDirectory C:\Temp
# 4. İndir ve BloodHound'a yükle
BloodHound ile Shadow Admin Bulma:
Analiz Adımları:
1. Collector çalıştır
   SharpHound.exe -c All --outputdirectory C:\temp
2. Dosyaları BloodHound'a yükle
   - JSON dosyalarını seç
   - Upload
3. Queryleri çalıştır:
   ├─ "Find Dangerous Rights"
   ├─ "Find AD Abuse Paths to High Value Targets"
   ├─ "Find Dangerous ACL Permissions"
   ├─ "Domain Dominance" (ileri)
   └─ "Find all Nodes - One Way Trust Relationships"
4. Sonuç: Grafikte kırmızı yollar = Riski yol (kimler admin olabilir?)
PingCastle, AD sağlığını denetler:
# 1. PingCastle.exe'yi indir
# https://www.pingcastle.com/
# 2. Admin olarak çalıştır
.\PingCastle.exe -healthcheck -domain contoso.com
# 3. HTML rapor oluşur: PingCastleReport_contoso.html
# Kritik Kontroller:
# ─────────────────
# ├─ "Detect unregistered users"              (Orfa admin yok mu?)
# ├─ "Dangerous ACLs"                         (Tehlikeli izinler)
# ├─ "Delegated Admins"                       (Yetki verilen adminler)
# ├─ "Service Accounts Not Delegated"         (Hizmet hesapları kontrol)
# └─ "Protected Groups Have Weak Accounts"    (Korunan gruplar güvensiz mi?)
# Script: Find_Shadow_Admins.ps1
function Find-ShadowAdmins {
    Write-Host "Shadow Admin Taraması Başladı..." -ForegroundColor Cyan
    
    # 1. Korunan grup üyelerini getir
    $ProtectedGroups = @('Domain Admins', 'Enterprise Admins', 'Schema Admins', 'Account Operators')
    $AdminUsers = @()
    
    foreach ($Group in $ProtectedGroups) {
        Get-ADGroupMember -Identity $Group -Recursive | 
            Where-Object { $_.objectClass -eq 'user' } | 
            ForEach-Object { $AdminUsers += $_ }
    }
    
    Write-Host " Resmi admin sayısı: $($AdminUsers.Count)"
    
    # 2. Tehlikeli ACL'leri bul
    Write-Host "`n Tehlikeli ACL'ler taranıyor..."
    
    $SuspiciousACEs = @()
    
    # OU'ları tara
    $OUs = Get-ADOrganizationalUnit -Filter * | Select-Object -First 50
    
    foreach ($OU in $OUs) {
        try {
            $ACL = Get-Acl "AD:\$($OU.DistinguishedName)"
            
            # GenericAll, GenericWrite, WriteDacl gibi tehlikeli izinleri bul
            $DangerousACEs = $ACL.Access | Where-Object {
                ($_.ActiveDirectoryRights -like '*GenericAll*') -or
                ($_.ActiveDirectoryRights -like '*GenericWrite*') -or
                ($_.ActiveDirectoryRights -like '*WriteDacl*') -or
                ($_.ActiveDirectoryRights -like '*WriteProperty*')
            }
            
            foreach ($ACE in $DangerousACEs) {
                # Eğer resmi admin değilse, shadow admin olabilir
                if ($AdminUsers | Where-Object { $_.SID -eq $ACE.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]) }) {
                    # Resmi admin, skip
                } else {
                    $SuspiciousACEs += [PSCustomObject]@{
                        OU = $OU.Name
                        Identity = $ACE.IdentityReference
                        Rights = $ACE.ActiveDirectoryRights
                        AccessType = $ACE.AccessControlType
                        ObjectType = $ACE.ObjectType
                    }
                }
            }
        } catch {
            # OU erişim hatası, devam et
        }
    }
    
    if ($SuspiciousACEs.Count -gt 0) {
        Write-Host "`n UYARI: $($SuspiciousACEs.Count) şüpheli ACL bulundu!" -ForegroundColor Red
        $SuspiciousACEs | Format-Table OU, Identity, Rights -AutoSize
    } else {
        Write-Host "`n Şüpheli ACL bulunamadı" -ForegroundColor Green
    }
    
    # 3. Delegasyon Grubuna Sahip Kullanıcıları Bul
    Write-Host "`n Özel delegasyon grupları taranıyor..."
    
    $DelegationGroups = Get-ADGroup -Filter { Name -like '*Admin*' -or Name -like '*Delegate*' } -Properties Members | 
        Where-Object { $_.DistinguishedName -like '*OU=*' } # Sadece OU'daki gruplar
    
    foreach ($Group in $DelegationGroups) {
        $Members = Get-ADGroupMember -Identity $Group -Recursive
        Write-Host "  └─ $($Group.Name): $($Members.Count) üye"
    }
}
# Kullanım
Find-ShadowAdmins
| Kaynak | URL | İçerik | 
|---|---|---|
| Tier Model | Microsoft Docs | Tier 0/1/2 mimarisi | 
| AdminSDHolder | Microsoft Docs | AdminSDHolder detaylı | 
| Protected Groups | Microsoft Docs | Korunan gruplar listesi | 
| Delegation | Microsoft Docs | OU delegasyonu rehberi | 
| Araç | Kullanım | Download | 
|---|---|---|
| BloodHound | Shadow Admin avı, ACL analizi | https://github.com/BloodHoundAD/BloodHound | 
| PingCastle | AD sağlık raporu, denetim | https://www.pingcastle.com/ | 
| ADExplorer | AD tarama ve ACL denetimi | https://docs.microsoft.com/en-us/sysinternals/ | 
| Get-ADGroupChanges | Grup değişiklikleri izleme | GitHub (çeşitli) | 
┌──────────────────────────────────────────────────────────────┐
│         ACTIVE DIRECTORY GÜVENLİ DELEGASYON CHECKLIST        │
├──────────────────────────────────────────────────────────────┤
✅ HAFTALIK GÖREVLER
 □ adminCount raporu oluştur ve gözden geçir
 □ Orfa admin olup olmadığını kontrol et
 □ Yeni admin eklentisini denetim günlüğüne kaydet
 □ Shadow admin avı çalıştır (BloodHound)
✅ AYLIK GÖREVLER
 □ HTML raporu oluştur ve yöneticilere gönder
 □ adminCount temizliğini çalıştır (orfa kalanları kaldır)
 □ AdminSDHolder ACL'ini denetle
 □ PingCastle raporu oluştur
 □ Delegasyon belgelerini güncelle
✅ ÇEYREK YIL GÖREVLERİ
 □ Tier model uyumluluğunu gözden geçir
 □ OU delegasyonunun hâlâ uygun olduğunu kontrol et
 □ Account Operators kullanımını sıfırla
 □ Break Glass hesaplarını test et (güvenli ortamda)
✅ YILLIK GÖREVLER
 □ Tüm admin hesaplarını denetim yapan dış ekip tarafından doğrula
 □ Security Assessment yapmaz
 □ Tier Model'i güncel hale getir
 □ Disaster Recovery planını test et
 □ Yönetici eğitimi düzenle
✅ KRİTİK KURALLARI KONTROL ET
 □ AdminSDHolder ACL'i BİR KEZ DAHA DEĞIŞMEDI
 □ Account Operators grubu KULLANILMIYOR
 □ Delegasyon SADECE OU seviyesinde
 □ TIER 0 hesapları 2-3 adet ve MFA'lı
 □ Break Glass hesapları var ve güvende (vault)
 □ Aylık raporlama ZORUNLU hale getirildi
 □ BloodHound / PingCastle raporları düzenli alınıyor
└──────────────────────────────────────────────────────────────┘
# Step 1
Get-ADUser -LDAPFilter "(adminCount=1)" -Properties MemberOf, WhenChanged | 
    Export-Csv -Path "C:\Backup\admincount_baseline.csv"
# Step 2
Audit-AdminSDHolder  # (Yukarıdaki script)
# Step 3
Remove-OrphanedAdminCount -WhatIf  # Sadece preview!
Active Directory'de admin hakkı yönetimi basit görünse de, yaşadığı zaman çok karmaşık hale gelebilir. Bu rehberin temel ilkeleri:
Başarı, günlük disiplin ve şeffaflık ile ölçülür. Şu anda 500+ gizli admin varsa, korkma. Planı uygula, rapor yap, denetleyeni tatmin et. Kolay gelsin...