Yıllar içinde fark ettim ki UAC (User Account Control), Windows Server ortamlarında en çok yanlış anlaşılan güvenlik mekanizmalarından biri. Kimi sysadmin arkadaşlar “zaten server ortamında ne işi var bunun” diye kapatıyor, kimileri de varsayılan ayarlarla bırakıp geçiyor. Oysa doğru yapılandırılmış bir UAC politikası, özellikle Active Directory ortamlarında ciddi bir güvenlik katmanı oluşturuyor. Bu yazıda UAC’ı sıfırdan anlatacak, gerçek senaryolar üzerinden nasıl yapılandıracağınızı göstereceğim.
UAC Nedir ve Server Ortamında Neden Önemlidir?
UAC, Windows Vista ile hayatımıza giren ve o günden bu yana gelişmeye devam eden bir güvenlik mekanizması. Temel mantığı şu: Bir kullanıcı veya uygulama yükseltilmiş yetkiler gerektiren bir işlem yapmak istediğinde, sistemin onay alması zorunlu hâle getiriliyor. Desktop ortamında bu “İzin vermek istiyor musunuz?” kutusu olarak karşımıza çıkıyor.
Server ortamında ise tablo biraz farklı. Windows Server 2008’den itibaren UAC server sistemlerde de aktif geliyor ancak davranışı biraz farklı. Admin Approval Mode denen bir konsept devreye giriyor. Bu modda, Domain Admins grubuna dahil bir kullanıcı bile sisteme iki token ile bağlanıyor: biri standart kullanıcı token’ı, diğeri yüksek yetkili admin token’ı. Yüksek yetkili işlemler için ikinci token’ın kullanılması gerekiyor ve bu da bir onay mekanizmasını tetikliyor.
Peki neden önemli? Şöyle düşünün: Bir admin hesabı ele geçirildi ve saldırgan bu hesapla sisteme bağlandı. UAC devre dışıysa, çalıştırdığı her uygulama anında admin yetkiyle çalışır. UAC aktifse ve doğru yapılandırılmışsa, kötü amaçlı yazılımın yüksek yetkili işlem başlatması için ek bir engelle karşılaşması gerekir. Bu %100 koruma sağlamaz ama saldırı yüzeyini daraltır.
UAC Seviyeleri ve Yapılandırma Seçenekleri
UAC’ın dört ana çalışma seviyesi var. Bunları anlamak, hangi ortamda hangi seviyeyi kullanmanız gerektiğini belirlemenizi sağlar.
- Always Notify (Her Zaman Bildir): En yüksek güvenlik seviyesi. Hem sistem ayarlarında hem de uygulama kurulumlarında onay istenir. Güvenlik açısından ideal ama yönetim yükü yüksek.
- Notify Me Only When Apps Try to Make Changes: Varsayılan ayar. Uygulamalar değişiklik yapmak istediğinde onay ister, ancak siz ayar değiştirirken sormaz.
- Notify Me Only When Apps Try to Make Changes (Do Not Dim Desktop): Bir öncekiyle aynı ama güvenli masaüstüne geçmiyor. Daha az güvenli.
- Never Notify (Hiçbir Zaman Bildirme): UAC tamamen devre dışı. Production ortamında kesinlikle önerilmez.
Server ortamında genellikle ikinci veya birinci seçenek kullanılır. Kritik sistemlerde birinci seviyeyi tercih etmek mantıklı.
Registry Üzerinden UAC Yapılandırması
UAC ayarlarının tamamı registry’de HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem altında tutuluyor. Bu yolu bilerek manuel yapılandırma yapabilir ya da Group Policy ile dağıtabilirsiniz.
Önemli registry değerleri şunlar:
- EnableLUA: UAC’ın açık (1) veya kapalı (0) olduğunu belirler. Asla 0 yapmayın.
- ConsentPromptBehaviorAdmin: Admin için onay isteme davranışı. 0=onaysız yükselt, 1=kimlik bilgisi iste, 2=onay iste, 5=secure desktop onay, 3=secure desktop kimlik bilgisi
- ConsentPromptBehaviorUser: Standart kullanıcı için davranış. 0=otomatik reddet, 1=kimlik bilgisi iste, 3=secure desktop kimlik bilgisi
- PromptOnSecureDesktop: Onay ekranının güvenli masaüstünde (1) açılıp açılmayacağı
- EnableVirtualization: UAC dosya/registry sanallaştırması (eski uygulamalar için)
PowerShell ile mevcut UAC yapılandırmasını sorgulamak için:
# Mevcut UAC ayarlarini goruntule
Get-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem" |
Select-Object EnableLUA, ConsentPromptBehaviorAdmin, ConsentPromptBehaviorUser, PromptOnSecureDesktop
# Sadece UAC etkin mi degil mi kontrol et
(Get-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem").EnableLUA
UAC ayarlarını PowerShell ile değiştirmek için:
# UAC'i en yuksek seviyeye al (her zaman bildir)
$registryPath = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem"
Set-ItemProperty -Path $registryPath -Name "ConsentPromptBehaviorAdmin" -Value 2
Set-ItemProperty -Path $registryPath -Name "ConsentPromptBehaviorUser" -Value 3
Set-ItemProperty -Path $registryPath -Name "PromptOnSecureDesktop" -Value 1
Set-ItemProperty -Path $registryPath -Name "EnableLUA" -Value 1
Write-Host "UAC ayarlari guncellendi. Degisikliklerin etkili olmasi icin sistemi yeniden baslatiniz." -ForegroundColor Green
Group Policy ile Merkezi UAC Yönetimi
Tek tek sunucuları elle yapılandırmak yerine Group Policy kullanmak çok daha mantıklı. Özellikle onlarca sunucusu olan ortamlarda bu yaklaşım hayat kurtarır.
GPO üzerinden UAC ayarlarına şuradan ulaşıyorsunuz: Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options
Bu yolda “User Account Control” ile başlayan sekiz ayrı politika seçeneği göreceksiniz. Bunların en kritikleri:
- User Account Control: Run all administrators in Admin Approval Mode – Bu politika UAC’ın temelini oluşturuyor. Kapatırsanız UAC fiilen devre dışı kalıyor.
- User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode – Admin onay davranışını belirliyor.
- User Account Control: Switch to the secure desktop when prompting for elevation – Güvenli masaüstü kullanımı.
PowerShell ile GPO ayarlarını uzak makinelerde kontrol etmek:
# Uzak sunucuda UAC GPO ayarlarini sorgula
$computers = @("SRV-WEB01", "SRV-DB01", "SRV-APP01")
foreach ($computer in $computers) {
Write-Host "`n=== $computer ===" -ForegroundColor Cyan
$uacSettings = Invoke-Command -ComputerName $computer -ScriptBlock {
$path = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem"
$props = Get-ItemProperty -Path $path
[PSCustomObject]@{
ComputerName = $env:COMPUTERNAME
EnableLUA = $props.EnableLUA
AdminConsent = $props.ConsentPromptBehaviorAdmin
UserConsent = $props.ConsentPromptBehaviorUser
SecureDesktop = $props.PromptOnSecureDesktop
}
}
$uacSettings | Format-List
}
Gerçek Dünya Senaryosu 1: Web Sunucusu Ortamı
Bir müşteride IIS sunucuları yönetiyordum ve uygulama ekibi sürekli “deploy sırasında UAC prompt çıkıyor, CI/CD pipeline’ımız duruyor” diye şikâyet ediyordu. Durumu incelediğimde şunu gördüm: Servis hesabı gereksiz yere local admin grubuna eklenmiş, ama UAC nedeniyle her deploy işleminde onay bekleniyor.
Çözüm şuydu: Servis hesabını local admin’den çıkardım, sadece ihtiyaç duyduğu dizinlere ve IIS’e özel yetkiler verdim. Deploy işlemleri için ayrı bir scheduled task oluşturdum ve bu task’ı gerçek bir admin hesabıyla “Run as highest privileges” seçeneğiyle çalışacak şekilde ayarladım.
Ama bazı durumlarda CI/CD servis hesabının belirli yüksek yetkili işlemleri onaysız yapması gerekebiliyor. Bu durum için Local Security Policy’de o hesabı “User Account Control: Behavior of the elevation prompt for administrators” ayarında özel bir şekilde yapılandırmak yerine, şu yaklaşımı kullandım:
# Belirli bir uygulama icin UAC bypass icermeyen guvenli yaklasim
# Scheduled Task ile yukseltilmis yetki
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-NonInteractive -File C:Deploydeploy-script.ps1"
$principal = New-ScheduledTaskPrincipal `
-UserId "DOMAINsvc-deploy" `
-RunLevel Highest `
-LogonType Password
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 30)
Register-ScheduledTask -TaskName "AppDeploy" `
-Action $action `
-Principal $principal `
-Settings $settings `
-Force
Write-Host "Deploy task olusturuldu." -ForegroundColor Green
Gerçek Dünya Senaryosu 2: Terminal Server / RDS Ortamı
Remote Desktop Services ortamları UAC açısından özel bir dikkat gerektiriyor. Yüzlerce kullanıcının bağlandığı bir RDS sunucusunda, bir kullanıcının yanlışlıkla veya kötü niyetle yükseltilmiş işlem başlatması ciddi sorunlara yol açabilir.
RDS ortamları için şu yapılandırmayı öneriyorum:
# RDS ortami icin UAC sertlestirme scripti
$path = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem"
# Standart kullanicilarin yukseltme isteklerini otomatik reddet
Set-ItemProperty -Path $path -Name "ConsentPromptBehaviorUser" -Value 0
# Admin onay ekranini guvenli masaustunde goster
Set-ItemProperty -Path $path -Name "PromptOnSecureDesktop" -Value 1
# Admin Approval Mode'u aktif tut
Set-ItemProperty -Path $path -Name "EnableLUA" -Value 1
# UAC dosya ve registry sanallastirmasini aktif tut (eski uygulamalar icin)
Set-ItemProperty -Path $path -Name "EnableVirtualization" -Value 1
# Guvenli konumlardan gelen imzali uygulamalar icin sessiz yukseltme
# (Bu production ortaminiza gore degerlendirin)
Set-ItemProperty -Path $path -Name "ValidateAdminCodeSignatures" -Value 1
Write-Host "RDS UAC yapılandırması tamamlandı." -ForegroundColor Green
UAC Denetim Logları ve İzleme
UAC olaylarını izlemek, güvenlik açısından kritik öneme sahip. Windows Event Log’da UAC ile ilgili olaylar birkaç farklı log’a dağılıyor. Security log’unda 4703 (token hakkı ayarlandı) ve 4688 (yeni process oluşturuldu) event ID’leri, Application and Services Logs altındaki Microsoft > Windows > UAC log’u ve Application log’undaki 1102 event ID’si takip edilmesi gereken başlıca kaynaklardır.
PowerShell ile UAC olaylarını sorgulamak:
# Son 24 saatteki UAC elevation olaylarini sorgula
$startTime = (Get-Date).AddHours(-24)
# Security logunda process creation olaylarini filtrele
$events = Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4688
StartTime = $startTime
} -ErrorAction SilentlyContinue |
Where-Object { $_.Message -like "*elevation*" -or $_.Message -like "*token*" }
if ($events) {
Write-Host "Son 24 saatte tespit edilen UAC ile ilgili olaylar:" -ForegroundColor Yellow
$events | Select-Object TimeCreated, Id, Message |
Format-List
} else {
Write-Host "Son 24 saatte UAC ile ilgili olay bulunamadi." -ForegroundColor Green
}
# UAC-specific log
$uacEvents = Get-WinEvent -LogName "Microsoft-Windows-UAC/Operational" `
-MaxEvents 50 -ErrorAction SilentlyContinue
$uacEvents | Select-Object TimeCreated, Id, LevelDisplayName, Message | Format-List
Sertleştirme: UAC ile Birlikte Kullanılması Gereken Ek Önlemler
UAC tek başına yeterli değil. Birkaç ek yapılandırmayla birlikte kullanıldığında anlamlı bir savunma katmanı oluşturuyor.
Local Administrator Hesabını Yönetmek: Yerleşik Administrator hesabı UAC Admin Approval Mode’dan muaf tutulur, bu yüzden bu hesabı devre dışı bırakmak veya adını değiştirmek iyi bir pratik.
# Yerlesik Administrator hesabini devre disi birak
Disable-LocalUser -Name "Administrator"
# Veya hesabi yeniden adlandir
Rename-LocalUser -Name "Administrator" -NewName "LocalAdm_Disabled"
# Mevcut local admin hesaplarini listele
Get-LocalGroupMember -Group "Administrators" |
Select-Object Name, ObjectClass, PrincipalSource
LAPS (Local Administrator Password Solution) ile Entegrasyon: UAC ile birlikte LAPS kullanmak, her makinenin yerel admin şifresinin farklı olmasını sağlar. Bu kombinasyon, pass-the-hash saldırılarına karşı etkili bir bariyer oluşturur.
# LAPS kurulu mu kontrol et
$lapsInstalled = Get-Module -Name LAPS -ListAvailable
if ($lapsInstalled) {
Write-Host "LAPS yuklu." -ForegroundColor Green
# LAPS ile yonetilen bilgisayarlari sorgula
Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime |
Where-Object { $_."ms-Mcs-AdmPwd" -ne $null } |
Select-Object Name, "ms-Mcs-AdmPwdExpirationTime" |
Format-Table -AutoSize
} else {
Write-Host "LAPS yuklu degil. Kurulum onerilir." -ForegroundColor Red
}
Protected Users Grubu ile Kombinasyon: Kritik admin hesaplarını Active Directory’deki Protected Users grubuna eklemek, credential theft saldırılarını önemli ölçüde zorlaştırıyor. Bu grup Kerberos davranışını değiştiriyor ve NTLM kullanımını engelliyor.
# Protected Users grubuna uye ekle
Add-ADGroupMember -Identity "Protected Users" -Members "domain-admin-user"
# Grubun mevcut uyelerini goruntule
Get-ADGroupMember -Identity "Protected Users" |
Select-Object Name, SamAccountName, ObjectClass
Uygulama Uyumluluğu Sorunları ve Çözümleri
UAC’ı sertleştirdiğinizde en çok karşılaşılan sorun eski uygulamaların çalışmaması. Özellikle 2000’li yıllarda yazılmış, admin yetkisi varsayan uygulamalar bu gruba giriyor.
Application Compatibility Toolkit ile uygulama manifesto dosyası oluşturabilir ya da mevcut uygulamaya uyumluluk katmanı ekleyebilirsiniz. Ama en pratik çözüm genellikle şu:
# Belirli bir uygulama icin UAC manifest ayari
# Uygulama dizinine asconfig.xml olustur
$manifestContent = @"
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
"@
# Manifest dosyasini uygulama dizinine kaydet
$appPath = "C:LegacyApp"
$manifestPath = Join-Path $appPath "app.exe.manifest"
$manifestContent | Out-File -FilePath $manifestPath -Encoding UTF8
Write-Host "Manifest dosyasi olusturuldu: $manifestPath" -ForegroundColor Green
# Application Compatibility Flags kayit defteri girisi
$appCompatPath = "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionAppCompatFlagsLayers"
if (-not (Test-Path $appCompatPath)) {
New-Item -Path $appCompatPath -Force | Out-Null
}
Set-ItemProperty -Path $appCompatPath -Name "C:LegacyAppapp.exe" -Value "RUNASADMIN"
UAC Yapılandırmasını Doğrulama ve Test Etme
Yapılandırmayı tamamladıktan sonra doğrulamak şart. Aşağıdaki script, bir sunucunun UAC sertleştirme durumunu kontrol ediyor ve CIS Benchmark gereksinimlerine göre değerlendiriyor:
# UAC Guvenlik Denetim Scripti
function Test-UACConfiguration {
param(
[string]$ComputerName = $env:COMPUTERNAME
)
$scriptBlock = {
$path = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem"
$props = Get-ItemProperty -Path $path
$results = @()
# EnableLUA kontrolu
$results += [PSCustomObject]@{
Kontrol = "UAC Etkin (EnableLUA)"
BeklenenDeger = 1
MevcutDeger = $props.EnableLUA
Durum = if ($props.EnableLUA -eq 1) { "GECTI" } else { "BASARISIZ" }
}
# Admin onay davranisi
$results += [PSCustomObject]@{
Kontrol = "Admin Onay Davranisi"
BeklenenDeger = "1 veya 2"
MevcutDeger = $props.ConsentPromptBehaviorAdmin
Durum = if ($props.ConsentPromptBehaviorAdmin -in @(1,2)) { "GECTI" } else { "UYARI" }
}
# Guvenli masaustu
$results += [PSCustomObject]@{
Kontrol = "Guvenli Masaustu"
BeklenenDeger = 1
MevcutDeger = $props.PromptOnSecureDesktop
Durum = if ($props.PromptOnSecureDesktop -eq 1) { "GECTI" } else { "BASARISIZ" }
}
# Kullanici elevation davranisi
$results += [PSCustomObject]@{
Kontrol = "Kullanici Elevation Davranisi"
BeklenenDeger = 0
MevcutDeger = $props.ConsentPromptBehaviorUser
Durum = if ($props.ConsentPromptBehaviorUser -eq 0) { "GECTI" } else { "UYARI" }
}
return $results
}
if ($ComputerName -eq $env:COMPUTERNAME) {
$results = & $scriptBlock
} else {
$results = Invoke-Command -ComputerName $ComputerName -ScriptBlock $scriptBlock
}
Write-Host "`n=== UAC Guvenlik Denetim Raporu: $ComputerName ===" -ForegroundColor Cyan
foreach ($result in $results) {
$color = switch ($result.Durum) {
"GECTI" { "Green" }
"BASARISIZ" { "Red" }
"UYARI" { "Yellow" }
default { "White" }
}
Write-Host "`n[$($result.Durum)] $($result.Kontrol)" -ForegroundColor $color
Write-Host " Beklenen: $($result.BeklenenDeger) | Mevcut: $($result.MevcutDeger)"
}
$failCount = ($results | Where-Object { $_.Durum -eq "BASARISIZ" }).Count
Write-Host "`n--- Ozet: $failCount basarisiz kontrol ---" -ForegroundColor $(if ($failCount -eq 0) { "Green" } else { "Red" })
}
# Testi calistir
Test-UACConfiguration
# Veya uzak sunucu icin
# Test-UACConfiguration -ComputerName "SRV-WEB01"
Sonuç
UAC, yalnız başına bir kale değil, derinlemesine savunma stratejisinin önemli bir parçası. Doğru yapılandırılmadığında ya gereksiz onay ekranları çıkararak operasyonel süreci yavaşlatıyor ya da güvenlik açıkları bırakıyor. Bu yazıda anlattıklarımı özetlersek:
UAC’ı hiçbir zaman production ortamında tamamen kapatmayın. “İşletim sistemi ayarı olmasa da olur” yaklaşımı gerçekten yanlış. EnableLUA değerini 1 olarak tutmak temel şart.
Admin Approval Mode’u mutlaka etkin bırakın. Bu mod, Domain Admin hesaplarının bile yükseltilmiş işlemler için onay vermesini sağlıyor ve credential theft senaryolarında saldırganın önüne önemli bir engel koyuyor.
Güvenli masaüstünü kapatmayın. Onay ekranının normal masaüstünde açılması, kötü amaçlı yazılımların bu ekranı taklit etmesine kapı aralıyor. PromptOnSecureDesktop her zaman 1 olsun.
Group Policy ile merkezi yönetim şart. Onlarca sunucu varsa tek tek elle ayarlamak hem zaman kaybı hem de hata riski. GPO’ya alın, dağıtın, izleyin.
Eski uygulamalarla baş ederken UAC’ı kapatmak yerine uygulama manifesto veya scheduled task yaklaşımını deneyin. Çoğu zaman daha temiz bir çözüm oluyor.
Son olarak, UAC denetim loglarını SIEM sisteminize veya en azından merkezi event log yönetiminize dahil edin. Anormal elevation denemeleri, içeriden gelen tehditlerin ya da hesap ele geçirme girişimlerinin erken sinyali olabilir. Bu logları izlemeden UAC kurmuş olmak, alarm sistemini açmadan kamerayı çalıştırmak gibi.