I have created a script that will allow a user to change the password of another user (if given permission). The script uses ADSI and is only accessible through a shortcut that starts a power shell GUI. The code that I use to change the password is below.
$pwd = "Password1"
$user = (([adsisearcher]"(&(objectCategory=User)(samaccountname=$username))").findall()).properties.distinguishedname
$oUser = [adsi]“LDAP://$user”
$ouser.psbase.invoke(“SetPassword”,$pwd)
$ouser.psbase.CommitChanges()
The script itself is locked for editing and the only way for a user to access it is through the shortcut I have given them. A higher up coworker liked the script however was worried about Privilege escalation My question is this, If I restrict the password changing ability of a user to be only a certain OU would they be able to escalate their privileges through this script? The way our OU's are set up everyone is contained within their OU unless they are a supervisor or director. This script is only intended to be given to supervisors.
Edit: I realize that it would be beneficial for me to put the full code instead of just the password changing code. Here it is.
#---------------------------------------------------------[Initialisations]--------------------------------------------------------
# Init PowerShell Gui
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Hide PowerShell Console
Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'
$consolePtr = [Console.Window]::GetConsoleWindow()
[Console.Window]::ShowWindow($consolePtr, 0)
#---------------------------------------------------------[Form]--------------------------------------------------------
$stayopen = 3
while($stayopen -ne 2){
[System.Windows.Forms.Application]::EnableVisualStyles()
$LocalResetPassForm = New-Object system.Windows.Forms.Form
$LocalResetPassForm.ClientSize = '480,300'
$LocalResetPassForm.text = "Reset Staff Password"
$LocalResetPassForm.BackColor = "#ffffff"
$LocalResetPassForm.TopMost = $false
$Errorhandleform = New-Object system.Windows.Forms.Form
$Errorhandleform.ClientSize = '480,300'
$Errorhandleform.text = "Reset Staff Password"
$Errorhandleform.BackColor = "#ffffff"
$Errorhandleform.TopMost = $false
$Titel = New-Object system.Windows.Forms.Label
$Titel.text = "Reset Staff Password"
$Titel.AutoSize = $true
$Titel.width = 25
$Titel.height = 10
$Titel.location = New-Object System.Drawing.Point(20,20)
$Titel.Font = 'Microsoft Sans Serif,13'
$Description = New-Object system.Windows.Forms.Label
$Description.text = "Clicking Change Password will change the Password of the account to Password1 and unlock the user's account"
$Description.AutoSize = $false
$Description.width = 450
$Description.height = 50
$Description.location = New-Object System.Drawing.Point(20,50)
$Description.Font = 'Microsoft Sans Serif,10'
$Errorhandle = New-Object system.Windows.Forms.Label
$Errorhandle.text = "We are unable to find the Username you provided please try again."
$Errorhandle.AutoSize = $false
$Errorhandle.width = 450
$Errorhandle.height = 50
$Errorhandle.location = New-Object System.Drawing.Point(20,50)
$Errorhandle.Font = 'Microsoft Sans Serif,10'
$TryAgainBtn = New-Object system.Windows.Forms.Button
$TryAgainBtn.BackColor = "#ffffff"
$TryAgainBtn.text = "Try Again"
$TryAgainBtn.width = 140
$TryAgainBtn.height = 30
$TryAgainBtn.location = New-Object System.Drawing.Point(330,250)
$TryAgainBtn.Font = 'Microsoft Sans Serif,10'
$TryAgainBtn.ForeColor = "#000"
$TryAgainBtn.Visible = $true
$TryAgainBtn.DialogResult = [System.Windows.Forms.DialogResult]::OK
$TryAgainBtn.AcceptButton = $ResetPassBtn
$ResetPassBtn = New-Object system.Windows.Forms.Button
$ResetPassBtn.BackColor = "#ffffff"
$ResetPassBtn.text = "Change Password"
$ResetPassBtn.width = 140
$ResetPassBtn.height = 30
$ResetPassBtn.location = New-Object System.Drawing.Point(330,250)
$ResetPassBtn.Font = 'Microsoft Sans Serif,10'
$ResetPassBtn.ForeColor = "#000"
$ResetPassBtn.Visible = $true
$ResetPassBtn.DialogResult = [System.Windows.Forms.DialogResult]::OK
$LocalResetPassForm.AcceptButton = $ResetPassBtn
$LocalResetPassForm.Controls.Add($ResetPassBtn)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(20,100)
$label.Size = New-Object System.Drawing.Size(320,20)
$label.Text = 'Enter The Staff Members username in the space Below:'
$LocalResetPassForm.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(20,120)
$textBox.Size = New-Object System.Drawing.Size(300,20)
$LocalResetPassForm.Controls.Add($textBox)
$cancelBtn = New-Object system.Windows.Forms.Button
$cancelBtn.BackColor = "#ffffff"
$cancelBtn.text = "Cancel"
$cancelBtn.width = 90
$cancelBtn.height = 30
$cancelBtn.location = New-Object System.Drawing.Point(230,250)
$cancelBtn.Font = 'Microsoft Sans Serif,10'
$cancelBtn.ForeColor = "#000"
$cancelBtn.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$LocalResetPassForm.CancelButton = $cancelBtn
$LocalResetPassForm.Controls.Add($cancelBtn)
$LocalResetPassForm.controls.AddRange(@($Titel,$Description,$cancelBtn))
$LocalResetPassForm.Topmost = $true
$LocalResetPassForm.Add_Shown({$textBox.Select()})
$result = $LocalResetPassForm.ShowDialog()
$stayopen = 2
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$username = $textBox.Text
#find if user exists
$finduser = (([adsisearcher]"(&(objectCategory=User)(samaccountname=$username))").findall()).properties.distinguishedname
#if user does not exist
if (!$finduser)
{
#open error window and set try again button
$Errorhandleform.controls.AddRange(@($Errorhandle,$TryAgainBtn))
$tryagain = $Errorhandleform.ShowDialog()
if ($tryagain -eq [System.Windows.Forms.DialogResult]::OK)
{
$stayopen = 3
}
}
#Change the Password
$pwd = "Password1"
$user = (([adsisearcher]"(&(objectCategory=User)(samaccountname=$username))").findall()).properties.distinguishedname
$ouser = [adsi]“LDAP://$user”
$ouser.psbase.invoke(“SetPassword”,$pwd)
$ouser.lockoutTime = 0
$ouser.pwdLastSet = 0
$ouser.psbase.CommitChanges()
}
}
Additionnally the Users would only have access to a shortcut that has this line as the Target C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File "T:\Scripts\passwordgui.ps1"
Tried with above PowerShell and modified as well but it didn’t work for me
There is a workaround you can follow to allow a specific user to change the password of another user by giving the delegating permission of read and reset users password on that certain OU’s.
Step 1: Give delegated permission on OU’s to any specific user to change the password of the same OU’s Users.
Step 2: Allow Local on locally to that specific user to login into Active Directory User and computers and to reset the password of another Users of specific OU’s (on that you have given delegated permission).
Reference : Allow log on locally - security policy setting (Windows 10) - Windows security | Microsoft Docs
Steps 3: Login to the VM using with Specific user to reset the password of another user
Able to change the Password of OU’s user using one specific user