Пример #1
0
 public bool ConsolidationTask()
 {
     return(StartTask("Healthcheck consolidation",
                      () =>
     {
         HealthcheckAnalyzer hc = new HealthcheckAnalyzer();
         if (String.IsNullOrEmpty(FileOrDirectory))
         {
             FileOrDirectory = Directory.GetCurrentDirectory();
         }
         if (!Directory.Exists(FileOrDirectory))
         {
             WriteInRed("The directory " + FileOrDirectory + " doesn't exist");
             return;
         }
         HealthcheckDataCollection consolidation = HealthcheckDataHelper.LoadXmls(FileOrDirectory, FilterReportDate);
         if (consolidation.Count == 0)
         {
             WriteInRed("No report has been found. The program will stop");
             return;
         }
         HealthCheckReportConsolidation report = new HealthCheckReportConsolidation(consolidation);
         report.GenerateReportFile("ad_hc_summary.html");
         HealthCheckReportMapBuilder nodeAnalyzer = new HealthCheckReportMapBuilder(consolidation);
         nodeAnalyzer.Log = Console.WriteLine;
         nodeAnalyzer.GenerateReportFile("ad_hc_summary_full_node_map.html");
         nodeAnalyzer.FullNodeMap = false;
         nodeAnalyzer.CenterDomainForSimpliedGraph = CenterDomainForSimpliedGraph;
         nodeAnalyzer.GenerateReportFile("ad_hc_summary_simple_node_map.html");
     }
                      ));
 }
Пример #2
0
        private void GenerateUserData(FakeHealthCheckDataGeneratorDomainModel model, HealthcheckData healthcheckData)
        {
            healthcheckData.UserAccountData    = new HealthcheckAccountData();
            healthcheckData.AdminLastLoginDate = DateBetween2Dates(healthcheckData.DomainCreation, DateTime.Now);;
            healthcheckData.AdminAccountName   = GraphObjectReference.Administrator;
            int size = GetCountFromSize(model);

            for (int i = 0; i < size; i++)
            {
                ADItem x = new ADItem();
                x.DistinguishedName = "CN=123";
                // disabled
                x.UserAccountControl += BoolOnChance(15) * 0x00000002;
                //preauth
                x.UserAccountControl += BoolOnChance(1) * 0x400000;
                // locked
                x.UserAccountControl += BoolOnChance(4) * 0x00000010;
                // pwd never expires
                x.UserAccountControl += BoolOnChance(10) * 0x00010000;
                // pwd not required
                x.UserAccountControl += BoolOnChance(2) * 0x00000020;
                // trusted to authenticate
                x.UserAccountControl += BoolOnChance(2) * 0x80000;
                x.PrimaryGroupID      = 515 + BoolOnChance(1);
                HealthcheckAnalyzer.ProcessAccountData(healthcheckData.UserAccountData, x, false);
            }
            healthcheckData.LoginScript = new List <HealthcheckLoginScriptData>();
        }
Пример #3
0
        private BotInputOutput RunHealthCheck(BotInputOutput input)
        {
            try
            {
                var analyze    = new HealthcheckAnalyzer();
                var parameters = new PingCastleAnalyzerParameters();
                parameters.Server = GetItem(input, "Server");
                var login    = GetItem(input, "Login");
                var password = GetItem(input, "Password");
                if (!string.IsNullOrEmpty(login) && !string.IsNullOrEmpty(password))
                {
                    parameters.Credential = new System.Net.NetworkCredential(login, password);
                }
                var port = GetItem(input, "Port");
                if (!string.IsNullOrEmpty(port))
                {
                    parameters.Port = int.Parse(port);
                }
                var healthcheck = analyze.PerformAnalyze(parameters);

                var o = new BotInputOutput();
                o.Data = new List <BotData>();
                AddData(o, "Status", "OK");
                AddData(o, "Target", parameters.Server);

                int riskId = 0;
                foreach (var risk in healthcheck.RiskRules)
                {
                    riskId++;
                    var rule = RuleSet <HealthcheckData> .GetRuleFromID(risk.RiskId);

                    AddData(o, "Rationale_" + riskId, risk.Rationale);
                    AddData(o, "Title_" + riskId, rule.Title);
                    AddData(o, "Solution_" + riskId, rule.Solution);
                    AddData(o, "Points_" + riskId, risk.Points.ToString());
                    AddData(o, "Documentation_" + riskId, rule.Documentation);
                    AddData(o, "TechnicalExplanation_" + riskId, rule.TechnicalExplanation);
                    foreach (var d in rule.Details)
                    {
                        AddData(o, "Detail_" + riskId, d);
                    }
                }

                healthcheck.SetExportLevel(PingCastleReportDataExportLevel.Full);
                var xmlreport = DataHelper <HealthcheckData> .SaveAsXml(healthcheck, null, false);

                AddData(o, "Report", xmlreport);

                return(o);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception:" + ex.Message);
                Console.WriteLine("StackTrace:" + ex.StackTrace);
                return(ExceptionOutput("Exception during the healthcheck " + ex.Message, ex.StackTrace));
            }
        }
Пример #4
0
        private void GenerateComputerData(FakeHealthCheckDataGeneratorDomainModel model, HealthcheckData healthcheckData)
        {
            healthcheckData.OperatingSystem        = new List <HealthcheckOSData>();
            healthcheckData.OperatingSystemVersion = new List <HealthcheckOSVersionData>();
            healthcheckData.ComputerAccountData    = new HealthcheckAccountData();
            int size = GetCountFromSize(model);

            for (int i = 0; i < size; i++)
            {
                ADItem x = new ADItem();
                x.DistinguishedName = "CN=123";
                // disabled
                x.UserAccountControl += BoolOnChance(15) * 0x00000002;
                //preauth
                x.UserAccountControl += BoolOnChance(1) * 0x400000;
                // locked
                x.UserAccountControl += BoolOnChance(4) * 0x00000010;
                // pwd never expires
                x.UserAccountControl += BoolOnChance(10) * 0x00010000;
                // pwd not required
                x.UserAccountControl += BoolOnChance(2) * 0x00000020;
                // trusted to authenticate
                x.UserAccountControl += BoolOnChance(2) * 0x80000;
                x.PrimaryGroupID      = 515 + BoolOnChance(1);
                HealthcheckAnalyzer.ProcessAccountData(healthcheckData.ComputerAccountData, x, true);
            }
            healthcheckData.LoginScript = new List <HealthcheckLoginScriptData>();

            healthcheckData.DomainControllers = new List <HealthcheckDomainController>();
            size = (int)Math.Exp(Math.Log10(size) / 2);
            if (size < 1)
            {
                size = 1;
            }
            for (int i = 0; i < size; i++)
            {
                HealthcheckDomainController dc = new HealthcheckDomainController();
                dc.DCName       = "DC" + i;
                dc.CreationDate = DateBetween2Dates(healthcheckData.DomainCreation, DateTime.Now);
                // last logon timestam can have a delta of 14 days
                dc.LastComputerLogonDate = DateTime.Now.AddDays(-1 * rnd.Next(180));
                dc.DistinguishedName     = "DC=DC";
                dc.OperatingSystem       = "Windows 2019";
                healthcheckData.DomainControllers.Add(dc);
            }
        }
Пример #5
0
        bool HealthcheckSubTask(string server, Dictionary <string, string> xmlreports, Dictionary <string, string> htmlreports, bool DoAnalyzeReachableDomains, out HealthcheckData data)
        {
            HealthcheckData reportTemp = null;
            bool            status     = StartTask("Healthcheck for " + server,
                                                   () =>
            {
                HealthcheckAnalyzer hc     = new HealthcheckAnalyzer();
                hc.AnalyzeReachableDomains = DoAnalyzeReachableDomains;
                hc.NumberOfDepthForSplit   = NumberOfDepthForSplit;
                hc.GenerateReport(server, ADWSPort, Credential);
                reportTemp    = hc.healthcheckData;
                string domain = hc.healthcheckData.DomainFQDN;
                DisplayAdvancement("Generating html report");
                HealthCheckReportSingle report = new HealthCheckReportSingle(hc.healthcheckData, License);
                htmlreports[domain]            = report.GenerateReportFile("ad_hc_" + domain + ".html");
                DisplayAdvancement("Generating xml file for consolidation report" + (EncryptReport ? " (encrypted)" : ""));
                hc.healthcheckData.Level = ExportLevel;
                xmlreports[domain]       = DataHelper <HealthcheckData> .SaveAsXml(hc.healthcheckData, "ad_hc_" + domain + ".xml", EncryptReport);
            });

            data = reportTemp;
            return(status);
        }
Пример #6
0
        private List <string> GetListOfDomainToExploreFromGenericName(string server)
        {
            List <string> domains = new List <string>();

            StartTask("Exploration",
                      () =>
            {
                HealthcheckAnalyzer hcroot = new HealthcheckAnalyzer();
                var reachableDomains       = hcroot.GetAllReachableDomains(Port, Credential);
                List <HealthcheckAnalyzer.ReachableDomainInfo> domainsfiltered = new List <HealthcheckAnalyzer.ReachableDomainInfo>();
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("List of domains that will be queried");
                Console.ResetColor();
                foreach (var reachableDomain in reachableDomains)
                {
                    if (compareStringWithWildcard(server, reachableDomain.domain) && !ShouldTheDomainBeNotExplored(reachableDomain.domain))
                    {
                        domains.Add(reachableDomain.domain);
                        Console.WriteLine(reachableDomain.domain);
                    }
                }
            });
            return(domains);
        }
Пример #7
0
        public bool CartoTask(bool PerformHealthCheckGenerateDemoReports)
        {
            List <HealthcheckAnalyzer.ReachableDomainInfo> domains = null;

            StartTask("Exploration",
                      () =>
            {
                HealthcheckAnalyzer hcroot = new HealthcheckAnalyzer();
                domains = hcroot.GetAllReachableDomains(Port, Credential);
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("List of domains that will be queried");
                Console.ResetColor();
                foreach (var domain in domains)
                {
                    Console.WriteLine(domain.domain);
                }
            });
            var consolidation = new PingCastleReportCollection <HealthcheckData>();

            StartTask("Examining all domains in parallele (this can take a few minutes)",
                      () =>
            {
                BlockingQueue <string> queue = new BlockingQueue <string>(30);
                int numberOfThread           = 100;
                Thread[] threads             = new Thread[numberOfThread];
                try
                {
                    ThreadStart threadFunction = () =>
                    {
                        for (; ;)
                        {
                            string domain = null;
                            if (!queue.Dequeue(out domain))
                            {
                                break;
                            }
                            try
                            {
                                Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] " + "Starting the analysis of " + domain);
                                HealthcheckAnalyzer hc = new HealthcheckAnalyzer();
                                var data = hc.GenerateCartoReport(domain, Port, Credential, AnalyzeReachableDomains);
                                consolidation.Add(data);
                                Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] " + "Analysis of " + domain + " completed with success");
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] " + "Analysis of " + domain + " failed");
                                Trace.WriteLine("Exception while analysing domain " + domain + " : " + ex.Message);
                                Trace.WriteLine(ex.StackTrace);
                            }
                        }
                    };
                    // Consumers
                    for (int i = 0; i < numberOfThread; i++)
                    {
                        threads[i] = new Thread(threadFunction);
                        threads[i].Start();
                    }
                    foreach (var domain in domains)
                    {
                        queue.Enqueue(domain.domain);
                    }
                    queue.Quit();
                    Trace.WriteLine("examining domains file completed. Waiting for worker thread to complete");
                    for (int i = 0; i < numberOfThread; i++)
                    {
                        threads[i].Join();
                    }
                    Trace.WriteLine("Done examining domains");
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("Exception while analysing domain in carto: " + ex.Message);
                    Trace.WriteLine(ex.StackTrace);
                }
                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();
                            }
                        }
                    }
                }
            });
            if (PerformHealthCheckGenerateDemoReports)
            {
                Console.WriteLine("Performing demo report transformation");
                Trace.WriteLine("Performing demo report transformation");
                consolidation = PingCastleReportHelper <HealthcheckData> .TransformReportsToDemo(consolidation);
            }
            if (!StartTask("Healthcheck consolidation",
                           () =>
            {
                consolidation.EnrichInformation();
                ReportHealthCheckMapBuilder nodeAnalyzer = new ReportHealthCheckMapBuilder(consolidation, License);
                nodeAnalyzer.Log = Console.WriteLine;
                nodeAnalyzer.CenterDomainForSimpliedGraph = CenterDomainForSimpliedGraph;
                nodeAnalyzer.GenerateReportFile("ad_carto_full_node_map.html");
                nodeAnalyzer.FullNodeMap = false;
                nodeAnalyzer.CenterDomainForSimpliedGraph = CenterDomainForSimpliedGraph;
                nodeAnalyzer.GenerateReportFile("ad_carto_simple_node_map.html");
            }
                           ))
            {
                return(false);
            }
            return(true);
        }
Пример #8
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");
                }
            }
        }
Пример #9
0
        public bool HeatlthCheckTask(string server, Dictionary <string, string> xmlreports, Dictionary <string, string> htmlreports)
        {
            Trace.WriteLine("Working on " + server);
            if (server == "*" && InteractiveMode)
            {
                Trace.WriteLine("Setting reachable domains to on because interactive + server = *");
                AnalyzeReachableDomains = true;
            }
            if (server.Contains("*"))
            {
                List <HealthcheckAnalyzer.ReachableDomainInfo> domains = null;
                StartTask("Exploration",
                          () =>
                {
                    HealthcheckAnalyzer hcroot = new HealthcheckAnalyzer();
                    domains = hcroot.GetAllReachableDomains(ADWSPort, Credential);
                    List <HealthcheckAnalyzer.ReachableDomainInfo> domainsfiltered = new List <HealthcheckAnalyzer.ReachableDomainInfo>();
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("List of domains that will be queried");
                    Console.ResetColor();
                    foreach (var domain in domains)
                    {
                        if (compareStringWithWildcard(server, domain.domain) && !ShouldTheDomainBeNotExplored(domain.domain))
                        {
                            domainsfiltered.Add(domain);
                            Console.WriteLine(domain.domain);
                        }
                    }
                    domains = domainsfiltered;
                });
                int i = 1;

                foreach (var domain in domains)
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("");
                    string display = "Starting the report for " + domain.domain + " (" + i++ + "/" + domains.Count + ")";
                    Console.WriteLine(display);
                    Console.WriteLine(new String('=', display.Length));
                    Console.ResetColor();
                    HealthcheckData hcData;
                    HealthcheckSubTask(domain.domain, xmlreports, htmlreports, AnalyzeReachableDomains, out hcData);
                }
            }
            else
            {
                HealthcheckData hcData;
                bool            output = HealthcheckSubTask(server, xmlreports, htmlreports, AnalyzeReachableDomains, out hcData);
                // do additional exploration based on trust results ?
                if (output && (ExploreTerminalDomains || ExploreForestTrust))
                {
                    if (hcData.Trusts != null)
                    {
                        List <string> domainToExamine = new List <string>();
                        foreach (var trust in hcData.Trusts)
                        {
                            string attributes = TrustAnalyzer.GetTrustAttribute(trust.TrustAttributes);
                            string direction  = TrustAnalyzer.GetTrustDirection(trust.TrustDirection);
                            if (direction.Contains("Inbound") || direction.Contains("Disabled"))
                            {
                                continue;
                            }
                            if (attributes.Contains("Intra-Forest"))
                            {
                                continue;
                            }
                            // explore forest trust only if explore forest trust is set
                            if (attributes.Contains("Forest Trust"))
                            {
                                if (ExploreForestTrust)
                                {
                                    if (!ShouldTheDomainBeNotExplored(trust.TrustPartner))
                                    {
                                        domainToExamine.Add(trust.TrustPartner);
                                    }
                                    if (trust.KnownDomains != null)
                                    {
                                        foreach (var di in trust.KnownDomains)
                                        {
                                            if (!ShouldTheDomainBeNotExplored(di.DnsName))
                                            {
                                                domainToExamine.Add(di.DnsName);
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (ExploreTerminalDomains)
                                {
                                    if (!ShouldTheDomainBeNotExplored(trust.TrustPartner))
                                    {
                                        domainToExamine.Add(trust.TrustPartner);
                                    }
                                }
                            }
                        }
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("List of domains that will be queried");
                        Console.ResetColor();
                        foreach (var domain in domainToExamine)
                        {
                            Console.WriteLine(domain);
                        }
                        foreach (string domain in domainToExamine)
                        {
                            HealthcheckData hcDataTemp;
                            HealthcheckSubTask(domain, xmlreports, htmlreports, AnalyzeReachableDomains, out hcDataTemp);
                        }
                    }
                }
                return(output);
            }
            return(true);
        }