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()));
 }
Exemple #7
0
        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();
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        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();
            }
        }
Exemple #10
0
        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());
 }