コード例 #1
0
        public GraphObjectReference ExportData(List <string> UsersToInvestigate)
        {
            ADDomainInfo         domainInfo      = null;
            RelationFactory      relationFactory = null;
            GraphObjectReference objectReference = null;

            DisplayAdvancement("Getting domain information (" + Server + ")");
            using (ADWebService adws = new ADWebService(Server, Port, Credential))
            {
                domainInfo = GetDomainInformation(adws);
                Storage.Initialize(domainInfo);
                Trace.WriteLine("Creating new relation factory");
                relationFactory = new RelationFactory(Storage, domainInfo, Credential);
                DisplayAdvancement("Exporting objects from Active Directory");
                objectReference = new GraphObjectReference(domainInfo);
                ExportReportData(adws, domainInfo, relationFactory, Storage, objectReference, UsersToInvestigate);
            }
            DisplayAdvancement("Inserting relations between nodes in the database");
            Trace.WriteLine("Inserting relations on hold");
            Storage.InsertRelationOnHold();
            Trace.WriteLine("Add trusted domains");
            AddTrustedDomains(Storage);
            Trace.WriteLine("Done");
            DisplayAdvancement("Export completed");
            DisplayAdvancement("Doing the analysis");
            return(objectReference);
        }
コード例 #2
0
 public ExportDataFromActiveDirectoryLive(ADDomainInfo domainInfo, ADWebService adws, NetworkCredential credential)
 {
     this.domainInfo = domainInfo;
     this.adws       = adws;
     Credential      = credential;
     Storage         = new LiveDataStorage();
 }
コード例 #3
0
ファイル: ScannerBase.cs プロジェクト: triplekill/pingcastle
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
 private void BuildUserList(ADWebService adws, ADDomainInfo domainInfo)
 {
     UsersToMatch = new List <KeyValuePair <SecurityIdentifier, string> >();
     if (UserList.Count == 0)
     {
         UsersToMatch.Add(new KeyValuePair <SecurityIdentifier, string>(new SecurityIdentifier("S-1-1-0"), "Everyone"));
         UsersToMatch.Add(new KeyValuePair <SecurityIdentifier, string>(new SecurityIdentifier("S-1-5-11"), "Authenticated Users"));
         UsersToMatch.Add(new KeyValuePair <SecurityIdentifier, string>(new SecurityIdentifier(domainInfo.DomainSid.Value + "-513"), "Domain Users"));
         UsersToMatch.Add(new KeyValuePair <SecurityIdentifier, string>(new SecurityIdentifier(domainInfo.DomainSid.Value + "-515"), "Domain Computers"));
         return;
     }
     foreach (var user in UserList)
     {
         var aditem = Search(adws, domainInfo, user);
         if (aditem == null)
         {
             DisplayAdvancement(user + " was not found");
             continue;
         }
         if (aditem.ObjectSid == null)
         {
             DisplayAdvancement(user + " has been found but it is not an object with a SID and thus cannot be searched for");
             continue;
         }
         UsersToMatch.Add(new KeyValuePair <SecurityIdentifier, string>(aditem.ObjectSid, user));
     }
     if (UsersToMatch.Count == 0)
     {
         throw new PingCastleException("The scanner has not ACL to search for");
     }
 }
コード例 #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");
                }
            }
        }
コード例 #7
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");
            }
        }
コード例 #8
0
        int AnalyzeMissingObjets(ADWebService adws, ADDomainInfo domainInfo, RelationFactory relationFactory, LiveDataStorage Storage)
        {
            int num = 0;

            while (true)
            {
                List <string> cns = Storage.GetCNToInvestigate();
                if (cns.Count > 0)
                {
                    num += cns.Count;
                    ExportCNData(adws, domainInfo, relationFactory, cns);
                }
                List <string> sids = Storage.GetSIDToInvestigate();
                if (sids.Count > 0)
                {
                    num += sids.Count;
                    ExportSIDData(adws, domainInfo, relationFactory, sids);
                }
                List <int> primaryGroupId = Storage.GetPrimaryGroupIDToInvestigate();
                if (primaryGroupId.Count > 0)
                {
                    num += primaryGroupId.Count;
                    ExportPrimaryGroupData(adws, domainInfo, relationFactory, primaryGroupId);
                }
                if (cns.Count == 0 && sids.Count == 0 && primaryGroupId.Count == 0)
                {
                    return(num);
                }
            }
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        private void ExportReportData(ADWebService adws, ADDomainInfo domainInfo, RelationFactory relationFactory, List <string> UsersToInvestigate)
        {
            List <string> sids = new List <string> {
                "S-1-5-32-548",
                "S-1-5-32-544",
                domainInfo.DomainSid.Value + "-512",
                domainInfo.DomainSid.Value + "-519",
                domainInfo.DomainSid.Value + "-518",
                domainInfo.DomainSid.Value + "-500",
                "S-1-5-32-551",
                domainInfo.DomainSid.Value + "-517",
                "S-1-5-32-569",
                domainInfo.DomainSid.Value + "-516",
                domainInfo.DomainSid.Value + "-498",
                domainInfo.DomainSid.Value + "-520",
                "S-1-5-32-557",
                domainInfo.DomainSid.Value + "-502",
                "S-1-5-32-556",
                "S-1-5-32-554",
                "S-1-5-32-550",
                domainInfo.DomainSid.Value,
                domainInfo.DomainSid.Value + "-521",
                "S-1-5-32-549",
            };
            ADItem aditem = null;

            foreach (string sid in sids)
            {
                aditem = Search(adws, domainInfo, sid);
                if (aditem != null)
                {
                    relationFactory.AnalyzeADObject(aditem);
                }
                else
                {
                    Trace.WriteLine("Unable to find the user: "******"Unable to find the user: " + user);
                }
            }

            AnalyzeMissingObjets(adws, domainInfo, relationFactory);
            relationFactory.InsertFiles();
            AnalyzeMissingObjets(adws, domainInfo, relationFactory);
        }
コード例 #11
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");
                }
            }
        }
コード例 #12
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);
        }
コード例 #13
0
        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);
            }
        }
コード例 #14
0
        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);
            }
        }
コード例 #15
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);
        }
コード例 #16
0
        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);
            }
        }
コード例 #17
0
        private void ExportReportData(ADWebService adws, ADDomainInfo domainInfo, IRelationFactory relationFactory, IDataStorage storage, GraphObjectReference objectReference, List <string> UsersToInvestigate)
        {
            ADItem aditem = null;

            foreach (var typology in objectReference.Objects.Keys)
            {
                var toDelete = new List <GraphSingleObject>();
                foreach (var obj in objectReference.Objects[typology])
                {
                    DisplayAdvancement("Working on " + obj.Description);
                    aditem = Search(adws, domainInfo, obj.Name);
                    if (aditem != null)
                    {
                        relationFactory.AnalyzeADObject(aditem);
                    }
                    else
                    {
                        Trace.WriteLine("Unable to find the user: "******"Working on " + user);
                aditem = Search(adws, domainInfo, user);
                if (aditem != null)
                {
                    string userKey = user;
                    if (aditem.ObjectSid != null)
                    {
                        userKey = aditem.ObjectSid.Value;
                    }
                    objectReference.Objects[Data.CompromiseGraphDataTypology.UserDefined].Add(new GraphSingleObject(userKey, user));
                    relationFactory.AnalyzeADObject(aditem);
                }
                else
                {
                    Trace.WriteLine("Unable to find the user: " + user);
                }
            }

            AnalyzeMissingObjets(adws, domainInfo, relationFactory, storage);
        }
コード例 #18
0
 private void ExportFilesData(ADWebService adws, ADDomainInfo domainInfo, IRelationFactory relationFactory, List <string> files)
 {
     if (Credential != null)
     {
         using (WindowsIdentity identity = NativeMethods.GetWindowsIdentityForUser(Credential, domainInfo.DnsHostName))
             using (var context = identity.Impersonate())
             {
                 ExportFilesDataWithImpersonation(adws, domainInfo, relationFactory, files);
                 context.Undo();
             }
     }
     else
     {
         ExportFilesDataWithImpersonation(adws, domainInfo, relationFactory, files);
     }
 }
コード例 #19
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);
        }
コード例 #20
0
        public void Export(string filename)
        {
            ADDomainInfo domainInfo = null;

            DisplayAdvancement("Starting");
            ADWebService.ConnectionType = ADConnectionType.LDAPOnly;

            using (ADWebService adws = new ADWebService(Server, Port, Credential))
            {
                DisplayAdvancement("Connected");
                domainInfo = adws.DomainInfo;
                DisplayAdvancement("Building a list of all OU");
                var exploration = adws.BuildOUExplorationList(domainInfo.DefaultNamingContext, 10);
                int currentOU   = 1;
                int error       = 0;
                using (StreamWriter sw = File.CreateText(filename))
                {
                    sw.WriteLine("OU\tstatus");
                    foreach (var ou in exploration)
                    {
                        DisplayAdvancement(" * Exporting OU=" + ou.OU + "(" + currentOU++ + "/" + exploration.Count + ") Type:" + ou.Scope);
                        try
                        {
                            adws.Enumerate(ou.OU, "(objectClass=*)", new string[] { "distinguishedName" }, (ADItem x) => { }, ou.Scope);
                            sw.WriteLine(ou.OU + "\tOK");
                        }
                        catch (DirectoryServicesCOMException ex)
                        {
                            if (ex.ExtendedError == 234)
                            {
                                error++;
                                Console.ForegroundColor = ConsoleColor.Red;
                                DisplayAdvancement("The OU " + ou.OU + " has a problem");
                                Console.ResetColor();
                                sw.WriteLine(ou.OU + "\tNot OK");
                            }
                        }
                        catch (Exception)
                        {
                        }
                    }
                }
                DisplayAdvancement(error + " error(s) found");
            }
        }
コード例 #21
0
        public void PerformAnalyze(HealthcheckData data, ADDomainInfo domainInfo, ADWebService adws, PingCastleAnalyzerParameters parameters)
        {
            ExportDataFromActiveDirectoryLive export = new ExportDataFromActiveDirectoryLive(domainInfo, adws, parameters.Credential);
            var ObjectReference = export.ExportData(parameters.AdditionalNamesForDelegationAnalysis);

            storage = export.Storage;

            data.ControlPaths         = new CompromiseGraphData();
            data.ControlPaths.Data    = new List <SingleCompromiseGraphData>();
            data.PrivilegedGroups     = new List <HealthCheckGroupData>();
            data.AllPrivilegedMembers = new List <HealthCheckGroupMemberData>();

            PrepareStopNodes(ObjectReference, domainInfo.DomainSid.Value);

            PrepareDetailledData(domainInfo, data, ObjectReference);
            PrepareDependancyGlobalData(data.ControlPaths);
            PrepareAnomalyAnalysisData(data.ControlPaths);

            PrepareAllPrivilegedMembers(data);
        }
コード例 #22
0
ファイル: ScannerBase.cs プロジェクト: slooppe/pingcastle
		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;
		}
コード例 #23
0
        public void ExportData(List <string> UsersToInvestigate)
        {
            ADDomainInfo    domainInfo      = null;
            RelationFactory relationFactory = null;

            DisplayAdvancement("Getting domain informations");
            using (ADWebService adws = new ADWebService(Server, Port, Credential))
            {
                domainInfo = GetDomainInformation(adws);
                Storage.Initialize(domainInfo);
                Trace.WriteLine("Creating new relation factory");
                relationFactory = new RelationFactory(Storage, domainInfo, Credential);
                DisplayAdvancement("Exporting objects from Active Directory");
                ExportReportData(adws, domainInfo, relationFactory, UsersToInvestigate);
            }
            DisplayAdvancement("Inserting relations between nodes in the database");
            Trace.WriteLine("Inserting relations on hold");
            Storage.InsertRelationOnHold(domainInfo.DnsHostName);
            Trace.WriteLine("Done");
            DisplayAdvancement("Export completed");
        }
コード例 #24
0
        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);
        }
コード例 #25
0
ファイル: ExportUsers.cs プロジェクト: vletoux/pingcastle
        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");
                }
            }
        }
コード例 #26
0
        private void ExportFilesDataWithImpersonation(ADWebService adws, ADDomainInfo domainInfo, IRelationFactory relationFactory, List <string> files)
        {
            // insert relation related to the files already seen.
            // add subdirectory / sub file is the permission is not inherited
            BlockingQueue <string> queue = new BlockingQueue <string>(200);
            int numberOfThread           = 20;

            Thread[] threads = new Thread[numberOfThread];
            try
            {
                ThreadStart threadFunction = () =>
                {
                    for (; ;)
                    {
                        string fileName = null;
                        if (!queue.Dequeue(out fileName))
                        {
                            break;
                        }

                        // function is safe and will never trigger an exception
                        relationFactory.AnalyzeFile(fileName);
                    }
                    Trace.WriteLine("Consumer quitting");
                };

                // Consumers
                for (int i = 0; i < numberOfThread; i++)
                {
                    threads[i] = new Thread(threadFunction);
                    threads[i].Start();
                }

                // do it in parallele (else time *6 !)
                foreach (string file in files)
                {
                    queue.Enqueue(file);
                }
                queue.Quit();
                Trace.WriteLine("insert file completed. Waiting for worker thread to complete");
                for (int i = 0; i < numberOfThread; i++)
                {
                    threads[i].Join();
                }
                Trace.WriteLine("Done insert file");
            }
            finally
            {
                queue.Quit();
                for (int i = 0; i < numberOfThread; i++)
                {
                    if (threads[i] != null)
                    {
                        if (threads[i].ThreadState == System.Threading.ThreadState.Running)
                        {
                            threads[i].Abort();
                        }
                    }
                }
            }
        }
コード例 #27
0
ファイル: LAPSBitLocker.cs プロジェクト: pdeforge/pingcastle
        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
        void CheckFilePermission(ADDomainInfo domainInfo, StreamWriter sw, ADWebService adws)
        {
            var pathToCheck = new List <string>();

            foreach (var script in Directory.GetDirectories(@"\\" + domainInfo.DnsHostName + @"\SYSVOL\" + domainInfo.DomainName + @"\scripts", "*", SearchOption.TopDirectoryOnly))
            {
                pathToCheck.Add(script);
            }
            foreach (var gpo in Directory.GetDirectories(@"\\" + domainInfo.DnsHostName + @"\SYSVOL\" + domainInfo.DomainName + @"\policies", "*", SearchOption.TopDirectoryOnly))
            {
                pathToCheck.Add(gpo);
            }

            BlockingQueue <string> queue = new BlockingQueue <string>(200);
            int numberOfThread           = 20;

            Thread[] threads = new Thread[numberOfThread];
            try
            {
                ThreadStart threadFunction = () =>
                {
                    adws.ThreadInitialization();
                    for (; ;)
                    {
                        string path = null;
                        if (!queue.Dequeue(out path))
                        {
                            break;
                        }
                        try
                        {
                            CheckFilePermissionWithPath(domainInfo, sw, path);
                        }
                        catch (Exception ex)
                        {
                            DisplayAdvancement("Error while working with " + path + " (" + ex.Message + ")");
                        }
                    }
                };

                // Consumers
                for (int i = 0; i < numberOfThread; i++)
                {
                    threads[i] = new Thread(threadFunction);
                    threads[i].Start();
                }

                foreach (string path in pathToCheck)
                {
                    queue.Enqueue(path);
                }
                queue.Quit();
                Trace.WriteLine("examining file completed. Waiting for worker thread to complete");
                for (int i = 0; i < numberOfThread; i++)
                {
                    threads[i].Join();
                }
                Trace.WriteLine("Done insert file");
            }
            finally
            {
                queue.Quit();
                for (int i = 0; i < numberOfThread; i++)
                {
                    if (threads[i] != null)
                    {
                        if (threads[i].ThreadState == System.Threading.ThreadState.Running)
                        {
                            threads[i].Abort();
                        }
                    }
                }
            }
        }
コード例 #29
0
        public void Export(string filename)
        {
            List <string>             reference    = new List <string>();
            ADDomainInfo              domainInfo   = null;
            Dictionary <uint, string> attReference = null;

            DisplayAdvancement("Starting");
            using (FileStream fsRepl = File.Create(filename + ".replData"))
                using (StreamWriter swRepl = new StreamWriter(fsRepl))
                    using (ADWebService adws = new ADWebService(Server, Port, Credential))

                    {
                        domainInfo = adws.DomainInfo;

                        DisplayAdvancement("Connected");

                        attReference = BuildAllAttributeDictionnary(adws);

                        string[] properties = new string[] { "distinguishedName", "replPropertyMetaData" };

                        int id = 0;
                        WorkOnReturnedObjectByADWS callback =
                            (ADItem x) =>
                        {
                            if (String.IsNullOrEmpty(x.DistinguishedName) || x.ReplPropertyMetaData == null)
                            {
                                return;
                            }
                            reference.Add(x.DistinguishedName);
                            foreach (var attId in x.ReplPropertyMetaData.Keys)
                            {
                                var usn  = x.ReplPropertyMetaData[attId].UsnLocalChange;
                                var date = x.ReplPropertyMetaData[attId].LastOriginatingChange;

                                swRepl.WriteLine("{0:X8},{1:X8},{2:X8},{3:X16}", usn, id, attId, date.ToFileTime());
                            }
                            id++;
                            if (id % 1000 == 0)
                            {
                                DisplayAdvancement(id + " objects enumerated");
                            }
                        };

                        adws.Enumerate(domainInfo.DefaultNamingContext, "(objectClass=*)", properties, callback, "Subtree");
                    }

            DisplayAdvancement("All objects enumerated");
            DisplayAdvancement("Sorting data");
            Process process = new Process();

            // Configure the process using the StartInfo properties.
            process.StartInfo.FileName    = "sort.exe";
            process.StartInfo.Arguments   = filename + ".replData /o " + filename + ".replData2";
            process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
            process.Start();
            process.WaitForExit();            // Waits here for the process to exit.
            DisplayAdvancement("data sorted");
            File.Delete(filename + ".replData");

            int      l       = 0;
            DateTime refDate = DateTime.MinValue;

            using (StreamWriter sw = File.CreateText(filename))
                using (var sr = new StreamReader(filename + ".replData2"))
                {
                    sw.WriteLine("PreviousUsn,PreviousObject,PreviousAttribute,PreviousDate,NewUsn,NewObject,NewAttribute,NewDate");
                    string previousLine = null;
                    while (!sr.EndOfStream)
                    {
                        string   line  = sr.ReadLine();
                        var      elt   = line.Split(',');
                        int      usn   = Convert.ToInt32(elt[0], 16);
                        int      id    = Convert.ToInt32(elt[1], 16);
                        uint     attId = Convert.ToUInt32(elt[2], 16);
                        DateTime date  = DateTime.FromFileTime(Convert.ToInt64(elt[3], 16));
                        if (l != 0 && refDate.AddDays(-7) > date)
                        {
                            string obj       = reference[id];
                            string attribute = "unknown(" + attId + ")";
                            if (attReference.ContainsKey(attId))
                            {
                                attribute = attReference[attId];
                            }
                            var    previousElt       = previousLine.Split(',');
                            uint   previousAttId     = Convert.ToUInt32(previousElt[2], 16);
                            string Previousattribute = "unknown(" + previousAttId + ")";
                            if (attReference.ContainsKey(previousAttId))
                            {
                                Previousattribute = attReference[previousAttId];
                            }
                            int      previousUsn  = Convert.ToInt32(previousElt[0], 16);
                            DateTime previousDate = DateTime.FromFileTime(Convert.ToInt64(previousElt[3], 16));
                            sw.WriteLine(previousUsn + "," + reference[Convert.ToInt32(previousElt[1], 16)] + "," + Previousattribute + "," + previousDate.ToString("u") + "," + usn + "," + obj + "," + attribute + "," + date.ToString("u"));
                        }
                        refDate = date;
                        l++;
                        previousLine = line;
                    }
                }
            File.Delete(filename + ".replData2");
        }