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"); } )); }
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>(); }
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)); } }
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); } }
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); }
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); }
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); }
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"); } } }
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); }