绕过域策略的强制密码历史
Contents
前言
域策略通常会设置强制密码历史,比如多少次密码不允许重复。
但对于Email、OA、SVN、Git等各种用到LDAP域认证来实现SSO的服务来说,密码都要重新改一遍,确实很麻烦。
安全上去,便利下来。
于是曾几何时,写了个ps脚本,通过不断设置随机密码,来绕过密码历史的次数限制,这样就可以继续沿用以前的密码了。
使用步骤
- 对于未加域的用户,cmd输入:runas /netonly /noprofile /user:YourCorp.com\YourUserName powershell
- 保存下面的代码到ecp.ps1,然后调用:Import-Module ecp.ps1; ECP YourUserName NewPassword
- 提示:这里可以使用AdFind工具来查看域策略,例如:AdFind.exe -h YourCorp.com -s base -b DC=YourCorp,DC=com ,pwdHistoryLength就是强制密码历史次数
$LDAP_ROOT = 'LDAP://DC=YourCorp,DC=com' //这里改成你所在的域
function GetUserLdapPath([string]$user)
{
$searcher = New-Object DirectoryServices.DirectorySearcher;
$searcher.Filter = "(&(objectCategory=Person)(sAMAccountName=$user))";
$searcher.SearchRoot = $LDAP_ROOT;
return $searcher.FindAll()[0].Path;
}
function GenRandomPassword()
{
Add-Type -AssemblyName System.Web;
$PasswordLength = 12; //这是生成的密码长度,对大多数域策略来说12位够了,也可以通过AdFind查询
$SpecialCharCount = 0; //特殊字符数量
return [System.Web.Security.Membership]::GeneratePassword($PasswordLength, $SpecialCharCount);
}
function ChangePassword([int]$rotation, [string]$user, [string]$old_psw, [string]$new_psw)
{
$ldap_user = GetUserLdapPath($user);
Write-Output "[User] $user [Ldap] $ldap_user";
if ([String]::IsNullOrEmpty($ldap_user)) {
Write-Output "[UserLdap] err";
return '';
}
$last_psw = $old_psw;
for ($i = 0; $i -lt $rotation; $i++) {
$rand_psw = GenRandomPassword;
([ADSI]$ldap_user).ChangePassword($last_psw, $rand_psw);
Write-Output "[Phase$i Password] $last_psw => $rand_psw";
$last_psw = $rand_psw;
}
([ADSI]$ldap_user).ChangePassword($last_psw, $new_psw);
Write-Output "[End Phase] $last_psw => $new_psw successfully.";
}
function ECP([string]$user, [string]$password)
{
ChangePassword 5 $user $password $password; //强制密码历史次数
}