private void GetUsers() { _logger.Log("[-] Querying for users..."); try { var userSearch = new DirectorySearcher(DirectoryEntry); userSearch.Filter = $"(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2){Config.FilterLDAP})"; userSearch.PageSize = 1000; userSearch.PropertiesToLoad.Add("sAMAccountName"); userSearch.PropertiesToLoad.Add("badPwdCount"); userSearch.PropertiesToLoad.Add("badPasswordTime"); userSearch.PropertiesToLoad.Add("lockoutTime"); userSearch.PropertiesToLoad.Add("lockoutDuration"); userSearch.PropertiesToLoad.Add("pwdLastSet"); userSearch.SearchScope = SearchScope.Subtree; var results = userSearch.FindAll(); if (results != null) { for (var i = 0; i < results.Count; i++) { LDAPPasswordPolicy policy; var user = new LDAPUserInfo(results[i]); policy = user.GetUserPolicy(Policies); user = user.ClassifyUser(policy); Users.Add(user); } _logger.Log($"[-] Total Users: {Users.Count}"); } else { _logger.Log("[-] Failed to retrieve the usernames from Active Directory; the script will exit."); Environment.Exit(0); } _logger.Log($"Queried {results.Count} users w/ {Policies.Count} password policies identified..."); } catch (Exception ex) { _logger.Log("[-] Failed to find or connect to Active Directory, or another issue occurred."); _logger.Log($"[-] Exception: {ex}"); Environment.Exit(0); } }
public static LDAPPasswordPolicy GetUserPolicy(this LDAPUserInfo user, List <LDAPPasswordPolicy> Policies) { var policy = Policies .Where(x => x.IsFineGrained && x.AppliesToUsers.Contains(user.Username, StringComparer.OrdinalIgnoreCase)) .OrderByDescending(y => y.PasswordPrecendence); if (policy.Count() > 0) { return(policy.First()); } else { return(Policies.First(x => !x.IsFineGrained)); } }
public static LDAPUserInfo ClassifyUser(this LDAPUserInfo user, LDAPPasswordPolicy policy) { user.PolicyName = policy.Name; 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 = UserState.LOCKED_OUT; } else if (badPasswordCount == (policy.LockoutThreshold - 1)) { user.UserState = UserState.PENDING_LOCK_OUT; } if (observationTime < now) { user.UserState = UserState.SAFE_TO_SPRAY; var diff = (policy.LockoutThreshold - 1); } else if ((badPasswordCount < (policy.LockoutThreshold - 1)) && (observationTime > now)) { user.UserState = 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); }