public static List <LDAPPasswordPolicy> GetFineGrainedPolicies(DirectoryEntry directoryObject) { var policies = new List <LDAPPasswordPolicy>(); var policySearch = new DirectorySearcher(directoryObject); policySearch.Filter = $"(objectclass=msDS-PasswordSettings)"; policySearch.PropertiesToLoad.Add("name"); policySearch.PropertiesToLoad.Add("msds-lockoutthreshold"); policySearch.PropertiesToLoad.Add("msds-psoappliesto"); policySearch.PropertiesToLoad.Add("msds-minimumpasswordlength"); policySearch.PropertiesToLoad.Add("msds-passwordhistorylength"); policySearch.PropertiesToLoad.Add("msds-lockoutobservationwindow"); policySearch.PropertiesToLoad.Add("msds-lockoutduration"); policySearch.PropertiesToLoad.Add("msds-minimumpasswordage"); policySearch.PropertiesToLoad.Add("msds-maximumpasswordage"); policySearch.PropertiesToLoad.Add("msds-passwordsettingsprecedence"); policySearch.PropertiesToLoad.Add("msds-passwordcomplexityenabled"); policySearch.PropertiesToLoad.Add("msds-passwordreversibleencryptionenabled"); var pwdPolicies = policySearch.FindAll(); foreach (SearchResult result in pwdPolicies) { var policy = new LDAPPasswordPolicy(result, true); policy.AppliesToUsers = GetPasswordPolicyUsers(policy, directoryObject); policies.Add(policy); } return(policies); }
public static void DisplayPolicyDetails(LDAPPasswordPolicy policy, List <LDAPPasswordPolicy> Policies, List <UserInfo> Users) { var count = DisplayPolicyUsers(policy.Name, Policies, Users, true); var lockoutDurationTs = new TimeSpan(policy.LockoutDuration * -1); var lockoutObservationWindowTs = new TimeSpan(policy.LockoutObservationWindow * -1); var MinimumPasswordAgeTs = new TimeSpan(policy.MinimumPasswordAge * -1); var MaximumPasswordAgeTs = new TimeSpan(policy.MaximumPasswordAge * -1); Console.WriteLine($"-----------------------------------"); Console.WriteLine($"Name: {policy.Name}"); Console.WriteLine($"Order Precedence: {policy.PasswordPrecendence}"); Console.WriteLine($"ADs Path: {policy.ADSPath}"); Console.WriteLine($"Is Fine Grained? {policy.IsFineGrained}"); if (policy.IsFineGrained) { Console.WriteLine($"Applied to: {policy.AppliesToUsers.Count} users"); } Console.WriteLine($"Minimum Password Length: {policy.MinimumPasswordLength}"); Console.WriteLine($"Lockout Threshold: {policy.LockoutThreshold}"); Console.WriteLine($"Lockout Duration: {string.Format("{0:%d}d {0:%h}h {0:%m}m {0:%s}s", lockoutDurationTs)}"); Console.WriteLine($"Lockout Observation Window: {string.Format("{0:%d}d {0:%h}h {0:%m}m {0:%s}s", lockoutObservationWindowTs)}"); Console.WriteLine($"Minimum / Maximum Password Age: {string.Format("{0:%d}d {0:%h}h {0:%m}m {0:%s}s", MinimumPasswordAgeTs)} / {string.Format("{0:%d}d {0:%h}h {0:%m}m {0:%s}s", MaximumPasswordAgeTs)}"); Console.WriteLine($"Password History Length: {policy.PasswordHistoryLength}"); Console.WriteLine($"Applies to: {count} users"); Console.WriteLine(); }
public static LDAPUserInfo ClassifyUser(this LDAPUserInfo user, LDAPPasswordPolicy policy) { user.PolicyName = policy.Name; if (policy.LockoutThreshold == 0) { user.UserState = Domain.UserState.SAFE_TO_SPRAY; return(user); } var now = DateTime.Now; var start = new DateTime(1900, 01, 01); var badPasswordCount = user.BadPasswordCount; var lockoutDurationTime = user.LockoutTime.AddTicks((policy.LockoutDuration * -1)); var observationTime = user.BadPasswordTime.AddTicks((policy.LockoutObservationWindow * -1)); if ((badPasswordCount == policy.LockoutThreshold) && (observationTime > now)) { user.UserState = Domain.UserState.LOCKED_OUT; } else if (badPasswordCount == (policy.LockoutThreshold - 1)) { user.UserState = Domain.UserState.PENDING_LOCK_OUT; } if (observationTime < now) { user.UserState = Domain.UserState.SAFE_TO_SPRAY; var diff = (policy.LockoutThreshold - 1); } else if ((badPasswordCount < (policy.LockoutThreshold - 1)) && (observationTime > now)) { user.UserState = Domain.UserState.SAFE_TO_SPRAY; var diff = (policy.LockoutThreshold - 1) - badPasswordCount; } if (lockoutDurationTime < start) { // Never locked out } if ((lockoutDurationTime > start) && (observationTime < now)) { // Was locked out } if ((badPasswordCount == (policy.LockoutThreshold - 1)) && (lockoutDurationTime < start) && (observationTime < now)) { // Almost locked out } if ((badPasswordCount > 0) && (badPasswordCount < (policy.LockoutThreshold - 1)) && (observationTime < now)) { // Prior failed attempts } return(user); }
public static List <string> GetPasswordPolicyUsers(LDAPPasswordPolicy policy, DirectoryEntry directoryObject) { Console.WriteLine($"[-] Retrieving users for policy: {policy.Name}"); var users = new List <string>(); policy.AppliesToDN.ForEach(a => { var groupSearch = new DirectorySearcher(directoryObject); groupSearch.Filter = $"(&(objectCategory=user)(memberOf={a}))"; groupSearch.PageSize = 1000; groupSearch.PropertiesToLoad.Add("sAMAccountName"); groupSearch.SearchScope = SearchScope.Subtree; var groupResults = groupSearch.FindAll(); if (groupResults.Count > 0) { for (var i = 0; i < groupResults.Count; i++) { var username = (string)groupResults[i].Properties["sAMAccountname"][0]; users.Add(username.ToLower()); } } else { var userSearch = new DirectorySearcher(directoryObject); userSearch.Filter = $"(&(objectCategory=user)(distinguishedName={a}))"; userSearch.PageSize = 1000; userSearch.PropertiesToLoad.Add("sAMAccountName"); userSearch.SearchScope = SearchScope.Subtree; var userResults = userSearch.FindOne(); if (userResults != null) { var username = (string)userResults.Properties["sAMAccountname"][0]; users.Add(username.ToLower()); } } }); return(users); }
static public LDAPPasswordPolicy GetDomainPolicy(DirectoryEntry directoryObject) { var searcher = new DirectorySearcher(directoryObject); searcher.SearchScope = SearchScope.Base; searcher.PropertiesToLoad.Add("name"); searcher.PropertiesToLoad.Add("msds-behavior-version"); searcher.PropertiesToLoad.Add("lockoutduration"); searcher.PropertiesToLoad.Add("lockoutthreshold"); searcher.PropertiesToLoad.Add("lockoutobservationwindow"); searcher.PropertiesToLoad.Add("minpwdlength"); searcher.PropertiesToLoad.Add("minpwdage"); searcher.PropertiesToLoad.Add("maxpwdage"); searcher.PropertiesToLoad.Add("pwdhistorylength"); searcher.PropertiesToLoad.Add("adspath"); searcher.PropertiesToLoad.Add("pwdproperties"); var result = searcher.FindOne(); var policy = new LDAPPasswordPolicy(result, false); policy.AppliesToUsers = new List <string>(); return(policy); }