Идём по киберследу: Анализ защищенности Active Directory c помощью утилиты BloodHound — страница 38 из 46

'$ObjectGUID'}) MERGE (m)-[r: WriteProperty]-(n) SET r.isacl=TRUE;"

}

}

# Проверяем права WriteDacl

if($acl.ActiveDirectoryRights -match "WriteDacl")

{

# Создаем Cypher-запрос на создание связи между шаблоном и объектами с правами WriteDacl

Add-Content $OutFile "MATCH (m {objectid:'$ObjectSID'}) MATCH (n {objectid:'$ObjectGUID'}) MERGE (m)-[r: WriteDacl]-(n) SET r.isacl=TRUE;"

}

# Проверяем права WriteOwner

if($acl.ActiveDirectoryRights -match "WriteOwner")

{

# Создаем Cypher-запрос на создание связи между шаблоном и объектами с правами WriteOwner

Add-Content $OutFile "MATCH (m {objectid:'$ObjectSID'}) MATCH (n {objectid:'$ObjectGUID'}) MERGE (m)-[r: WriteOwner]-(n) SET r.isacl=TRUE;"

}

# Проверяем права GenericAll

if($acl.ActiveDirectoryRights -match "GenericAll")

{

# Создаем Cypher-запрос на создание связи между шаблоном и объектами с правами GenericAll

Add-Content $OutFile "MATCH (m {objectid:'$ObjectSID'}) MATCH (n {objectid:'$ObjectGUID'}) MERGE (m)-[r: GenericAll]-(n) SET r.isacl=TRUE;"

}

}

}

# Выполняем ADSI-запрос для получения всех шаблонов сертификатов

$objects = [ADSI]"LDAP://CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration,$CurrentDomain"

$cas = $objects.Get_Children()

foreach($ca in $cas)

{

# Получаем имя центра сертификации

$name = $ca.properties.name.ToUpper()

# Получаем сервер, на котором установлен центр сертификации

$dnshostname = $ca.dnshostname.value.ToString().ToUpper()

# Получаем guid центра сертификации

$ObjectGUID = [guid]$ca.properties.objectGUID.value | select -ExpandProperty Guid

# Проверяем наличие флага AttributeSubjectaltName2 (ESC6)

$reg=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$dnshostname)

$key = $reg.OpenSubKey("SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\$name\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy")

if($key.GetValue('EditFlags') -band "0x00040000")

{

$AttributeSubjectaltName2 = "Enabled"

}

else

{

$AttributeSubjectaltName2 = "Disabled"

}

# Проверяем, доступен ли Web Enrollment

$URL = "http://$dnshostname/certsrv"

$Request = [System.Net.WebRequest]::Create($URL)

$Cache = New-Object System.Net.CredentialCache

$Cache.Add([System.Uri]::new($URL), "NTLM", [System.Net.CredentialCache]::DefaultNetworkCredentials)

$Request.Credentials = $Cache

$Request.Timeout = 3000

try {

$Response = $Request.GetResponse()

if($Response.StatusCode -eq [System.Net.HttpStatusCode]::OK)

{

$WebEnrollement = "Enabled"

}

}

catch {

$WebEnrollement = "Disabled"

}

# Проверяем отсутствие флага EnforceEncryptiCertRequest (ESC11)

$reg=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$dnshostname)

$key = $reg.OpenSubKey("SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\$name")

if($key.GetValue('InterfaceFlags') -band "512")

{

$EnforceEncryptiCertRequest = "Enabled"

}

else

{

$EnforceEncryptiCertRequest = "Disabled"

}

# Получаем значение атрибута Request Disposition в центре сертификации

$reg=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$dnshostname)

$key = $reg.OpenSubKey("SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\$name\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy")

# Преобразуем результат в читаемый вид на основе hashtable

$vals=[RequestDisposition]$key.getvalue('RequestDisposition')

# Список для Request Disposition

$RequestDisposition = "' {0}'" -f ($vals.ToString().Replace(", ","','"))

# Получаем время создания центра сертификации в формате epoch

$WhenCreated = (Get-Date $ca.Properties.WhenCreated.DateTime -UFormat%s). split(',')[0]

# Получаем время изменения центра сертификации в формате epoch

$WhenChanged = (Get-Date $ca.Properties.WhenChanged.DateTime -UFormat%s). split(',')[0]

# Создаем Cypher-запрос на создание узла центра сертификации со всеми доступными свойствами

Add-Content $OutFile "MERGE (m: CA {objectid:'$ObjectGUID', name:'$name', dnshostname:'$dnshostname', domain:'$DomainName', webenrollement:'$WebEnrollement', attributesubjectaltname2:'$AttributeSubjectaltName2', enforceencrypticertrequest:'$EnforceEncryptiCertRequest', requestdisposition: [$RequestDisposition], whencreated:$WhenCreated, whenchanged:$WhenChanged});"

# Получаем SID владельца центра сертификации

$ID = new-object System.Security.Principal.NTAccount($ca.ObjectSecurity.Owner)

$OwnerSID = $ID.Translate([System.Security.Principal.SecurityIdentifier]). toString()

if($ownersid.Length -le 12)

{

$OwnerSID = $DomainObject.name.toUpper() +"-" + $OwnerSID

}

# Создаем Cypher-запрос на создание связи между шаблоном и владельцем

Add-Content $OutFile "MATCH (m {ObjectID:'$OwnerSID'}) MATCH (n: CA {ObjectID:'$ObjectGUID'}) MERGE (m)-[r: Owns]->(n) SET r.isacl=TRUE;"

# Получаем ACL для центра сертификации

$reg=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$dnshostname)

$key = $reg.OpenSubKey("SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\$name")

$Objects = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $key.getvalue('Security'), 0

foreach($Object in $Objects.DiscretionaryAcl)

{

# Получаем SID объекта, который имеет права

$ObjectID = $Object.SecurityIdentifier[0].Value

if($ObjectID.Length -le 12)

{

$ObjectID = $DomainObject.name.toUpper() +"-" + $ObjectID

}

# Проверяем права на запрос сертификата

if($Object.AccessMask -band "512")

{

# Создаем Cypher-запрос на создание связи между шаблоном и объектом с правами на запрос сертификата