Last active
April 15, 2021 07:52
-
-
Save HopHouse/7653ace88400c79c67bf14fba45cd4c2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Associated blog post : https://blog.hophouse.fr/_posts/CheckResetPasswordRights.html | |
function Get-ADAllUserGroupMembership { | |
<# | |
.SYNOPSIS | |
Recursively retrieve all the groups where a specified group belongs to. | |
.EXAMPLE | |
PS> Get-ADAllUserGroupMembership -Server 10.10.10.10 -GroupName custom_admin | |
.PARAMETER Server | |
Domain Controller where to run commands. | |
.PARAMETER GroupName | |
Group where the function will dig. | |
#> | |
[CmdletBinding()] | |
param( | |
[parameter(mandatory=$True)] | |
[ValidateNotNullOrEmpty()] | |
[string]$Server, | |
[parameter(mandatory=$True)] | |
[ValidateNotNullOrEmpty()] | |
[string]$GroupName | |
) | |
$GroupMembership = @() | |
$GroupObject = Get-ADGroup -Server $Server -Identity $GroupName -Properties MemberOf,objectSid | |
[array]$GroupMembership += $GroupObject | |
$GroupMemberObject = ($GroupObject).MemberOf | |
if($GroupMemberObject.count -eq 0) { | |
return $GroupMembership | |
} | |
foreach ($grp in $GroupMemberObject) { | |
[array]$GroupMembership += Get-ADAllUserGroupMembership -Server $Server -GroupName $grp | |
} | |
return $GroupMembership | Sort-Object -Unique | |
} | |
function Invoke-CheckResetUserPasswordRight { | |
<# | |
.SYNOPSIS | |
Retrieve the users that the specified users are able to reset the password. | |
.EXAMPLE | |
PS> Invoke-CheckResetUserPasswordRight -Server 10.10.10.10 -Users User1 | |
PS> Invoke-CheckResetUserPasswordRight -Server 10.10.10.10 -Users User1 -Filter 'enabled -eq $true' | |
PS> Invoke-CheckResetUserPasswordRight -Server 10.10.10.10 -Users User1 -Filter "Name -like '*user*'" | |
PS> Invoke-CheckResetUserPasswordRight -Server 10.10.10.10 -Users User1,User2 -SearchBase "OU=Admins,DC=lab,DC=local" | |
PS> Invoke-CheckResetUserPasswordRight -Server 10.10.10.10 -Users User1,User2,User3 -NoGroupCheck -OnlyResult | |
.PARAMETER Server | |
Domain Controller where to run commands. | |
.PARAMETER Users | |
List of users to check. | |
.PARAMETER Filter | |
Filter applied to the Get-AdUser function. | |
.PARAMETER Filter | |
Apply a search base to the function Get-AdUser. | |
.PARAMETER OnlyResults | |
Display only the samAccountName of users where specified users can reset the password. | |
.PARAMETER OnlyResults | |
Search only direct right to reset password and do not include groups of the user. | |
#> | |
[CmdletBinding()] | |
[OutputType([hashtable])] | |
param( | |
[parameter(mandatory=$True)] | |
[ValidateNotNullOrEmpty()] | |
[string]$Server, | |
[parameter(mandatory=$True)] | |
[ValidateNotNullOrEmpty()] | |
[array]$Users, | |
[parameter(mandatory=$False)] | |
[string]$Filter = "*", | |
[parameter(mandatory=$False)] | |
[ValidateNotNullOrEmpty()] | |
[string]$SearchBase = "", | |
[switch]$OnlyResults, | |
[switch]$NoGroupCheck | |
) | |
try { | |
Import-Module ActiveDirectory | |
} | |
catch { | |
Write-Host "[!] Please install the ActiveDirectory module" | |
return | |
} | |
$ResultRestPasswordRight = @() | |
$objects = @() | |
# Default values for ObjectType GUID - CN=User-Force-Change-Password,CN=Extended-Rights,CN=Configuration,DC=lab,DC=local | |
$RestPasswordRight = "00299570-246d-11d0-a768-00aa006e0529" | |
#$ChangePasswordRight = "ab721a53-1e2f-11d0-9819-00aa0040529b" | |
$GenericAllRight = "00000000-0000-0000-0000-000000000000" | |
# Mount the AD as drive in order to get ACL on its objects | |
Write-Output "[+] Mount AD drive" | |
New-PSDrive -Name AD -PSProvider ActiveDirectory -Root "//RootDSE/" -Server $Server | Out-Null | |
# Get user information | |
foreach ($User in $Users) { | |
Echo "[+] Get User informations for $User" | |
$userInfo = Get-ADUser -Server $Server -Identity $User -Properties MemberOf | |
if ($userInfo -eq $null) { | |
return | |
} | |
[array]$objects += $userInfo | |
$userGroups = ($userInfo).MemberOf | |
if ($NoGroupCheck.IsPresent -eq $True) { | |
break | |
} | |
Write-Output "[+] Get groups for $User" | |
($userGroups) | ForEach-Object { | |
[array]$objects += Get-ADAllUserGroupMembership -Server $Server -GroupName $_ | |
} | |
if ($userGroups.count -ge 1) { | |
Write-Output "[+] $User belongs to :" | |
($objects[1..($objects.Length-1)]) | ForEach-Object { | |
Write-Output " - [$($_.objectSid)] $($_.samAccountName)" | |
} | |
} else { | |
Write-Output " [+] $User does not belong to any group." | |
} | |
$objects = ($objects | Sort-Object -Unique) | |
} | |
Write-Output "[+] Get all users" | |
if ($SearchBase -ne "") { | |
$allUsers = Get-ADUser -Server $Server -Filter $Filter -SearchBase $SearchBase | |
} else { | |
$allUsers = Get-ADUser -Server $Server -Filter $Filter | |
} | |
Write-Output "[+] Run search on $($allUsers.count) users at $(Get-Date)" | |
($allUsers) | ForEach-Object { | |
$targetUser = $_ | |
# Get ACL to reset password right | |
try { | |
$aclResetPassword = ((Get-Acl "AD:\$($targetUser.DistinguishedName)" | Select-object Access).access| Where-Object {$_.ObjectType -eq $RestPasswordRight -or $_.InheritedObjectType -eq $ResetPasswordRight -or $_.ObjectType -eq $GenericAllRight}) | |
} | |
catch { } | |
($objects) | ForEach-Object { | |
$object = $_ | |
$acl = $aclResetPassword | Where-Object {$_.IdentityReference -like "*$($object.SamAccountName)" -or $_.IdentityReference -eq $object.SID} | |
if ($acl -ne $null) { | |
$properties = @{ | |
From = $object.samAccountName | |
PasswordResetRight = $true | |
User = $targetUser.samAccountName | |
UserIsEnabled = $targetUser.Enabled | |
} | |
$obj = New-Object -TypeName psobject -Property $properties | |
$ResultRestPasswordRight += $obj | |
} | |
} | |
} | |
Write-Output "[+] Finished search on $($allUsers.count) users at $(Get-Date)" | |
if ($OnlyResults -eq $True) { | |
return ($ResultRestPasswordRight).User | Sort-Object -Unique | |
} | |
if ($ResultRestPasswordRight.Length -ge 1) { | |
Write-Output "`r`n[+] CMD : Set-ADAccountPassword -Server $($Server) -identity User -Reset -NewPassword (ConvertTo-SecureString -AsPlainText 'Password' -Force)" | |
} | |
return $ResultRestPasswordRight | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment