/* * private void PrepareObjectiveData(CompromiseGraphData data) * { * data.Objectives = new List<CompromiseGraphObjective>(); * data.Objectives.Add(new CompromiseGraphObjective() * { * Category = RiskRuleCategory.Trusts, * Objective = "No more than 1 domain can take control of an admin or critical object", * Score = 100, * RulesMatched = new List<string>() { "A-TEST" }, * }); * data.Objectives.Add(new CompromiseGraphObjective() * { * Category = RiskRuleCategory.Trusts, * Objective = "No domain can take control of an admin or critical object", * Score = 100, * }); * data.Objectives.Add(new CompromiseGraphObjective() * { * Category = RiskRuleCategory.Trusts, * Objective = "No domain can take control of a user defined object", * Score = 25, * }); * data.Objectives.Add(new CompromiseGraphObjective() * { * Category = RiskRuleCategory.Trusts, * Objective = "At the exception of a domain declared as an admin domain, no child domain of a forest should have permission on other domains", * Score = 25, * }); * bool criticalfound = false; * foreach (var anomaly in data.AnomalyAnalysis) * { * string risk = null; * int basescore; * if (anomaly.CriticalObjectFound) * criticalfound = true; * switch (anomaly.ObjectRisk) * { * case CompromiseGraphDataObjectRisk.Critical: * risk = "critical"; * basescore = 100; * break; * case CompromiseGraphDataObjectRisk.High: * risk = "high"; * basescore = 80; * break; * case CompromiseGraphDataObjectRisk.Medium: * risk = "medium"; * basescore = 60; * break; * default: * continue; * * } * data.Objectives.Add(new CompromiseGraphObjective() * { * Category = RiskRuleCategory.Anomalies, * Objective = "No " + risk + " priority object should be available to more than 100 indirect number", * Score = basescore, * IsAchieved = anomaly.MaximumIndirectNumber < 100, * }); * data.Objectives.Add(new CompromiseGraphObjective() * { * Category = RiskRuleCategory.Anomalies, * Objective = "No " + risk + " object should be available to more than 50 indirect number", * Score = basescore - 10, * IsAchieved = anomaly.MaximumIndirectNumber < 50, * }); * data.Objectives.Add(new CompromiseGraphObjective() * { * Category = RiskRuleCategory.Anomalies, * Objective = "No " + risk + " object should be available to more than 10 indirect number", * Score = basescore - 20, * IsAchieved = anomaly.MaximumIndirectNumber < 10, * }); * data.Objectives.Add(new CompromiseGraphObjective() * { * Category = RiskRuleCategory.Anomalies, * Objective = "No " + risk + " object should be available to indirect users at all", * Score = basescore - 30, * IsAchieved = anomaly.MaximumIndirectNumber == 0, * }); * } * data.Objectives.Add(new CompromiseGraphObjective() * { * Category = RiskRuleCategory.Anomalies, * Objective = "No object should allow Everyone, Authenticated Users, Domain Users or Domain Computers to take control of itself", * Score = 100, * IsAchieved = criticalfound, * }); * }*/ private void ProduceReportFile(CompromiseGraphData data, CompromiseGraphDataTypology typology, CompromiseGraphDataObjectRisk risk, string description, string name) { try { Dictionary <string, string> databaseProperties = storage.GetDatabaseInformation(); DateTime exportDate = DateTime.Parse(databaseProperties["Date"]); Trace.WriteLine("Generating Description:" + description + " Name=" + name); int rootNodeId = storage.SearchItem(name); if (rootNodeId < 0) { // do not display error message for schema admin and enterprise admins which are missing on child domains if (typology == CompromiseGraphDataTypology.PrivilegedAccount && (name.EndsWith("-519") || name.EndsWith("-518") || name.EndsWith("-498") || name.Equals("S-1-5-32-557"))) { return; } Trace.WriteLine("Id not found for name=" + name); Console.WriteLine("The report " + description + " starting from " + name + " couldn't be built because the object wasn't found"); return; } List <int> nodesid = new List <int>(); Dictionary <int, List <Relation> > links = RetrieveLinks(rootNodeId, nodesid); Dictionary <int, Node> chartNodes = storage.RetrieveNodes(nodesid); List <int> directUsers = RetrieveDirectUserNodes(rootNodeId, new string[] { "user", "msDS-GroupManagedServiceAccount", "msDS-ManagedServiceAccount" }); List <int> directComputers = RetrieveDirectUserNodes(rootNodeId, new string[] { "computer" }); SimplifyGraph(chartNodes, links); ComputeDistance(rootNodeId, links, chartNodes); var singleCompromiseData = BuildSingleCompromiseGraphData(rootNodeId, chartNodes, links, directUsers); singleCompromiseData.Name = name; singleCompromiseData.Description = description; singleCompromiseData.Typology = typology; singleCompromiseData.ObjectRisk = risk; BuildUserMembers(singleCompromiseData, directUsers); BuildComputerMembers(singleCompromiseData, directComputers); BuildIndirectMembers(singleCompromiseData); BuildDependancies(data, singleCompromiseData, chartNodes); BuildDeletedObjects(data, singleCompromiseData, chartNodes); data.Data.Add(singleCompromiseData); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Exception: " + ex.Message); Console.WriteLine(ex.StackTrace); Trace.WriteLine(ex.Message); Trace.WriteLine(ex.StackTrace); if (ex.InnerException != null) { Trace.WriteLine("innerexception: " + ex.InnerException.Message); } } }
private void ProduceReportFile(ADDomainInfo domainInfo, HealthcheckData hcdata, CompromiseGraphDataTypology typology, CompromiseGraphDataObjectRisk risk, string description, string name) { try { var data = hcdata.ControlPaths; Dictionary <string, string> databaseProperties = storage.GetDatabaseInformation(); DateTime exportDate = DateTime.Parse(databaseProperties["Date"]); Trace.WriteLine("Generating Description:" + description + " Name=" + name); int rootNodeId = storage.SearchItem(name); if (rootNodeId < 0) { Trace.WriteLine("root node not found"); // do not display error message for schema admin and enterprise admins which are missing on child domains if (typology == CompromiseGraphDataTypology.PrivilegedAccount && (name.EndsWith("-519") || name.EndsWith("-518") || name.EndsWith("-498") || name.Equals("S-1-5-32-557"))) { return; } Trace.WriteLine("Id not found for name=" + name); Console.WriteLine("The report " + description + " starting from " + name + " couldn't be built because the object wasn't found"); return; } Dictionary <int, Node> chartNodes = new Dictionary <int, Node>(); List <int> directUsers = new List <int>(); List <int> directComputers = new List <int>(); Dictionary <int, List <Relation> > links = new Dictionary <int, List <Relation> >(); Trace.WriteLine("BuildTree"); BuildTree(rootNodeId, chartNodes, directUsers, directComputers, links); Trace.WriteLine("BuildCompromissionData"); var singleCompromiseData = BuildSingleCompromiseGraphData(rootNodeId, chartNodes, links, directUsers); singleCompromiseData.Name = name; singleCompromiseData.Description = description; singleCompromiseData.Typology = typology; singleCompromiseData.ObjectRisk = risk; if (chartNodes[rootNodeId].Type == "group") { Trace.WriteLine("Build users members"); BuildUserMembers(singleCompromiseData, directUsers); Trace.WriteLine("Build computer members"); BuildComputerMembers(singleCompromiseData, directComputers); if (typology == CompromiseGraphDataTypology.PrivilegedAccount) { Trace.WriteLine("Build privilege data"); BuildPrivilegeData(domainInfo, hcdata, singleCompromiseData, directUsers, directComputers); } } Trace.WriteLine("Build indirect members"); BuildIndirectMembers(singleCompromiseData); Trace.WriteLine("Build dependancies"); BuildDependancies(domainInfo, data, singleCompromiseData, chartNodes); Trace.WriteLine("build deleted objects"); BuildDeletedObjects(domainInfo, data, singleCompromiseData, chartNodes); Trace.WriteLine("done"); data.Data.Add(singleCompromiseData); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Exception: " + ex.Message); Console.WriteLine(ex.StackTrace); Trace.WriteLine(ex.Message); Trace.WriteLine(ex.StackTrace); if (ex.InnerException != null) { Trace.WriteLine("innerexception: " + ex.InnerException.Message); } } }