public static bool AddMultiValue(this Cursor cursor, Columnid columnId, SecurityIdentifier[] valuesToAdd) { //NOTE: Must be in transaction and record must be in editing state. var binarySidHistory = valuesToAdd.Select(sid => sid.GetBinaryForm(true)); // TODO: Create method , bool[][]? return(cursor.AddMultiValue(columnId, binarySidHistory, HashEqualityComparer.GetInstance())); }
private void TestComputerDefaultPassword() { string defaultPassword = this.Account.SamAccountName.TrimEnd('$').ToLower(); byte[] defaultHash = NTHash.ComputeHash(defaultPassword); if (HashEqualityComparer.GetInstance().Equals(this.Account.NTHash, defaultHash)) { // The computer has the default password. this.result.DefaultComputerPassword.Add(this.Account.LogonName); } }
/// <summary> /// Re-encrypts the PEK list using a new boot key. /// </summary> /// <param name="oldBootKey">Current boot key, using which the PEK list is encrypted.</param> /// <param name="newBootKey">New boot key using which to encrypt the PEK list.</param> public void ChangeBootKey(byte[] oldBootKey, byte[] newBootKey) { // Validate Validator.AssertLength(oldBootKey, BootKeyRetriever.BootKeyLength, "oldBootKey"); if (newBootKey != null) { // This value is optional. No encryption is used when blank key is provided. Validator.AssertLength(newBootKey, BootKeyRetriever.BootKeyLength, "newBootKey"); } if (HashEqualityComparer.GetInstance().Equals(oldBootKey, newBootKey)) { // Both keys are the same so no change is required. return; } if (!this.context.DomainController.DomainNamingContextDNT.HasValue) { // The domain object must exist throw new DirectoryObjectNotFoundException("domain"); } // Execute using (var transaction = this.context.BeginTransaction()) { // Retrieve and decrypt var domain = this.FindObject(this.context.DomainController.DomainNamingContextDNT.Value); byte[] encryptedPEK; domain.ReadAttribute(CommonDirectoryAttributes.PEKList, out encryptedPEK); var pekList = new DataStoreSecretDecryptor(encryptedPEK, oldBootKey); // Encrypt with the new boot key (if blank, plain encoding is done instead) byte[] binaryPekList = pekList.ToByteArray(newBootKey); // Save the new value this.dataTableCursor.BeginEditForUpdate(); bool hasChanged = domain.SetAttribute(CommonDirectoryAttributes.PEKList, binaryPekList); this.CommitAttributeUpdate(domain, CommonDirectoryAttributes.PEKList, transaction, hasChanged, true); } }
protected override void ProcessRecord() { if (this.Account.Enabled == false && !this.IncludeDisabledAccounts.IsPresent) { // The account is disabled and should be skipped. string message = String.Format("Skipping account {0}, because it is disabled.", this.Account.LogonName); this.WriteVerbose(message); return; } // Verbose message string message2 = String.Format("Processing account {0}...", this.Account.LogonName); this.WriteVerbose(message2); if (this.Account.UserAccountControl.HasFlag(UserAccountControl.PasswordNeverExpires)) { // The account has a non-expiring password. this.result.PasswordNeverExpires.Add(this.Account.LogonName); } if (this.Account.UserAccountControl.HasFlag(UserAccountControl.UseDesKeyOnly)) { // Only DES kerberos encryption type is used with this account. this.result.DESEncryptionOnly.Add(this.Account.LogonName); } if (this.Account.AdminCount && !this.Account.UserAccountControl.HasFlag(UserAccountControl.NotDelegated)) { // This administrative account can be delegated. this.result.DelegatableAdmins.Add(this.Account.LogonName); } if (this.Account.UserAccountControl.HasFlag(UserAccountControl.PasswordNotRequired)) { // The account's password is not required. this.result.PasswordNotRequired.Add(this.Account.LogonName); } if (this.Account.UserAccountControl.HasFlag(UserAccountControl.PreAuthNotRequired)) { // Pre-authentication is not required for this account account. this.result.PreAuthNotRequired.Add(this.Account.LogonName); } if (this.Account.SamAccountType == SamAccountType.User && this.Account.ServicePrincipalName?.Length > 0 && !this.Account.SupportsKerberosAESEncryption) { // This is a kerberoastable user/service account, because it has a SPN configured, but has Kerberos AES encryption support disabled. this.result.Kerberoastable.Add(this.Account.LogonName); } if (this.Account.SupplementalCredentials != null) { if (this.Account.SupplementalCredentials.ClearText != null) { // Account has ClearText password (stored using reversible encryption) this.result.ClearTextPassword.Add(this.Account.LogonName); } if (this.Account.UserAccountControl.HasFlag(UserAccountControl.SmartCardRequired)) { // Smart card user if (this.Account.SupplementalCredentials.Kerberos != null) { // Accounts that require smart card authentication should have an empty supplemental credentials data structure. this.result.SmartCardUsersWithPassword.Add(this.Account.LogonName); } } else { // Not a smart card user if (this.Account.SupplementalCredentials.KerberosNew == null) { // Account is missing the AES kerberos keys. This is only OK if smart card auth is enforced for this account. this.result.AESKeysMissing.Add(this.Account.LogonName); } } } if (this.Account.LMHash != null) { // Account has the LM hash present. this.result.LMHash.Add(this.Account.LogonName); } if (this.Account.NTHash == null) { // The account has no password. this.result.EmptyPassword.Add(this.Account.LogonName); // All the remaining tests are based on NT hash, so we can skip them. return; } if (HashEqualityComparer.GetInstance().Equals(this.Account.NTHash, NTHash.Empty)) { // The account has an empty password. this.result.EmptyPassword.Add(this.Account.LogonName); // Skip the remaining tests, because they only make sense for non-empty passwords. return; } if (this.Account.SamAccountType == SamAccountType.Computer) { // Check if the computer has a default password. this.TestComputerDefaultPassword(); } else { // Computer accounts typically have random passwords, so we only perform the following tests for other account types like User or Trust. this.LookupAccountNTHashInSortedFile(); if (this.hashToAccountMap != null) { // Add the current account's NT hash to the map for further processing. this.AddAccountToHashMap(); } } }
protected override void BeginProcessing() { // Test the optional file path in advance to throw an early error. this.ResolveFilePath(this.WeakPasswordHashesFile); this.ResolveFilePath(this.WeakPasswordsFile); // Open the sorted weak password hashes file, as we will be searching it on-the-fly. string sortedHashesFile = this.ResolveFilePath(this.WeakPasswordHashesSortedFile); if (sortedHashesFile != null) { this.sortedHashFileSearcher = new SortedFileSearcher(sortedHashesFile); } if (this.ShouldTestWeakPasswordsInMemory || !this.SkipDuplicatePasswordTest.IsPresent) { // We need to cache NT hashes of all accounts for the Duplicate and Weak Password Tests. this.hashToAccountMap = new Dictionary <byte[], SortedSet <string> >(PasswordDictionaryInitialCapacity, HashEqualityComparer.GetInstance()); } // Initialize the test results. this.result = new PasswordQualityTestResult(); }
public static bool SetValue(this Cursor cursor, Columnid columnId, byte[] newValue) { return(cursor.SetValue(columnId, newValue, HashEqualityComparer.GetInstance())); }
protected override void BeginProcessing() { // Test the optional file path in advance to throw an early error. this.ResolveFilePath(this.WeakPasswordHashesFile); this.ResolveFilePath(this.WeakPasswordsFile); if (this.ShouldTestWeakPasswords || !this.SkipDuplicatePasswordTest.IsPresent) { // We need to cache NT hashes of all accounts for the Duplicate and Weak Password Tests. this.hashToAccountMap = new Dictionary <byte[], SortedSet <string> >(PasswordDictionaryInitialCapacity, HashEqualityComparer.GetInstance()); } // Initialize the test results. this.result = new PasswordQualityTestResult(); }
private bool processRecords() { foreach (DSAccount acc in accs) { if (acc.UserAccountControl.HasFlag(UserAccountControl.PasswordNeverExpires)) { accFindings["Password Never Expires"].Add(acc); } if (acc.UserAccountControl.HasFlag(UserAccountControl.UseDesKeyOnly)) { accFindings["Only DES Kerberos Encryption Used"].Add(acc); } if (acc.AdminCount && !acc.UserAccountControl.HasFlag(UserAccountControl.NotDelegated)) { accFindings["Admin Account can be Delegated"].Add(acc); } if (acc.UserAccountControl.HasFlag(UserAccountControl.PasswordNotRequired)) { accFindings["Password not Required"].Add(acc); } if (acc.UserAccountControl.HasFlag(UserAccountControl.PreAuthNotRequired)) { accFindings["Pre-authentication not Required"].Add(acc); } if (acc.SupplementalCredentials != null) { if (acc.SupplementalCredentials.ClearText != null) { string cleartext = acc.SupplementalCredentials.ClearText; accFindings["Password Stored in Cleartext"].Add(acc); } if (acc.SupplementalCredentials.KerberosNew == null) { accFindings["Account is Missing AES Kerberos Keys"].Add(acc); } } if (acc.LMHash != null) { accFindings["Account has LM Hash"].Add(acc); } if (acc.NTHash == null) { accFindings["Account has no Password"].Add(acc); } if (HashEqualityComparer.GetInstance().Equals(acc.NTHash, NTHash.Empty)) { accFindings["Account has an Empty Password"].Add(acc); } if (acc.SamAccountType == SamAccountType.Computer) { //check for default comp creds } string currHash = acc.NTHash.ToHex(); if (currHash != null && currHash.Length > 0) { if (!hashDict.ContainsKey(currHash)) { hashDict.Add(currHash, new List <DSAccount>()); } hashDict[currHash].Add(acc); } } return(true); }
protected override void ProcessRecord() { if (this.Account.Enabled == false && !this.IncludeDisabledAccounts.IsPresent) { // The account is disabled and should be skipped. // TODO: Move to resources. string message = String.Format("Skipping account {0}, because it is disabled.", this.Account.SamAccountName); this.WriteVerbose(message); return; } // Verbose message // TODO: Move to resources. string message2 = String.Format("Processing account {0}...", this.Account.SamAccountName); this.WriteVerbose(message2); if (this.Account.UserAccountControl.HasFlag(UserAccountControl.PasswordNeverExpires)) { // The account has a non-expiring password. this.result.PasswordNeverExpires.Add(this.Account.SamAccountName); } if (this.Account.UserAccountControl.HasFlag(UserAccountControl.UseDesKeyOnly)) { // Only DES kerbero encryption type is used with this account. this.result.DESEncryptionOnly.Add(this.Account.SamAccountName); } if (this.Account.AdminCount && !this.Account.UserAccountControl.HasFlag(UserAccountControl.NotDelegated)) { // This administrative account can be delegated. this.result.DelegatableAdmins.Add(this.Account.SamAccountName); } if (this.Account.UserAccountControl.HasFlag(UserAccountControl.PasswordNotRequired)) { // The account's password is not required. this.result.PasswordNotRequired.Add(this.Account.SamAccountName); } if (this.Account.UserAccountControl.HasFlag(UserAccountControl.PreAuthNotRequired)) { // Pre-authentication is not required for this account account. this.result.PreAuthNotRequired.Add(this.Account.SamAccountName); } if (this.Account.SupplementalCredentials != null) { if (this.Account.SupplementalCredentials.ClearText != null) { // Account has ClearText password (stored using reversible encryption) // Only reveal the password if explicitly asked to do so. string outputPassword = this.ShowPlainTextPasswords.IsPresent ? this.Account.SupplementalCredentials.ClearText : String.Empty; this.result.ClearTextPassword.Add(this.Account.SamAccountName, outputPassword); } if (this.Account.SupplementalCredentials.KerberosNew == null && !this.Account.UserAccountControl.HasFlag(UserAccountControl.SmartCardRequired)) { // Account is missing the AES kerberos keys. This is only OK if smart card auth is enforced for this account. this.result.AESKeysMissing.Add(this.Account.SamAccountName); } } if (this.Account.LMHash != null) { // Account has the LM hash present. this.result.LMHash.Add(this.Account.SamAccountName); } if (this.Account.NTHash == null) { // The account has no password. this.result.EmptyPassword.Add(this.Account.SamAccountName); // All the remaining tests are based on NT hash, so we can skip them. return; } if (HashEqualityComparer.GetInstance().Equals(this.Account.NTHash, NTHash.Empty)) { // The account has an empty password. this.result.EmptyPassword.Add(this.Account.SamAccountName); // Skip the remaining tests, because they only make sense for non-empty passwords. return; } if (this.Account.SamAccountType == SamAccountType.Computer) { // Check if the computer has a default password. this.TestComputerDefaultPassword(); } if (this.WeakPasswordHashes != null) { // Check if the account has a weak password. this.TestWeakHashes(); } if (!this.SkipDuplicatePasswordTest.IsPresent) { // Find password duplicates this.TestDuplicateHash(); } }
protected override void BeginProcessing() { // Perform some initialization. if (!this.SkipDuplicatePasswordTest.IsPresent) { this.duplicatePasswordDictionary = new Dictionary <byte[], StringCollection>(PasswordDictionaryInitialCapacity, HashEqualityComparer.GetInstance()); } this.result = new PasswordQualityTestResult(); }
protected override void BeginProcessing() { this.hashDictionary = new Dictionary <byte[], string>(HashEqualityComparer.GetInstance()); }