Esempio n. 1
0
        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);
            }
        }
Esempio n. 3
0
        public void TwoHashes_WithSameData_AreSame()
        {
            var inputX = new byte[] { 0, 1, 2, 3, 4 };
            var inputY = new byte[] { 0, 1, 2, 3, 4 };

            var equalityComparer = new HashEqualityComparer();

            var x = Mock.Of <IHash>(m => m.Bytes == inputX);
            var y = Mock.Of <IHash>(m => m.Bytes == inputY);

            Assert.IsTrue(equalityComparer.Equals(x, y));
        }
Esempio n. 4
0
        public void TwoHashes_WithDifferentData_AreDifferent()
        {
            var inputX = new byte[] { 0, 1, 2, 3, 4 };
            var inputY = new byte[] { 1, 2, 3, 4, 5 };

            var equalityComparer = new HashEqualityComparer();

            var x = Mock.Of <IHash>(m => m.Bytes == inputX);
            var y = Mock.Of <IHash>(m => m.Bytes == inputY);

            Assert.IsFalse(equalityComparer.Equals(x, y));
        }
        /// <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);
            }
        }
 /// <summary>
 /// Constructor
 /// </summary>
 protected KeyConfigurationBase(ICountConfiguration <TCount> configuration, bool createValueFilter = true) :
     base(createValueFilter)
 {
     _countConfiguration = configuration;
     _getId  = GetIdImpl;
     _idHash = id =>
     {
         var res = BitConverter.ToInt32(_murmurHash.Hash(BitConverter.GetBytes(id)), 0);
         return(res == 0 ? 1 : res);
     };
     _hashes = (hash, hashCount) => ComputeHash(hash, BitConverter.ToInt32(_murmurHash.Hash(BitConverter.GetBytes(hash), 912345678), 0), hashCount, 1);
     //the hashSum value is an identity hash.
     _entityHash = e => IdHash(GetId(e));
     _isPure     = (d, p) => CountConfiguration.IsPure(d.Counts[p]) &&
                   HashEqualityComparer.Equals(d.HashSumProvider[p], IdHash(d.IdSumProvider[p]));
     _idAdd                = _idRemove = (id1, id2) => id1 ^ id2;
     _idIntersect          = (id1, id2) => id1 & id2;
     _hashIdentity         = 0;
     _idIdentity           = 0L;
     _hashAdd              = _hashRemove = (h1, h2) => h1 ^ h2;
     _hashIntersect        = (h1, h2) => h1 & h2;
     _idEqualityComparer   = EqualityComparer <long> .Default;
     _hashEqualityComparer = EqualityComparer <int> .Default;
 }
        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();
        }
Esempio n. 9
0
 public static bool SetValue(this Cursor cursor, Columnid columnId, byte[] newValue)
 {
     return(cursor.SetValue(columnId, newValue, HashEqualityComparer.GetInstance()));
 }
Esempio n. 10
0
        /// <summary>
        /// Returns a list of list of strings - each entry in the outer list contains a list of filenames of files with the same contents.
        /// </summary>
        /// <param name="startingDirectory">The directory in which to start searching</param>
        /// <param name="errors">A list into which to insert errors</param>
        /// <returns>A list of list of files whose contents are the same</returns>
        public List <List <string> > GetDups(string startingDirectory, out List <string> errors)
        {
            _errors = new List <string>();
            var hashingEngines = _parallel ? Enumerable.Range(0, Environment.ProcessorCount).Select(x => Task.Run(() => HashEngine())).ToList() : null;

            var stack = new Stack <string>();

            stack.Push(startingDirectory);

            while (stack.Any())
            {
                var dir = stack.Pop();
                foreach (var file in Directory.GetFiles(dir))
                {
                    var finfo = new FileInfo(file);
                    if (!_lengthToFilenames.TryGetValue(finfo.Length, out var fileList))
                    {
                        fileList = new List <FilenameAndHash>();
                        _lengthToFilenames.Add(finfo.Length, fileList);
                    }
                    fileList.Add(new FilenameAndHash {
                        Filename = file
                    });

                    // only compute the SHA-1 for the file if this is the second or subsequent file with this particular length.
                    // If this is the second file we also need to compute the SHA-1 for the first file:

                    if (fileList.Count > 1)
                    {
                        if (fileList.Count == 2)
                        {
                            _hashQueue.Add(fileList.First());
                        }
                        _hashQueue.Add(fileList.Last());
                    }
                }

                foreach (var subDir in Directory.GetDirectories(dir))
                {
                    stack.Push(subDir);
                }
            }

            _hashQueue.CompleteAdding();
            Task.WaitAll(hashingEngines.ToArray());

            var sha1Comparer             = new HashEqualityComparer();
            var duplicateEntriesByLength = _lengthToFilenames.Where(x => x.Value.Count > 1);

            // transform the length dictionary into an IEnumerable<ILookup<byte[]...note that we lose the dictionary key as
            // we are no longer interested in the length of the file. Also note that we check if a file actually **has** a computed
            // hash as it may not due to our inability to open it:
            var shaLookups = duplicateEntriesByLength.Select(x => x.Value.Where(y => y.HasComputedHash).ToLookup(z => z.Sha1, sha1Comparer));

            // transform each lookup into a list of lists (each "bucket in the lookup becomes a list) - so we then
            // we flatten the entire result to a list-of-lists - we could have done this with SelectMany:

            var dups = (from lookup in shaLookups                                            // each entry is a lookup "bucketed" by SHA1
                        from lubucket in lookup                                              // take each bucket where the number of items in the bucket is greater than 1
                        where lubucket.Count() > 1
                        let fileList = (from file in lubucket select file.Filename).ToList() // get all the items from the bucket, but we want ONLY THE FILENAME for each item
                                       select fileList).ToList();

            errors = _errors;
            return(dups);
        }
Esempio n. 11
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();
        }
Esempio n. 12
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);
        }
Esempio n. 13
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();
            }
        }
Esempio n. 14
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());
 }