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 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 void GetUsers(string domain, string domainController = "", string ou = "") { if (string.IsNullOrEmpty(domainController)) { domainController = FindDomainController(domain); } string bindPath = BindPath(domain, domainController); //Console.WriteLine(bindPath); DirectoryEntry directoryObject = new DirectoryEntry(bindPath); List <LDAPPasswordPolicy> Policies = new List <LDAPPasswordPolicy>(); List <UserInfo> Users = new List <UserInfo>(); DirectorySearcher userSearcher = new DirectorySearcher(directoryObject); userSearcher.Filter = "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))"; userSearcher.PropertiesToLoad.Add("sAMAccountName"); userSearcher.PropertiesToLoad.Add("badPwdCount"); userSearcher.PropertiesToLoad.Add("badPasswordTime"); userSearcher.PropertiesToLoad.Add("lockoutTime"); userSearcher.PropertiesToLoad.Add("lockoutDuration"); userSearcher.PropertiesToLoad.Add("pwdLastSet"); userSearcher.SearchScope = SearchScope.Subtree; try { //pass policy Policies.Add(GetDomainPolicy(directoryObject)); var fineGrainedPolicies = GetFineGrainedPolicies(directoryObject); fineGrainedPolicies.ForEach(x => x.AppliesToUsers = GetPasswordPolicyUsers(x, directoryObject)); Policies.AddRange(fineGrainedPolicies); //users SearchResultCollection users = userSearcher.FindAll(); foreach (SearchResult user_ in users) { LDAPPasswordPolicy policy; var user = new LDAPUserInfo(user_); policy = user.GetUserPolicy(Policies); user = user.ClassifyUser(policy); Users.Add(user); } Console.WriteLine($"[*] {Users.Count} users & {Policies.Count} policies found"); Console.WriteLine("[*] Saving to users.json and policy.json to loot folder"); File.WriteAllText(Path.Combine("loot", "users.json"), new JavaScriptSerializer().Serialize(Users)); File.WriteAllText(Path.Combine("loot", "policy.json"), new JavaScriptSerializer().Serialize(Policies)); } catch (System.Runtime.InteropServices.COMException ex) { switch ((uint)ex.ErrorCode) { case 0x8007052E: throw new Exception("[-] Login error when retrieving usernames from dc \"" + domainController + "\"! Bad creds?"); case 0x8007203A: throw new Exception("[-] Error connecting with the dc \"" + domainController + "\"! Make sure that provided /domain or /dc are valid"); case 0x80072032: throw new Exception("[-] Invalid syntax in DN specification! Make sure that /ou is correct"); case 0x80072030: throw new Exception("[-] There is no such object on the server! Make sure that /ou is correct"); default: throw ex; } } catch (Exception e) { throw e; } }