Example #1
0
        public void SetDomainUsers()
        {
            DirectorySearch ds          = GetDirectorySearcher();
            List <string>   domainUsers = new List <string>();

            string[] ldapProperties = new string[] { "name", "adminCount", "sAMAccountName", "userAccountControl", "servicePrincipalName", "userPrincipalName" };
            string   ldapFilter     = "(&(objectClass=user)(objectCategory=person))";

            IEnumerable <SearchResultEntry> searchResultEntries = ds.QueryLdap(ldapFilter, ldapProperties, System.DirectoryServices.Protocols.SearchScope.Subtree);

            foreach (SearchResultEntry resEnt in searchResultEntries)
            {
                bool keepUser = false;
                try
                {
                    //busted account name
                    if (String.IsNullOrEmpty(resEnt.GetProperty("sAMAccountName")))
                    {
                        continue;
                    }

                    int  uacFlags;
                    bool success =
                        int.TryParse(resEnt.GetProperty("userAccountControl"),
                                     out uacFlags);
                    UserAccountControlFlags userAccFlags = (UserAccountControlFlags)uacFlags;

                    if (userAccFlags.HasFlag(UserAccountControlFlags.AccountDisabled))
                    {
                        continue;
                    }

                    string userName = resEnt.GetProperty("sAMAccountName");

                    if (userName.EndsWith("$"))
                    {
                        Mq.Trace("Skipping " + userName +
                                 " because it appears to be a computer or trust account.");
                        continue;
                    }

                    //skip mailboxy accounts - domains always have a billion of these.
                    if (userName.IndexOf("mailbox", StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        Mq.Trace("Skipping " + userName +
                                 " because it appears to be a mailbox.");
                        continue;
                    }

                    if (userName.IndexOf("mbx", StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        Mq.Trace("Skipping " + userName +
                                 " because it appears to be a mailbox.");
                        continue;
                    }

                    // if has an SPN, keep it
                    if (!keepUser && resEnt.GetProperty("servicePrincipalName") != null)
                    {
                        Mq.Trace("Adding " + userName +
                                 " to target list because it has an SPN");
                        keepUser = true;
                    }

                    // if it's got adminCount, keep it
                    if (!keepUser && resEnt.GetProperty("adminCount") == "1")
                    {
                        Mq.Trace("Adding " + userName +
                                 " to target list because it had adminCount=1.");
                        keepUser = true;
                    }

                    // if the password doesn't expire it's probably a service account
                    if (!keepUser && userAccFlags.HasFlag(UserAccountControlFlags.PasswordDoesNotExpire))
                    {
                        Mq.Trace("Adding " + userName +
                                 " to target list because password does not expire,  probably service account.");
                        keepUser = true;
                    }

                    if (!keepUser && userAccFlags.HasFlag(UserAccountControlFlags.DontRequirePreauth))
                    {
                        Mq.Trace("Adding " + userName +
                                 " to target list because it doesn't require Kerberos pre-auth.");
                        keepUser = true;
                    }

                    if (!keepUser && userAccFlags.HasFlag(UserAccountControlFlags.TrustedForDelegation))
                    {
                        Mq.Trace("Adding " + userName +
                                 " to target list because it is trusted for delegation.");
                        keepUser = true;
                    }

                    if (!keepUser && userAccFlags.HasFlag(UserAccountControlFlags
                                                          .TrustedToAuthenticateForDelegation))
                    {
                        Mq.Trace("Adding " + userName +
                                 " to target list because it is trusted for delegation.");
                        keepUser = true;
                    }

                    // Included patterns
                    if (!keepUser)
                    {
                        foreach (string str in MyOptions.DomainUserMatchStrings)
                        {
                            if (userName.ToLower().Contains(str.ToLower()))
                            {
                                Mq.Trace("Adding " + userName +
                                         " to target list because it contained " + str + ".");
                                keepUser = true;
                                break;
                            }
                        }
                    }


                    // Finished testing
                    if (!keepUser)
                    {
                        continue;
                    }

                    // Must have matched something
                    // For common/frequent names,  force fully-qualified strict formats
                    if (MyOptions.DomainUserStrictStrings.Contains(userName, StringComparer.OrdinalIgnoreCase))
                    {
                        Mq.Trace("Using strict formats for " + userName + ".");

                        domainUsers.Add(String.Format(@"{0}\{1}", _targetDomainNetBIOSName, userName));

                        if (!string.IsNullOrEmpty(resEnt.GetProperty("userPrincipalName")))
                        {
                            domainUsers.Add(resEnt.GetProperty("userPrincipalName"));
                        }

                        continue;
                    }

                    // Otherwise, go with the format preference from the config file
                    foreach (DomainUserNamesFormat dnuf in MyOptions.DomainUserNameFormats)
                    {
                        switch (dnuf)
                        {
                        case DomainUserNamesFormat.NetBIOS:
                            domainUsers.Add(String.Format(@"{0}\{1}", _targetDomainNetBIOSName, userName));
                            break;

                        case DomainUserNamesFormat.UPN:
                            if (!string.IsNullOrEmpty(resEnt.GetProperty("userPrincipalName")))
                            {
                                domainUsers.Add(resEnt.GetProperty("userPrincipalName"));
                            }
                            else
                            {
                                Mq.Trace("Adding " + userName + " with simple sAMAccountName because UPN is missing.");
                                domainUsers.Add(userName);
                            }
                            break;

                        case DomainUserNamesFormat.sAMAccountName:
                            domainUsers.Add(userName);
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    Mq.Trace(e.ToString());
                    continue;
                }
            }

            this._domainUsers = domainUsers;
        }
Example #2
0
        private void SetDomainUsersAndComputers()
        {
            if (!String.IsNullOrEmpty(MyOptions.TargetDc))
            {
                DomainControllers.Add(MyOptions.TargetDc);
            }
            else
            {
                GetDomainControllers();
            }

            List <string> domainComputers = new List <string>();
            List <string> domainUsers     = new List <string>();

            // we do this so if the first one fails we keep trying til we find a DC we can talk to.

            foreach (string domainController in DomainControllers)
            {
                try
                {
                    // TODO add support for user defined creds here.

                    using (DirectoryEntry entry = new DirectoryEntry("LDAP://" + domainController))
                    {
                        using (DirectorySearcher mySearcher = new DirectorySearcher(entry))
                        {
                            mySearcher.Filter = ("(objectClass=computer)");

                            // No size limit, reads all objects
                            mySearcher.SizeLimit = 0;

                            // Read data in pages of 250 objects. Make sure this value is below the limit configured in your AD domain (if there is a limit)
                            mySearcher.PageSize = 250;

                            // Let searcher know which properties are going to be used, and only load those
                            mySearcher.PropertiesToLoad.Add("name");
                            mySearcher.PropertiesToLoad.Add("dNSHostName");
                            mySearcher.PropertiesToLoad.Add("lastLogonTimeStamp");

                            foreach (SearchResult resEnt in mySearcher.FindAll())
                            {
                                // Note: Properties can contain multiple values.
                                if (resEnt.Properties["dNSHostName"].Count > 0)
                                {
                                    string computerName = (string)resEnt.Properties["dNSHostName"][0];
                                    domainComputers.Add(computerName);
                                }
                            }
                        }

                        this._domainComputers = domainComputers;

                        if (MyOptions.DomainUserRules)
                        {
                            // now users
                            using (DirectorySearcher mySearcher = new DirectorySearcher(entry))
                            {
                                mySearcher.Filter = ("(objectClass=user)");

                                // No size limit, reads all objects
                                mySearcher.SizeLimit = 0;

                                // Read data in pages of 250 objects. Make sure this value is below the limit configured in your AD domain (if there is a limit)
                                mySearcher.PageSize = 250;

                                // Let searcher know which properties are going to be used, and only load those
                                mySearcher.PropertiesToLoad.Add("name");
                                mySearcher.PropertiesToLoad.Add("adminCount");
                                mySearcher.PropertiesToLoad.Add("sAMAccountName");
                                mySearcher.PropertiesToLoad.Add("userAccountControl");

                                foreach (SearchResult resEnt in mySearcher.FindAll())
                                {
                                    try
                                    {
                                        //busted account name
                                        if (resEnt.Properties["sAMAccountName"].Count == 0)
                                        {
                                            continue;
                                        }

                                        int  uacFlags;
                                        bool succes =
                                            int.TryParse(resEnt.Properties["userAccountControl"][0].ToString(),
                                                         out uacFlags);
                                        UserAccountControlFlags userAccFlags = (UserAccountControlFlags)uacFlags;

                                        if (userAccFlags.HasFlag(UserAccountControlFlags.AccountDisabled))
                                        {
                                            continue;
                                        }

                                        string userName = (string)resEnt.Properties["sAMAccountName"][0];

                                        // skip computer accounts
                                        if (userName.EndsWith("$"))
                                        {
                                            continue;
                                        }

                                        if (userName.IndexOf("mailbox", StringComparison.OrdinalIgnoreCase) >= 0)
                                        {
                                            continue;
                                        }

                                        if (userName.IndexOf("mbx", StringComparison.OrdinalIgnoreCase) >= 0)
                                        {
                                            continue;
                                        }

                                        // if it's got adminCount, keep it
                                        if (resEnt.Properties["adminCount"].Count != 0)
                                        {
                                            if (resEnt.Properties["adminCount"][0].ToString() == "1")
                                            {
                                                Mq.Trace("Adding " + userName +
                                                         " to target list because it had adminCount=1.");
                                                domainUsers.Add(userName);
                                                continue;
                                            }
                                        }

                                        // if the password doesn't expire it's probably a service account
                                        if (userAccFlags.HasFlag(UserAccountControlFlags.PasswordDoesNotExpire))
                                        {
                                            Mq.Trace("Adding " + userName +
                                                     " to target list because I think it's a service account.");
                                            domainUsers.Add(userName);
                                            continue;
                                        }

                                        if (userAccFlags.HasFlag(UserAccountControlFlags.DontRequirePreauth))
                                        {
                                            Mq.Trace("Adding " + userName +
                                                     " to target list because I think it's a service account.");
                                            domainUsers.Add(userName);
                                            continue;
                                        }

                                        if (userAccFlags.HasFlag(UserAccountControlFlags.TrustedForDelegation))
                                        {
                                            Mq.Trace("Adding " + userName +
                                                     " to target list because I think it's a service account.");
                                            domainUsers.Add(userName);
                                            continue;
                                        }

                                        if (userAccFlags.HasFlag(UserAccountControlFlags
                                                                 .TrustedToAuthenticateForDelegation))
                                        {
                                            Mq.Trace("Adding " + userName +
                                                     " to target list because I think it's a service account.");
                                            domainUsers.Add(userName);
                                            continue;
                                        }

                                        // if it matches a string we like, keep it
                                        foreach (string str in MyOptions.DomainUserMatchStrings)
                                        {
                                            if (userName.ToLower().Contains(str.ToLower()))
                                            {
                                                Mq.Trace("Adding " + userName +
                                                         " to target list because it contained " + str + ".");
                                                domainUsers.Add(userName);
                                                break;
                                            }
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                        Mq.Trace(e.ToString());
                                        continue;
                                    }
                                }
                            }
                        }
                        this._domainUsers = domainUsers;
                    }

                    break;
                }
                catch (Exception e)
                {
                    Mq.Trace(e.ToString());
                    throw;
                }
            }
        }
Example #3
0
        public void SetDomainComputers(string LdapFilter)
        {
            DirectorySearch ds = GetDirectorySearcher();

            List <string> domainComputers = new List <string>();

            try
            {
                if (!MyOptions.DfsOnly)
                {
                    // if we aren't limiting the scan to DFS shares then let's get some computer targets.

                    List <string> ldapPropertiesList = new List <string> {
                        "name", "dNSHostName", "lastLogonTimeStamp"
                    };
                    string ldapFilter = LdapFilter;

                    // extremely dirty hack to break a sig I once saw for Snaffler's LDAP queries. ;-)
                    int num = random.Next(1, 5);
                    while (num > 0)
                    {
                        Guid guid = Guid.NewGuid();
                        ldapPropertiesList.Add(guid.ToString());
                        --num;
                    }
                    string[] ldapProperties = ldapPropertiesList.ToArray();

                    IEnumerable <SearchResultEntry> searchResultEntries = ds.QueryLdap(ldapFilter, ldapProperties, System.DirectoryServices.Protocols.SearchScope.Subtree);

                    // set a window of "the last 4 months" - if a computer hasn't logged in to the domain in 4 months it's probably gone.
                    DateTime validLltsWindow = DateTime.Now.AddMonths(-4);
                    foreach (SearchResultEntry resEnt in searchResultEntries)
                    {
                        int  uacFlags;
                        bool success =
                            int.TryParse(resEnt.GetProperty("userAccountControl"),
                                         out uacFlags);

                        UserAccountControlFlags userAccFlags = (UserAccountControlFlags)uacFlags;

                        if (userAccFlags.HasFlag(UserAccountControlFlags.AccountDisabled))
                        {
                            continue;
                        }

                        try
                        {
                            // get the last logon timestamp value as a datetime
                            string lltsString = resEnt.GetProperty("lastlogontimestamp");
                            long   lltsLong;
                            long.TryParse(lltsString, out lltsLong);
                            DateTime lltsDateTime = DateTime.FromFileTime(lltsLong);
                            // compare it to our window, and if lltsDateTime is older, skip the computer acct.
                            if (lltsDateTime <= validLltsWindow)
                            {
                                continue;
                            }
                        }
                        catch (Exception e)
                        {
                            Mq.Error("Error calculating lastLogonTimeStamp for computer account " + resEnt.DistinguishedName);
                        }

                        if (!String.IsNullOrEmpty(resEnt.GetProperty("dNSHostName")))
                        {
                            string computerName = resEnt.GetProperty("dNSHostName");
                            domainComputers.Add(computerName);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Mq.Trace(e.ToString());
            }

            this._domainComputers = domainComputers;
        }