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

{

$offset = $pBuffer.ToInt64()

for ($i = 0; $i -lt $totalEntries; $i++)

{

$pEntry = New-Object IntPtr($offset)

$shareInfo = [Runtime.InteropServices.Marshal]::PtrTo Structure($pEntry, [Type] [SHARE_INFO_1])

$offset += [Runtime.InteropServices. Marshal]::SizeOf($shareInfo)

# Генерируем guid для общего ресурса

$objectid = ([guid]::NewGuid()). toString(). toUpper()

# Из результатов перечисления получаем имя, описание и тип общего ресурса

$shareName = $shareInfo.shi1_netname.ToUpper()

$shareDescription = $shareInfo.shi1_remark

$shareType = $shareInfo.shi1_type

# Проверяем доступ к общему ресурсу для текущего пользователя

try{

$TargetPath = ("\\" + $ComputerName + "\" + $shareName).ToUpper()

$Null = [IO.Directory]::GetFiles($TargetPath)

$ShareAccess = "TRUE"

}catch{

$ShareAccess = "FALSE"

}

# Составляем строку запроса для создания узла

Add-Content $OutFile "MERGE (s: Share {objectid:'$objectid', name:'$shareName', des cription:'$shareDescription', type:$shareType, accsessible:$ShareAccess, domain:'$DomainName', path:'\\$TargetPath'});"

Add-Content $OutFile "MATCH (s: Share {objectid:'$objectid'}) MATCH(c: Computer {objectid:'$SID'}) MERGE (s)-[r: HostedOn]->(c);"

# Получаем ACL для общего ресурса

$Acl = Get-Acl $TargetPath -ErrorAction SilentlyContinue

foreach ($Access in $acl.Access)

{

if($Access.FileSystemRights -match "Write|FullControl|Modify")

{

# Получаем SID для объекта

$ID = new-object System.Security.Principal. NTAccount($Access.IdentityReference.Value)

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

if($ObjectSID.Length -le 12)

{

$ObjectSID = $DomainName +"-" + $ObjectSID

}

# Формируем права доступа для создания связей

if($Access.FileSystemRights -match "Write")

{

$Right = "CanWrite"

}

if($Access.FileSystemRights -match "Modify")

{

$Right = "CanModify"

}

if($Access.FileSystemRights -match "FullControl")

{

$Right = "FullControl"

}

# Отбрасываем системные учетные записи

if(($ObjectSID -notmatch "S-1–3–0|S-1–5–18|S-1–5–9") -and ($Access.IdentityReference.Value -notmatch "TrustedInstaller"))

{

# Проверяем наследование

$IsInherited = $Access.IsInherited

# Формируем строку запроса для связей ACL

Add-Content $OutFile "MATCH (m {objectid:'$ObjectSID'}) MATCH (s: Share {objectid:'$objectid'}) MERGE (m)-[r:$Right]->(s) SET r.isinherited = $IsInherited, r.isfsacl = TRUE;"

}

}

}

# Получаем директории с исключением доменных и у которых есть права доступа

if(($shareName -notmatch "\$|SYSVOL|NETLOGON") -and ($ShareAccess -eq "TRUE"))

{

# Получаем поддиректории с глубиной две директории

$FolderPath = Get-ChildItem -Path $TargetPath -Recurse -Directory -Depth 2

Foreach ($Folder in $FolderPath)

{

# Получаем свойства поддиректорий: имя, полное имя, guid и полный путь

$name = $Folder.Name.toUpper()

$fullname = $Folder.FullName.toUpper()

$objectid = ([guid]::NewGuid()). toString(). toUpper()

$parentpath = ([IO.Directory]::GetParent($fullname). fullname). toUpper()

# Проверяем доступ для текущего пользователя

try{

$Null = [IO.Directory]::GetFiles($fullname)

$PathAccess = "TRUE"

}catch{

$PathAccess = "FALSE"

}

# Формируем строку запроса для создания узла поддиректории

Add-Content $OutFile "MERGE (s: Share {objectid:'$objectid', name:'$Name', accsessible:$PathAccess, domain:'$DomainName', path:'\\$fullname'});"

Add-Content $OutFile "MATCH (m: Share {path:'\\ $parentpath'}) MATCH (n: Share {objectid:'$objectid'}) MERGE (m)-[r: Contains]->(n);"

# Получаем ACL для поддиректорий

$Acl = Get-Acl $fullname -ErrorAction SilentlyContinue

foreach ($Access in $acl.Access)

{

if($Access.FileSystemRights -match "Write|FullControl|Modify")

{

# Получаем SID для объекта

$ID = new-object System.Security.Principal. NTAccount($Access.IdentityReference.Value)

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

if($ObjectSID.Length -le 12)

{

$ObjectSID = $DomainName +"-" + $ObjectSID

}

# Формируем права доступа для создания связей

if($Access.FileSystemRights -match "Write")

{

$Right = "CanWrite"

}

if($Access.FileSystemRights -match "Modify")

{

$Right = "CanModify"

}

if($Access.FileSystemRights -match "FullControl")

{

$Right = "FullControl"

}

# Отбрасываем привилегированные учетные записи

if(($ObjectSID -notmatch "S-1-3-0|S-1-5-18|S-1-5–9|S-1–5–32–544 |-517$|-512$|-519$|-500$") -and ($Access.IdentityReference.Value -notmatch "TrustedInstaller"))

{

# Проверяем наследование

$IsInherited = $Access.IsInherited

# Формируем строку запроса для связей ACL

Add-Content $OutFile "MATCH (m {objectid:'$ObjectSID'}) MATCH (s: Share {objectid:'$objectid'}) MERGE (m)-[r:$Right]->(s) SET r.isinherited = $IsInherited, r.isfsacl = TRUE;"

}

}

}

}

}

}

[Void] [NetApi32]::NetApiBufferFree($pBuffer)

}

}

}

После выполнения с помощью скрипта загрузим данные в базу neo4j:

..\GetSharesInfo.ps1

Get-SharesInfo

..\neo4j_uploaddata.ps1