当用户使用 ADSI 脚本时防止权限升级
Prevent privilege escalation when a user utilizes an ADSI script
我创建了一个脚本,允许用户更改另一个用户的密码(如果获得许可)。该脚本使用 ADSI,只能通过启动电源 shell GUI 的快捷方式访问。我用来更改密码的代码如下。
$pwd = "Password1"
$user = (([adsisearcher]"(&(objectCategory=User)(samaccountname=$username))").findall()).properties.distinguishedname
$oUser = [adsi]“LDAP://$user”
$ouser.psbase.invoke(“SetPassword”,$pwd)
$ouser.psbase.CommitChanges()
脚本本身已被锁定以供编辑,用户访问它的唯一方法是通过我给他们的快捷方式。一位上级同事喜欢该脚本,但担心权限提升 我的问题是,如果我将用户的密码更改能力限制为仅某个 OU,他们是否能够通过该脚本提升权限?我们的 OU 的设置方式是每个人都包含在他们的 OU 中,除非他们是主管或董事。此脚本仅供主管使用。
编辑:我意识到放置完整代码而不只是密码更改代码对我来说是有益的。在这里。
#---------------------------------------------------------[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()
}
}
此外,用户只能访问将此行作为目标的快捷方式 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File "T:\Scripts\passwordgui.ps1"
尝试使用上述 PowerShell 并进行了修改,但它对我不起作用
您可以遵循一种解决方法,通过授予特定 OU 的读取和重置用户密码的委派权限,允许特定用户更改其他用户的密码。
步骤 1:将 OU 的委派权限授予任何特定用户以更改同一 OU 用户的密码。
步骤 2:允许 Local on locally 该特定用户登录到 Active Directory 用户和计算机并重置密码特定 OU 的另一个用户(您已授予委派权限)。
参考:Allow log on locally - security policy setting (Windows 10) - Windows security | Microsoft Docs
步骤 3:使用特定用户登录 VM 以重置另一个用户的密码
可以使用一个特定用户更改 OU 用户的密码
我创建了一个脚本,允许用户更改另一个用户的密码(如果获得许可)。该脚本使用 ADSI,只能通过启动电源 shell GUI 的快捷方式访问。我用来更改密码的代码如下。
$pwd = "Password1"
$user = (([adsisearcher]"(&(objectCategory=User)(samaccountname=$username))").findall()).properties.distinguishedname
$oUser = [adsi]“LDAP://$user”
$ouser.psbase.invoke(“SetPassword”,$pwd)
$ouser.psbase.CommitChanges()
脚本本身已被锁定以供编辑,用户访问它的唯一方法是通过我给他们的快捷方式。一位上级同事喜欢该脚本,但担心权限提升 我的问题是,如果我将用户的密码更改能力限制为仅某个 OU,他们是否能够通过该脚本提升权限?我们的 OU 的设置方式是每个人都包含在他们的 OU 中,除非他们是主管或董事。此脚本仅供主管使用。
编辑:我意识到放置完整代码而不只是密码更改代码对我来说是有益的。在这里。
#---------------------------------------------------------[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()
}
}
此外,用户只能访问将此行作为目标的快捷方式 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File "T:\Scripts\passwordgui.ps1"
尝试使用上述 PowerShell 并进行了修改,但它对我不起作用
您可以遵循一种解决方法,通过授予特定 OU 的读取和重置用户密码的委派权限,允许特定用户更改其他用户的密码。
步骤 1:将 OU 的委派权限授予任何特定用户以更改同一 OU 用户的密码。
步骤 2:允许 Local on locally 该特定用户登录到 Active Directory 用户和计算机并重置密码特定 OU 的另一个用户(您已授予委派权限)。
参考:Allow log on locally - security policy setting (Windows 10) - Windows security | Microsoft Docs
步骤 3:使用特定用户登录 VM 以重置另一个用户的密码
可以使用一个特定用户更改 OU 用户的密码