Пример #1
0
        private void AddDnsAdmins(GraphObjectReference objectReference)
        {
            string[] properties = new string[] {
                "name",
                "objectSid"
            };
            bool dnsAdminFound = false;
            WorkOnReturnedObjectByADWS callback =
                (ADItem x) =>
            {
                objectReference.Objects[CompromiseGraphDataTypology.PrivilegedAccount].Add(new GraphSingleObject(x.ObjectSid.Value, GraphObjectReference.DnsAdministrators, CompromiseGraphDataObjectRisk.Medium));
                dnsAdminFound = true;
            };

            // we do a one level search just case the group is in the default position
            adws.Enumerate("CN=Users," + domainInfo.DefaultNamingContext, "(&(objectClass=group)(description=DNS Administrators Group))", properties, callback, "OneLevel");
            if (!dnsAdminFound)
            {
                adws.Enumerate("CN=Users," + domainInfo.DefaultNamingContext, "(&(objectClass=group)(sAMAccountName=DNSAdmins))", properties, callback, "OneLevel");
            }
            if (!dnsAdminFound)
            {
                // then full tree. This is an optimization for LDAP request
                adws.Enumerate(domainInfo.DefaultNamingContext, "(&(objectClass=group)(description=DNS Administrators Group))", properties, callback);
            }
            if (!dnsAdminFound)
            {
                adws.Enumerate(domainInfo.DefaultNamingContext, "(&(objectClass=group)(sAMAccountName=DNSAdmins))", properties, callback);
            }
        }
Пример #2
0
        public void Export(string filename)
        {
            ADDomainInfo domainInfo = null;

            using (ADWebService adws = new ADWebService(Server, Port, Credential))
            {
                domainInfo = adws.DomainInfo;


                DisplayAdvancement("Iterating through user objects (all except disabled ones)");
                string[] properties = new string[] { "DistinguishedName", "sAMAccountName", "userAccountControl", "whenCreated", "lastLogonTimestamp", };


                using (var sw = File.CreateText(filename))
                {
                    sw.WriteLine("SAMAccountName\tDN\tWhen Created\tLast Logon Timestamp");

                    WorkOnReturnedObjectByADWS callback =
                        (ADItem x) =>
                    {
                        sw.WriteLine(x.SAMAccountName + "\t" + x.DistinguishedName + "\t" + x.WhenCreated.ToString("u") + "\t" + x.LastLogonTimestamp.ToString("u") + "\t" + x.PwdLastSet.ToString("u"));
                    };
                    adws.Enumerate(domainInfo.DefaultNamingContext, "(&(objectClass=user)(objectCategory=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(sAMAccountName=krbtgt)))", properties, callback);
                }

                DisplayAdvancement("Done");
            }
        }
Пример #3
0
        private void BuildDirectDelegationData()
        {
            if (domainInfo.ForestFunctionality < 2)
            {
                return;
            }
            var map = new Dictionary <string, List <string> >(StringComparer.OrdinalIgnoreCase);
            WorkOnReturnedObjectByADWS callback =
                (ADItem aditem) =>
            {
                foreach (var d in aditem.msDSAllowedToDelegateTo)
                {
                    var spn = d.Split('/');
                    if (spn.Length < 2)
                    {
                        continue;
                    }
                    if (!map.ContainsKey(spn[1]))
                    {
                        map[spn[1]] = new List <string>();
                    }
                    var sid = aditem.ObjectSid.Value;
                    if (!map[spn[1]].Contains(sid))
                    {
                        map[spn[1]].Add(sid);
                    }
                }
            };

            adws.Enumerate(domainInfo.DefaultNamingContext,
                           "(&(msDS-AllowedToDelegateTo=*)((userAccountControl:1.2.840.113556.1.4.804:=16777216)))",
                           new string[] { "objectSid", "msDS-AllowedToDelegateTo" }, callback);
            RelationFactory.InitializeDelegation(map);
        }
Пример #4
0
        List <string> GetListOfComputerToExplore()
        {
            ADDomainInfo domainInfo = null;

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

            using (ADWebService adws = new ADWebService(Server, Port, Credential))
            {
                domainInfo = adws.DomainInfo;
                string[] properties = new string[] { "dNSHostName", "primaryGroupID" };


                WorkOnReturnedObjectByADWS callback =
                    (ADItem x) =>
                {
                    computers.Add(x.DNSHostName);
                };

                string filterClause = null;
                switch (ScanningMode)
                {
                case 3:
                    filterClause = "(!(operatingSystem=*server*))";
                    break;

                case 4:
                    filterClause = "(operatingSystem=*server*)";
                    break;
                }
                adws.Enumerate(domainInfo.DefaultNamingContext, "(&(ObjectCategory=computer)" + filterClause + "(!userAccountControl:1.2.840.113556.1.4.803:=2)(lastLogonTimeStamp>=" + DateTime.Now.AddDays(-60).ToFileTimeUtc() + "))", properties, callback);
            }
            return(computers);
        }
        private ADDomainInfo GetDomainInformation(ADWebService adws)
        {
            ADDomainInfo domainInfo = null;

            domainInfo = adws.DomainInfo;
            if (adws.useLdap)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Performance warning: using LDAP instead of ADWS");
                Console.ResetColor();
            }
            // adding the domain sid
            string[] properties = new string[] { "objectSid", };
            WorkOnReturnedObjectByADWS callback =
                (ADItem aditem) =>
            {
                domainInfo.DomainSid = aditem.ObjectSid;
            };

            adws.Enumerate(domainInfo.DefaultNamingContext,
                           "(&(objectClass=domain)(distinguishedName=" + domainInfo.DefaultNamingContext + "))",
                           properties, callback);
            // adding the domain Netbios name
            string[] propertiesNetbios = new string[] { "nETBIOSName" };
            adws.Enumerate("CN=Partitions," + domainInfo.ConfigurationNamingContext,
                           "(&(objectCategory=crossRef)(systemFlags:1.2.840.113556.1.4.803:=3)(nETBIOSName=*)(nCName=" + domainInfo.DefaultNamingContext + "))",
                           propertiesNetbios,
                           (ADItem aditem) =>
            {
                domainInfo.NetBIOSName = aditem.NetBIOSName;
            }
                           , "OneLevel");
            return(domainInfo);
        }
Пример #6
0
        public void Export(string filename)
        {
            DisplayAdvancement("Starting");

            using (ADWebService adws = new ADWebService(Server, Port, Credential))
            {
                string[] propertiesLaps = new string[] { "schemaIDGUID" };
                // note: the LDAP request does not contain ms-MCS-AdmPwd because in the old time, MS consultant was installing customized version of the attriute, * being replaced by the company name
                // check the oid instead ? (which was the same even if the attribute name was not)
                adws.Enumerate(adws.DomainInfo.SchemaNamingContext, "(name=ms-*-AdmPwd)", propertiesLaps, (ADItem aditem) =>
                {
                    LAPSSchemaId = aditem.SchemaIDGUID;
                }, "OneLevel");

                using (StreamWriter sw = File.CreateText(filename))
                {
                    sw.WriteLine("DistinguishedName\tIdentity\tAccessRule");
                    var domainInfo = adws.DomainInfo;
                    EnrichDomainInfo(adws, domainInfo);
                    BuildUserList(adws, domainInfo);

                    WorkOnReturnedObjectByADWS callback = ((ADItem x)
                                                           =>
                    {
                        if (x.NTSecurityDescriptor != null)
                        {
                            var Owner = x.NTSecurityDescriptor.GetOwner(typeof(SecurityIdentifier));
                            var match = MatchesUsersToCheck(Owner);
                            if (match != null)
                            {
                                sw.WriteLine(x.DistinguishedName + "\t" + match.Value.Value + "\tOwner");
                            }
                            foreach (ActiveDirectoryAccessRule accessrule in x.NTSecurityDescriptor.GetAccessRules(true, false, typeof(SecurityIdentifier)))
                            {
                                // ignore audit / denied ace
                                if (accessrule.AccessControlType != AccessControlType.Allow)
                                {
                                    continue;
                                }
                                match = MatchesUsersToCheck(accessrule.IdentityReference);
                                if (!match.HasValue)
                                {
                                    continue;
                                }
                                if (MatchesBadACL(accessrule))
                                {
                                    sw.WriteLine(x.DistinguishedName + "\t" + match.Value.Value + "\t" + accessrule.ActiveDirectoryRights.ToString());
                                }
                            }
                        }
                    }
                                                           );
                    DisplayAdvancement("Analyzing AD Objects");
                    adws.Enumerate(domainInfo.DefaultNamingContext, "(objectClass=*)", new string[] { "distinguishedName", "nTSecurityDescriptor" }, callback);
                    DisplayAdvancement("Analyzing files");
                    CheckFilePermission(domainInfo, sw, adws);
                    DisplayAdvancement("Done");
                }
            }
        }
        private ADItem Search(ADWebService adws, ADDomainInfo domainInfo, string userName)
        {
            ADItem output = null;
            WorkOnReturnedObjectByADWS callback =
                (ADItem aditem) =>
            {
                output = aditem;
            };

            if (userName.StartsWith("S-1-5"))
            {
                adws.Enumerate(domainInfo.DefaultNamingContext,
                               "(objectSid=" + ADConnection.EncodeSidToString(userName) + ")",
                               properties, callback);
                if (output != null)
                {
                    return(output);
                }
            }
            if (userName.StartsWith("CN=") && userName.EndsWith(domainInfo.DefaultNamingContext))
            {
                adws.Enumerate(domainInfo.DefaultNamingContext,
                               "(distinguishedName=" + ADConnection.EscapeLDAP(userName) + ")",
                               properties, callback);
                if (output != null)
                {
                    return(output);
                }
            }
            if (userName.Length <= 20)
            {
                adws.Enumerate(domainInfo.DefaultNamingContext,
                               "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" + ADConnection.EscapeLDAP(userName) + "))",
                               properties, callback);
                if (output != null)
                {
                    return(output);
                }
            }
            adws.Enumerate(domainInfo.DefaultNamingContext,
                           "(cn=" + ADConnection.EscapeLDAP(userName) + ")",
                           properties, callback);
            if (output != null)
            {
                return(output);
            }
            adws.Enumerate(domainInfo.DefaultNamingContext,
                           "(displayName=" + ADConnection.EscapeLDAP(userName) + ")",
                           properties, callback);
            if (output != null)
            {
                return(output);
            }
            return(output);
        }
Пример #8
0
        public void Export(string filename)
        {
            DisplayAdvancement("Starting");

            using (ADWebService adws = new ADWebService(Server, Port, Credential))
            {
                using (StreamWriter sw = File.CreateText(filename))
                {
                    sw.WriteLine("DistinguishedName\tIdentity\tAccessRule");
                    var domainInfo = adws.DomainInfo;
                    EnrichDomainInfo(adws, domainInfo);
                    BuildUserList(adws, domainInfo);

                    WorkOnReturnedObjectByADWS callback = ((ADItem x)
                                                           =>
                    {
                        if (x.NTSecurityDescriptor != null)
                        {
                            var Owner = x.NTSecurityDescriptor.GetOwner(typeof(SecurityIdentifier));
                            var match = MatchesUsersToCheck(Owner);
                            if (match != null)
                            {
                                sw.WriteLine(x.DistinguishedName + "\t" + match.Value.Value + "\tOwner");
                            }
                            foreach (ActiveDirectoryAccessRule accessrule in x.NTSecurityDescriptor.GetAccessRules(true, false, typeof(SecurityIdentifier)))
                            {
                                // ignore audit / denied ace
                                if (accessrule.AccessControlType != AccessControlType.Allow)
                                {
                                    continue;
                                }
                                match = MatchesUsersToCheck(accessrule.IdentityReference);
                                if (!match.HasValue)
                                {
                                    continue;
                                }
                                if (MatchesBadACL(accessrule))
                                {
                                    sw.WriteLine(x.DistinguishedName + "\t" + match.Value.Value + "\t" + accessrule.ActiveDirectoryRights.ToString());
                                }
                            }
                        }
                    }
                                                           );
                    DisplayAdvancement("Analyzing AD Objects");
                    adws.Enumerate(domainInfo.DefaultNamingContext, "(objectClass=*)", new string[] { "distinguishedName", "nTSecurityDescriptor" }, callback);
                    DisplayAdvancement("Analyzing files");
                    CheckFilePermission(domainInfo, sw);
                    DisplayAdvancement("Done");
                }
            }
        }
Пример #9
0
        private void EnrichDomainInfo(ADWebService adws, ADDomainInfo domainInfo)
        {
            // adding the domain sid
            string[] properties = new string[] { "objectSid", };
            WorkOnReturnedObjectByADWS callback =
                (ADItem aditem) =>
            {
                domainInfo.DomainSid = aditem.ObjectSid;
            };

            adws.Enumerate(domainInfo.DefaultNamingContext,
                           "(&(objectClass=domain)(distinguishedName=" + domainInfo.DefaultNamingContext + "))",
                           properties, callback);
        }
        private void ExportPrimaryGroupData(ADWebService adws, ADDomainInfo domainInfo, RelationFactory relationFactory, List <int> primaryGroupIDs)
        {
            WorkOnReturnedObjectByADWS callback =
                (ADItem aditem) =>
            {
                relationFactory.AnalyzeADObject(aditem);
            };

            foreach (int id in primaryGroupIDs)
            {
                adws.Enumerate(domainInfo.DefaultNamingContext,
                               "(primaryGroupID=" + id + ")",
                               properties, callback);
            }
        }
        private void ExportSIDData(ADWebService adws, ADDomainInfo domainInfo, RelationFactory relationFactory, List <string> sids)
        {
            WorkOnReturnedObjectByADWS callback =
                (ADItem aditem) =>
            {
                relationFactory.AnalyzeADObject(aditem);
            };

            foreach (string sid in sids)
            {
                adws.Enumerate(domainInfo.DefaultNamingContext,
                               "(objectSid=" + ADConnection.EncodeSidToString(sid) + ")",
                               properties, callback);
            }
        }
        private void ExportCNData(ADWebService adws, ADDomainInfo domainInfo, RelationFactory relationFactory, List <string> cns)
        {
            WorkOnReturnedObjectByADWS callback =
                (ADItem aditem) =>
            {
                relationFactory.AnalyzeADObject(aditem);
            };

            foreach (string cn in cns)
            {
                adws.Enumerate(domainInfo.DefaultNamingContext,
                               "(distinguishedName=" + ADConnection.EscapeLDAP(cn) + ")",
                               properties, callback);
            }
        }
Пример #13
0
        private Dictionary <uint, string> BuildAllAttributeDictionnary(ADWebService adws)
        {
            var output = new Dictionary <uint, string>();

            string[] properties = new string[] { "lDAPDisplayName", "attributeID" };

            WorkOnReturnedObjectByADWS callback =
                (ADItem x) =>
            {
                output[TransformOidToAttId(x.AttributeID, x.lDAPDisplayName)] = x.lDAPDisplayName;
            };

            adws.Enumerate(adws.DomainInfo.SchemaNamingContext, "(&(objectclass=attributeSchema)(lDAPDisplayName=*))", properties, callback, "Subtree");
            return(output);
        }
Пример #14
0
        private ADItem Search(ADWebService adws, ADDomainInfo domainInfo, string userName)
        {
            ADItem output = null;

            string[] properties = new string[] {
                "distinguishedName",
                "displayName",
                "name",
                "objectSid",
            };
            WorkOnReturnedObjectByADWS callback =
                (ADItem aditem) =>
            {
                output = aditem;
            };

            if (userName.StartsWith("S-1-5"))
            {
                adws.Enumerate(domainInfo.DefaultNamingContext,
                               "(objectSid=" + ADConnection.EncodeSidToString(userName) + ")",
                               properties, callback);
            }

            adws.Enumerate(domainInfo.DefaultNamingContext,
                           "(sAMAccountName=" + ADConnection.EscapeLDAP(userName) + ")",
                           properties, callback);
            if (output != null)
            {
                return(output);
            }
            adws.Enumerate(domainInfo.DefaultNamingContext,
                           "(cn=" + ADConnection.EscapeLDAP(userName) + ")",
                           properties, callback);
            if (output != null)
            {
                return(output);
            }
            adws.Enumerate(domainInfo.DefaultNamingContext,
                           "(displayName=" + ADConnection.EscapeLDAP(userName) + ")",
                           properties, callback);
            if (output != null)
            {
                return(output);
            }
            return(output);
        }
Пример #15
0
		List<string> GetListOfComputerToExplore()
		{
			ADDomainInfo domainInfo = null;

			List<string> computers = new List<string>();
			using (ADWebService adws = new ADWebService(Server, Port, Credential))
			{
				domainInfo = adws.DomainInfo;
				string[] properties = new string[] { "dNSHostName", "primaryGroupID" };


				WorkOnReturnedObjectByADWS callback =
					(ADItem x) =>
					{
						computers.Add(x.DNSHostName);
					};

				adws.Enumerate(domainInfo.DefaultNamingContext, "(&(ObjectCategory=computer)(!userAccountControl:1.2.840.113556.1.4.803:=2)(lastLogonTimeStamp>=" + DateTime.Now.AddDays(-40).ToFileTimeUtc() + "))", properties, callback);
			}
			return computers;
		}
        private ADDomainInfo GetDomainInformation(ADWebService adws)
        {
            ADDomainInfo domainInfo = null;

            domainInfo = adws.DomainInfo;
            if (adws.useLdap)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Performance warning: using LDAP instead of ADWS");
                Console.ResetColor();
            }
            // adding the domain sid
            string[] properties = new string[] { "objectSid", };
            WorkOnReturnedObjectByADWS callback =
                (ADItem aditem) =>
            {
                domainInfo.DomainSid = aditem.ObjectSid;
            };

            adws.Enumerate(domainInfo.DefaultNamingContext,
                           "(&(objectClass=domain)(distinguishedName=" + domainInfo.DefaultNamingContext + "))",
                           properties, callback);
            return(domainInfo);
        }
Пример #17
0
 public void Enumerate(Action preambleWithReentry, string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope)
 {
     if (preambleWithReentry != null)
     {
         preambleWithReentry();
     }
     try
     {
         connection.Enumerate(distinguishedName, filter, properties, callback, scope);
     }
     catch (Exception ex)
     {
         Trace.WriteLine("Exception: " + ex.Message);
         Trace.WriteLine("StackTrace: " + ex.StackTrace);
         if (fallBackConnection == null)
         {
             throw;
         }
         Console.ForegroundColor = ConsoleColor.Yellow;
         Console.WriteLine("The AD query failed. Using the alternative protocol (" + fallBackConnection.GetType().Name + ")");
         Console.ResetColor();
         if (preambleWithReentry != null)
         {
             preambleWithReentry();
         }
         fallBackConnection.Enumerate(distinguishedName, filter, properties, callback, scope);
     }
 }
Пример #18
0
 public void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope)
 {
     Enumerate(null, distinguishedName, filter, properties, callback, scope);
 }
Пример #19
0
        public override void Export(string filename)
        {
            ADDomainInfo domainInfo = null;

            using (ADWebService adws = new ADWebService(Server, Port, Credential))
            {
                domainInfo = adws.DomainInfo;

                int export = 0;
                using (StreamWriter sw = File.CreateText(filename))
                {
                    var header = new List <string>();
                    var hcprop = AddData.GetProperties();
                    header.Add("DistinguishedName");
                    header.Add("sAMAccountName");
                    header.Add("scriptPath");
                    header.Add("primaryGroupID");
                    header.Add("lastLogonTimestamp");
                    header.Add("pwdLastSet");
                    header.Add("whenCreated");
                    header.Add("objectClass");
                    header.Add("userAccountControl");
                    header.AddRange(hcprop);

                    sw.WriteLine(string.Join("\t", header.ToArray()));


                    WorkOnReturnedObjectByADWS callback =
                        (ADItem x) =>
                    {
                        var d = new AddData();
                        HealthcheckAnalyzer.ProcessAccountData(d, x, false);
                        if ((++export % 500) == 0)
                        {
                            DisplayAdvancement("Exported: " + export);
                        }


                        var data = new List <string>();
                        data.Add(x.DistinguishedName);
                        data.Add(x.SAMAccountName);
                        data.Add(x.ScriptPath);
                        data.Add(x.PrimaryGroupID.ToString());
                        data.Add(x.LastLogonTimestamp.ToString("u"));
                        data.Add(x.PwdLastSet.ToString("u"));
                        data.Add(x.WhenCreated.ToString("u"));
                        data.Add(x.Class);
                        data.Add(x.UserAccountControl.ToString());
                        foreach (var p in hcprop)
                        {
                            data.Add(d.PropertiesSet.Contains(p).ToString());
                        }
                        sw.WriteLine(string.Join("\t", data.ToArray()));
                    };

                    DisplayAdvancement("Starting");
                    adws.Enumerate(domainInfo.DefaultNamingContext, HealthcheckAnalyzer.userFilter, HealthcheckAnalyzer.userProperties, callback, "SubTree");
                    DisplayAdvancement("Done");
                }
            }
        }
Пример #20
0
 public override void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope)
 {
     EnumerateInternalWithADWS(distinguishedName, filter, properties, scope,
                               (ItemListType items) =>
     {
         if (items != null)
         {
             foreach (XmlElement item in items.Any)
             {
                 ADItem aditem = null;
                 try
                 {
                     aditem = ADItem.Create(item);
                 }
                 catch (Exception ex)
                 {
                     Console.WriteLine("Warning: unable to process element (" + ex.Message + ")\r\n" + item.OuterXml);
                     Trace.WriteLine("Warning: unable to process element\r\n" + item.OuterXml);
                     Trace.WriteLine("Exception: " + ex.Message);
                     Trace.WriteLine(ex.StackTrace);
                 }
                 if (aditem != null)
                 {
                     callback(aditem);
                 }
             }
         }
     }
                               );
 }
Пример #21
0
 public abstract void EnumerateUsingWorkerThread(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope);
Пример #22
0
        public override void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope)
        {
            Trace.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] Running ldap enumeration");
            Trace.WriteLine("BaseObject=" + scope);
            Trace.WriteLine("Filter=" + filter);
            Trace.WriteLine("distinguishedName=" + distinguishedName);
            Trace.WriteLine("scope=" + scope);

            IntPtr result;
            var    r = ldap_search_s(connection, distinguishedName, StringToScope(scope), filter, properties, false, out result);

            if (r == -7)
            {
                // LDAP Error -7 (Bad search filter)
                // the filter contains a new attribute that the AD don't know - yet
                // just ignore it because the query will return nothing
                Trace.WriteLine("LDAP Error -7 (Bad search filter) - ignored");
                return;
            }
            if (r != 0)
            {
                throw new LDAPException(r);
            }
            try
            {
                var entry = ldap_count_entries(connection, result);
                var j     = result;
                for (int i = 0; i < entry; i++)
                {
                    var data = new Dictionary <string, berval[]>();
                    foreach (var prop in properties)
                    {
                        data[prop] = GetValueBin(j, prop);
                    }
                    var aditem = ADItem.Create(data);
                    callback(aditem);
                    j = ldap_next_entry(connection, j);
                }
            }
            finally
            {
                ldap_memfree(result);
            }
        }
Пример #23
0
        // translation securitydescriptor can take of lot of CPU
        public override void EnumerateUsingWorkerThread(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope)
        {
            BlockingQueue <ItemListType> queue = new BlockingQueue <ItemListType>(600);
            // background thread
            Thread workingthread = null;

            try
            {
                workingthread = new Thread(
                    () =>
                {
                    ItemListType items = null;
                    for (; ;)
                    {
                        if (!queue.Dequeue(out items))
                        {
                            break;
                        }
                        foreach (XmlElement item in items.Any)
                        {
                            ADItem aditem = ADItem.Create(item);
                            try
                            {
                                callback(aditem);
                            }
                            catch (Exception ex)
                            {
                                Trace.WriteLine("Exception in workerthread:" + ex.Message);
                                Trace.WriteLine(ex.StackTrace);
                            }
                        }
                    }
                    Trace.WriteLine("Exiting worker thread");
                }
                    );

                ReceiveItems callbackInternal = (ItemListType items)
                                                =>
                {
                    if (items != null)
                    {
                        queue.Enqueue(items);
                    }
                }
                ;

                workingthread.Start();
                EnumerateInternalWithADWS(distinguishedName, filter, properties, scope, callbackInternal);
                Trace.WriteLine("Done enumerating objects at: " + DateTime.Now);
                queue.Quit();
                workingthread.Join();
                Trace.WriteLine("Enumeration using worker thread complete");
            }
            finally
            {
                queue.Quit();
                if (workingthread != null)
                {
                    if (workingthread.ThreadState == System.Threading.ThreadState.Running)
                    {
                        workingthread.Abort();
                    }
                }
            }
        }
Пример #24
0
 public override void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope)
 {
     EnumerateInternalWithADWS(distinguishedName, filter, properties, scope,
                               (ItemListType items) =>
     {
         if (items != null)
         {
             foreach (XmlElement item in items.Any)
             {
                 ADItem aditem = ADItem.Create(item);
                 callback(aditem);
             }
         }
     }
                               );
 }
Пример #25
0
        private void EnumerateInternalWithLDAP(string distinguishedName, string filter, string[] properties, string scope, WorkOnReturnedObjectByADWS callback)
        {
            Trace.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] Running ldap enumeration");
            Trace.WriteLine("BaseObject=" + scope);
            Trace.WriteLine("Filter=" + filter);
            DirectoryEntry entry;
            int            numberOfObjectAlreadyExtracted = 0;

            try
            {
                if (Credential == null)
                {
                    entry = new DirectoryEntry(@"LDAP://" + Server + (Port == 0 ? null : ":" + Port) + "/" + distinguishedName, null, null, AuthenticationTypes.ServerBind | AuthenticationTypes.Secure | (Port == 636 ? AuthenticationTypes.SecureSocketsLayer:0));
                }
                else
                {
                    entry = new DirectoryEntry(@"LDAP://" + Server + (Port == 0 ? null : ":" + Port) + "/" + distinguishedName, Credential.UserName, Credential.Password, AuthenticationTypes.ServerBind | AuthenticationTypes.Secure | (Port == 636 ? AuthenticationTypes.SecureSocketsLayer : 0));
                }

                DirectorySearcher clsDS = new DirectorySearcher(entry);
                clsDS.SearchRoot = entry;
                clsDS.Filter     = filter;
                clsDS.PageSize   = 500;
                switch (scope)
                {
                case "OneLevel":
                    clsDS.SearchScope = SearchScope.OneLevel;
                    break;

                case "SubTree":
                    clsDS.SearchScope = SearchScope.Subtree;
                    break;

                case "Base":
                    clsDS.SearchScope = SearchScope.Base;
                    break;
                }

                bool nTSecurityDescriptor = false;
                foreach (string property in properties)
                {
                    clsDS.PropertiesToLoad.Add(property);
                    // prepare the flag for the ntsecuritydescriptor
                    if (String.Compare("nTSecurityDescriptor", property, true) == 0)
                    {
                        nTSecurityDescriptor = true;
                    }
                }
                Trace.WriteLine("[" + DateTime.Now.ToLongTimeString() + "]Calling FindAll");
                foreach (SearchResult sr in clsDS.FindAll())
                {
                    ADItem aditem = null;
                    try
                    {
                        aditem = ADItem.Create(sr, nTSecurityDescriptor);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Warning: unable to process element (" + ex.Message + ")\r\n" + sr.Path);
                        Trace.WriteLine("Warning: unable to process element\r\n" + sr.Path);
                        Trace.WriteLine("Exception: " + ex.Message);
                        Trace.WriteLine(ex.StackTrace);
                    }
                    if (aditem != null)
                    {
                        callback(aditem);
                    }
                    numberOfObjectAlreadyExtracted++;
                }
                Trace.WriteLine("[" + DateTime.Now.ToLongTimeString() + "]Enumeration successful");
            }
            catch (DirectoryServicesCOMException ex)
            {
                Trace.WriteLine("[" + DateTime.Now.ToLongTimeString() + "]An exception occured");
                Trace.WriteLine("ErrorCode: " + ex.ErrorCode);
                Trace.WriteLine("ExtendedError: " + ex.ExtendedError);
                Trace.WriteLine("ExtendedErrorMessage: " + ex.ExtendedErrorMessage);
                Trace.WriteLine("numberOfObjectAlreadyExtracted=" + numberOfObjectAlreadyExtracted);
                if (ex.ErrorCode == -2147023570)
                {
                    Trace.WriteLine("Translating DirectoryServicesCOMException to UnauthorizedAccessException");
                    throw new UnauthorizedAccessException(ex.Message);
                }
                throw;
            }
        }
Пример #26
0
 public override void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope)
 {
     EnumerateInternalWithLDAP(distinguishedName, filter, properties, scope, callback);
 }
Пример #27
0
        public void Export(string filename)
        {
            ADDomainInfo domainInfo = null;

            using (ADWebService adws = new ADWebService(Server, Port, Credential))
            {
                domainInfo = adws.DomainInfo;

                var computers = new List <Computer>();

                DisplayAdvancement("Resolving LAPS attribute");

                var      attributeAdmPwd = "ms-Mcs-AdmPwd";
                string[] propertiesLaps  = new string[] { "name" };
                // note: the LDAP request does not contain ms-MCS-AdmPwd because in the old time, MS consultant was installing customized version of the attriute, * being replaced by the company name
                // check the oid instead ? (which was the same even if the attribute name was not)
                adws.Enumerate(domainInfo.SchemaNamingContext, "(name=ms-*-AdmPwd)", propertiesLaps, (ADItem aditem) => { attributeAdmPwd = aditem.Name; }, "OneLevel");
                DisplayAdvancement("LAPS attribute is " + attributeAdmPwd);
                DisplayAdvancement("Iterating through computer objects (all except disabled ones)");
                string[] properties = new string[] { "DistinguishedName", "dNSHostName", "msDS-ReplAttributeMetaData", "whenCreated", "lastLogonTimestamp", "operatingSystem" };

                WorkOnReturnedObjectByADWS callback =
                    (ADItem x) =>
                {
                    var computer = new Computer()
                    {
                        DN                 = x.DistinguishedName,
                        DNS                = x.DNSHostName,
                        WhenCreated        = x.WhenCreated,
                        LastLogonTimestamp = x.LastLogonTimestamp,
                        OperatingSystem    = x.OperatingSystem,
                    };
                    if (x.msDSReplAttributeMetaData.ContainsKey(attributeAdmPwd))
                    {
                        computer.HasLAPS        = true;
                        computer.LAPSLastChange = x.msDSReplAttributeMetaData[attributeAdmPwd].LastOriginatingChange;
                    }
                    computers.Add(computer);
                };

                adws.Enumerate(domainInfo.DefaultNamingContext, "(&(ObjectCategory=computer)(!userAccountControl:1.2.840.113556.1.4.803:=2))", properties, callback);
                DisplayAdvancement("Looking for BitLocker information");
                foreach (var computer in computers)
                {
                    WorkOnReturnedObjectByADWS callbackBitLocker =
                        (ADItem x) =>
                    {
                        const string re1 = "CN=" +
                                           "([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\\\\\+|-)[0-9]{2}:[0-9]{2})\\{" +
                                           "([A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12})" +
                                           "\\},";

                        Regex r = new Regex(re1, RegexOptions.IgnoreCase | RegexOptions.Singleline);
                        Match m = r.Match(x.DistinguishedName);
                        if (m.Success)
                        {
                            computer.HasBitLocker = true;
                            // + sign has to be escaped in LDAP
                            var date = DateTime.Parse(m.Groups[1].ToString().Replace("\\+", "+"));
                            if (computer.BitLockerLastChange < date)
                            {
                                computer.BitLockerLastChange = date;
                            }
                            //string guid = m.Groups[2].ToString();
                        }
                        else
                        {
                            Trace.WriteLine("Object found but didn't match the regex: " + x.DistinguishedName);
                        }
                        var d = x.DistinguishedName;
                    };
                    adws.Enumerate(computer.DN, "(objectClass=*)", null, callbackBitLocker, "OneLevel");
                }
                DisplayAdvancement("Writing to file");
                using (var sw = File.CreateText(filename))
                {
                    sw.WriteLine("DN\tDNS\tWhen Created\tLast Logon Timestamp\tOperating System\tHasLAPS\tLAPS changed date\tHasBitlocker\tBitlocker change date");
                    foreach (var computer in computers)
                    {
                        sw.WriteLine(computer.DN + "\t" + computer.DNS + "\t" + computer.WhenCreated.ToString("u") + "\t" + computer.LastLogonTimestamp.ToString("u") + "\t" + computer.OperatingSystem + "\t" + computer.HasLAPS + "\t" + (computer.HasLAPS ? computer.LAPSLastChange.ToString("u") : "") + "\t" + computer.HasBitLocker + "\t" + (computer.HasBitLocker ? computer.BitLockerLastChange.ToString("u") : ""));
                    }
                }
                DisplayAdvancement("Done");
            }
        }
Пример #28
0
        private List <ADItem> Search(string userName, SearchType search = SearchType.Unknown)
        {
            List <ADItem> output        = new List <ADItem>();
            string        searchString  = null;
            string        namingContext = domainInfo.DefaultNamingContext;

            switch (search)
            {
            default:
            case SearchType.Unknown:
                if (userName.StartsWith("S-1-5"))
                {
                    output = Search(userName, SearchType.Sid);
                    if (output != null)
                    {
                        return(output);
                    }
                }
                if (userName.StartsWith("CN=") && userName.EndsWith(domainInfo.DefaultNamingContext))
                {
                    output = Search(userName, SearchType.DistinguishedName);
                    if (output != null)
                    {
                        return(output);
                    }
                }
                if (userName.Length <= 20)
                {
                    output = Search(userName, SearchType.SAMAccountName);
                    if (output != null)
                    {
                        return(output);
                    }
                }
                output = Search(userName, SearchType.Name);
                if (output != null)
                {
                    return(output);
                }
                output = Search(userName, SearchType.DisplayName);
                if (output != null)
                {
                    return(output);
                }
                return(null);

            case SearchType.Sid:
                searchString = "(|(objectSid=" + ADConnection.EncodeSidToString(userName) + ")(sidhistory=" + ADConnection.EncodeSidToString(userName) + "))";
                break;

            case SearchType.DistinguishedName:
                searchString = "(distinguishedName=" + ADConnection.EscapeLDAP(userName) + ")";
                if (userName.EndsWith(domainInfo.ConfigurationNamingContext, StringComparison.InvariantCultureIgnoreCase))
                {
                    namingContext = domainInfo.ConfigurationNamingContext;
                }
                else if (userName.EndsWith(domainInfo.SchemaNamingContext, StringComparison.InvariantCultureIgnoreCase))
                {
                    namingContext = domainInfo.SchemaNamingContext;
                }
                break;

            case SearchType.SAMAccountName:
                searchString = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" + ADConnection.EscapeLDAP(userName) + "))";
                break;

            case SearchType.Name:
                searchString = "(cn=" + ADConnection.EscapeLDAP(userName) + ")";
                break;

            case SearchType.DisplayName:
                searchString = "(displayName=" + ADConnection.EscapeLDAP(userName) + ")";
                break;

            case SearchType.PrimaryGroupId:
                searchString = "(primaryGroupID=" + userName + ")";
                break;
            }
            WorkOnReturnedObjectByADWS callback =
                (ADItem aditem) =>
            {
                output.Add(aditem);
            };

            adws.Enumerate(namingContext,
                           searchString,
                           properties.ToArray(), callback);
            return(output);
        }
Пример #29
0
 public void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback)
 {
     Enumerate(distinguishedName, filter, properties, callback, "Subtree");
 }
Пример #30
0
 public void EnumerateUsingWorkerThread(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope)
 {
     connection.EnumerateUsingWorkerThread(distinguishedName, filter, properties, callback, scope);
 }