Exemplo n.º 1
0
        private void BuildIndirectMembers(SingleCompromiseGraphData singleCompromiseData)
        {
            singleCompromiseData.IndirectMembers = new List <SingleCompromiseGraphIndirectMemberData>();
            var map = new Dictionary <int, int>();

            foreach (var link in singleCompromiseData.Links)
            {
                map[link.Source] = link.Target;
            }
            var reference = new Dictionary <int, SingleCompromiseGraphNodeData>();

            foreach (var node in singleCompromiseData.Nodes)
            {
                reference[node.Id] = node;
            }
            foreach (var node in singleCompromiseData.Nodes)
            {
                if ((node.IsTypeAUser && node.Suspicious) || node.Critical)
                {
                    var user = BuildIndirectMemberUser(singleCompromiseData, node, reference, map);
                    singleCompromiseData.IndirectMembers.Add(user);
                }
            }
            singleCompromiseData.NumberOfIndirectMembers = singleCompromiseData.IndirectMembers.Count;
        }
Exemplo n.º 2
0
 private void BuildComputerMembers(SingleCompromiseGraphData singleCompromiseData, List <int> directNodes)
 {
     singleCompromiseData.DirectComputerMembers = new List <SingleCompromiseGraphComputerMemberData>();
     foreach (var id in directNodes)
     {
         var node = storage.RetrieveNode(id);
         var user = BuildMembersComputer(node.ADItem);
         singleCompromiseData.DirectComputerMembers.Add(user);
     }
 }
Exemplo n.º 3
0
        public void AddGraph(SingleCompromiseGraphData graphData)
        {
            if (!ImpactedGraph.ContainsKey(graphData.Name))
            {
                var detail = new CompromiseGraphRuleDetail();
                detail.Details = new List <string>();
                ImpactedGraph.Add(graphData.Name, detail);
            }
            string ruleDetail = String.Format("{1} ({0})", graphData.Name, graphData.Description);

            if (!Details.Contains(ruleDetail))
            {
                Details.Add(ruleDetail);
            }
        }
Exemplo n.º 4
0
 private void BuildDeletedObjects(CompromiseGraphData data, SingleCompromiseGraphData singleCompromiseData, Dictionary <int, Node> chartNodes)
 {
     singleCompromiseData.DeletedObjects = new List <SingleCompromiseGraphDeletedData>();
     foreach (var node in chartNodes.Values)
     {
         if (String.Equals(node.Type, "foreignsecurityprincipal", StringComparison.InvariantCultureIgnoreCase))
         {
             // ignore everything but deleted accounts
             if (node.Sid.StartsWith(data.DomainSid + "-"))
             {
                 singleCompromiseData.DeletedObjects.Add(new SingleCompromiseGraphDeletedData()
                 {
                     Sid = node.Sid,
                 }
                                                         );
             }
         }
     }
 }
Exemplo n.º 5
0
        private SingleCompromiseGraphIndirectMemberData BuildIndirectMemberUser(SingleCompromiseGraphData singleCompromiseData, SingleCompromiseGraphNodeData node, Dictionary <int, SingleCompromiseGraphNodeData> reference, Dictionary <int, int> map)
        {
            var member = new SingleCompromiseGraphIndirectMemberData();

            member.Name     = node.ShortName;
            member.Distance = node.Distance;
            if (node.ADItem != null && node.ADItem.ObjectSid != null)
            {
                member.Sid = node.ADItem.ObjectSid.Value;
            }
            int id          = node.Id;
            var currentNode = node;
            var path        = new List <string>();

            while (id >= 0 && !(currentNode.IsTypeAUser && !currentNode.Suspicious))
            {
                path.Add(currentNode.ShortName);
                if (map.ContainsKey(id))
                {
                    id          = map[id];
                    currentNode = reference[id];
                }
                else
                {
                    id = -1;
                }
            }
            if (id >= 0)
            {
                path.Add(currentNode.ShortName);
                member.AuthorizedObject = currentNode.ShortName;
            }
            if (path.Count > 4)
            {
                member.Path = path[0] + "->" + path[1] + "->...->" + path[path.Count - 2] + "->" + path[path.Count - 1];
            }
            else
            {
                member.Path = string.Join("->", path.ToArray());
            }
            return(member);
        }
Exemplo n.º 6
0
 public void AddGraphRawDetail(SingleCompromiseGraphData graphData, params object[] data)
 {
     AddGraph(graphData);
     ImpactedGraph[graphData.Name].Details.Add(String.Format(DetailFormatString, data));
 }
Exemplo n.º 7
0
        private void BuildPrivilegeData(ADDomainInfo domainInfo, HealthcheckData hcdata, SingleCompromiseGraphData singleCompromiseData, List <int> directNodes1, List <int> directNodes2)
        {
            var items = new List <ADItem>();

            foreach (var id in directNodes1)
            {
                var node = storage.RetrieveNode(id);
                var item = node.ADItem;
                items.Add(item);
            }
            foreach (var id in directNodes2)
            {
                var node = storage.RetrieveNode(id);
                var item = node.ADItem;
                items.Add(item);
            }
            var groupData = AnalyzeGroupData(domainInfo.DnsHostName, singleCompromiseData.Description, items);

            hcdata.PrivilegedGroups.Add(groupData);
        }
Exemplo n.º 8
0
        private void BuildDependancies(ADDomainInfo domainInfo, CompromiseGraphData refData, SingleCompromiseGraphData singleCompromiseData, Dictionary <int, Node> chartNodes)
        {
            var reference = new Dictionary <SecurityIdentifier, SingleCompromiseGraphDependancyData>();
            var domains   = storage.GetKnownDomains();

            foreach (var node in chartNodes.Values)
            {
                if (String.Equals(node.Type, "foreignsecurityprincipal", StringComparison.InvariantCultureIgnoreCase))
                {
                    // ignore deleted accounts
                    if (node.Sid.StartsWith(domainInfo.DomainSid.Value + "-"))
                    {
                        continue;
                    }
                    SingleCompromiseGraphDependancyData data;
                    var sid       = new SecurityIdentifier(node.Sid);
                    var domainSid = sid.AccountDomainSid;
                    if (domainSid == null)
                    {
                        continue;
                    }
                    if (!reference.ContainsKey(domainSid))
                    {
                        data = new SingleCompromiseGraphDependancyData();
                        reference[domainSid] = data;
                        data.Sid             = domainSid.Value;
                        foreach (var domain in domains)
                        {
                            if (String.Equals(domain.DomainSid.Value, data.Sid, StringComparison.InvariantCultureIgnoreCase))
                            {
                                data.FQDN    = domain.DnsDomainName;
                                data.Netbios = domain.NetbiosDomainName;
                                break;
                            }
                        }
                        data.Items = new List <SingleCompromiseGraphDependancyMemberData>();
                    }
                    else
                    {
                        data = reference[domainSid];
                    }
                    if (node.Shortname.Contains("\\"))
                    {
                        if (String.IsNullOrEmpty(data.Netbios))
                        {
                            data.Netbios = node.Shortname.Split('\\')[0];
                        }
                        data.NumberOfResolvedItems++;
                    }
                    else
                    {
                        data.NumberOfUnresolvedItems++;
                    }
                    data.Items.Add(new SingleCompromiseGraphDependancyMemberData()
                    {
                        Name = node.Shortname,
                        Sid  = node.Sid,
                    }
                                   );
                }
            }
            singleCompromiseData.Dependancies = new List <SingleCompromiseGraphDependancyData>(reference.Values);
            singleCompromiseData.Dependancies.Sort(
                (SingleCompromiseGraphDependancyData a, SingleCompromiseGraphDependancyData b)
                =>
            {
                return(String.Compare(a.Netbios, b.Netbios));
            }
                );
        }
Exemplo n.º 9
0
        private SingleCompromiseGraphData BuildSingleCompromiseGraphData(int rootNodeId, Dictionary <int, Node> nodes, Dictionary <int, List <Relation> > links, List <int> directNodes)
        {
            var data = new SingleCompromiseGraphData();
            var idconversiontable = new Dictionary <int, int>();

            // START OF NODES

            data.Nodes = new List <SingleCompromiseGraphNodeData>();

            Trace.WriteLine("Building root node");
            // it is important to put the root node as the first node for correct display
            int  nodenumber = 0;
            Node rootNode   = nodes[rootNodeId];

            data.Nodes.Add(new SingleCompromiseGraphNodeData()
            {
                Id        = nodenumber,
                Name      = rootNode.Name,
                Type      = rootNode.Type,
                ShortName = rootNode.Shortname,
                Distance  = 0,
            });
            idconversiontable[rootNode.Id] = nodenumber++;

            Trace.WriteLine("Building nodes");
            foreach (Node node in nodes.Values)
            {
                if (node.Id == rootNodeId)
                {
                    continue;
                }
                bool exception = false;
                // authenticated users is allowed for PreWin2000 group
                if (string.Equals(rootNode.Sid, "S-1-5-32-554", StringComparison.OrdinalIgnoreCase) && string.Equals(node.Sid, "S-1-5-11", StringComparison.OrdinalIgnoreCase))
                {
                    exception = true;
                }
                data.Nodes.Add(new SingleCompromiseGraphNodeData()
                {
                    Id         = nodenumber,
                    Name       = node.Name,
                    Type       = node.Type,
                    ShortName  = node.Shortname,
                    Distance   = node.Distance,
                    Suspicious = node.IsTypeAUser && !directNodes.Contains(node.Id),
                    Critical   = !exception && node.EveryoneLikeGroup,
                    ADItem     = node.ADItem,
                });
                if (!exception && node.EveryoneLikeGroup)
                {
                    data.CriticalObjectFound = true;
                }
                idconversiontable[node.Id] = nodenumber++;
            }
            // END OF NODES

            Trace.WriteLine("check links");
            // defensive programming: check for data consistency
            foreach (int key in links.Keys)
            {
                List <Relation> link = links[key];
                foreach (Relation detail in link)
                {
                    if (!idconversiontable.ContainsKey(detail.ToId))
                    {
                        Trace.WriteLine("Inconsistancy: node missing: Id=" + detail.ToId);
                    }
                    if (!idconversiontable.ContainsKey(detail.FromId))
                    {
                        Trace.WriteLine("Inconsistancy: node missing: Id=" + detail.FromId);
                    }
                }
            }

            Trace.WriteLine("Building links");
            // START LINKS
            data.Links = new List <SingleCompromiseGraphLinkData>();

            foreach (int key in links.Keys)
            {
                List <Relation> link = links[key];
                foreach (Relation detail in link)
                {
                    data.Links.Add(new SingleCompromiseGraphLinkData()
                    {
                        Source = idconversiontable[detail.ToId],
                        Target = idconversiontable[detail.FromId],
                        Hints  = string.Join(" ", detail.Hint.ToArray()),
                    });
                }
            }
            // END OF LINKS
            return(data);
        }
        string BuildJasonFromSingleCompromiseGraph(SingleCompromiseGraphData data)
        {
            StringBuilder         output            = new StringBuilder();
            Dictionary <int, int> idconversiontable = new Dictionary <int, int>();

            output.Append("{");
            // START OF NODES

            output.Append("  \"nodes\": [");
            // it is important to put the root node as the first node for correct display
            for (int i = 0; i < data.Nodes.Count; i++)
            {
                var node = data.Nodes[i];
                if (i != 0)
                {
                    output.Append("    },");
                }
                output.Append("    {");
                output.Append("      \"id\": " + node.Id + ",");
                output.Append("      \"name\": \"" + HealthCheckReportMapBuilder.EscapeJsonString(node.Name) + "\",");
                output.Append("      \"type\": \"" + node.Type + "\",");
                output.Append("      \"shortName\": \"" + HealthCheckReportMapBuilder.EscapeJsonString(node.ShortName) + "\",");
                if (node.Distance == 0)
                {
                    output.Append("      \"dist\": null");
                }
                else
                {
                    output.Append("      \"dist\": \"" + node.Distance + "\"");
                }
            }
            output.Append("    }");
            output.Append("  ],");
            // END OF NODES

            // START LINKS
            output.Append("  \"links\": [");
            // avoid a final ","
            for (int i = 0; i < data.Links.Count; i++)
            {
                var relation = data.Links[i];
                if (i != 0)
                {
                    output.Append("    },");
                }

                output.Append("    {");
                output.Append("      \"source\": " + relation.Source + ",");
                output.Append("      \"target\": " + relation.Target + ",");
                output.Append("      \"rels\": [");
                for (int j = 0; j < relation.Hints.Count; j++)
                {
                    output.Append("         \"" + data.Links[i].Hints[j] + "\"" + (j == relation.Hints.Count - 1 ? String.Empty : ","));
                }

                output.Append("       ]");
            }
            if (data.Links.Count > 0)
            {
                output.Append("    }");
            }
            output.Append("  ]");
            // END OF LINKS
            output.Append("}");
            return(output.ToString());
        }
Exemplo n.º 11
0
        private SingleCompromiseGraphData BuildSingleCompromiseGraphData(int rootNodeId, Dictionary <int, Node> nodes, Dictionary <int, List <Relation> > links, List <int> directNodes)
        {
            var data = new SingleCompromiseGraphData();
            var idconversiontable = new Dictionary <int, int>();

            // START OF NODES

            data.Nodes = new List <SingleCompromiseGraphNodeData>();

            // it is important to put the root node as the first node for correct display
            int  nodenumber = 0;
            Node rootNode   = nodes[rootNodeId];

            data.Nodes.Add(new SingleCompromiseGraphNodeData()
            {
                Id        = nodenumber,
                Name      = rootNode.Name,
                Type      = rootNode.Type,
                ShortName = rootNode.Shortname,
                Distance  = 0,
            });
            idconversiontable[rootNode.Id] = nodenumber++;

            foreach (Node node in nodes.Values)
            {
                if (node.Id == rootNodeId)
                {
                    continue;
                }
                if (String.Equals(node.Type, "foreignsecurityprincipal", StringComparison.OrdinalIgnoreCase))
                {
                    if (String.Equals(node.Sid, "S-1-5-11", StringComparison.OrdinalIgnoreCase))
                    {
                        data.Nodes.Add(new SingleCompromiseGraphNodeData()
                        {
                            Id        = nodenumber,
                            Name      = node.Name,
                            Type      = node.Type,
                            ShortName = "Authenticated Users",
                            Distance  = node.Distance,
                            Critical  = true,
                            ADItem    = node.ADItem,
                        });
                        // unusual except when found on pre win2k group
                        if (!String.Equals(rootNode.Sid, "S-1-5-32-554", StringComparison.OrdinalIgnoreCase))
                        {
                            data.CriticalObjectFound = true;
                        }
                        idconversiontable[node.Id] = nodenumber++;
                        continue;
                    }
                    if (String.Equals(node.Sid, "S-1-1-0", StringComparison.OrdinalIgnoreCase))
                    {
                        data.Nodes.Add(new SingleCompromiseGraphNodeData()
                        {
                            Id        = nodenumber,
                            Name      = node.Name,
                            Type      = node.Type,
                            ShortName = "Everyone",
                            Distance  = node.Distance,
                            Critical  = true,
                            ADItem    = node.ADItem,
                        });
                        data.CriticalObjectFound   = true;
                        idconversiontable[node.Id] = nodenumber++;
                        continue;
                    }
                }
                bool domainUsersFound = (node.Type == "foreignsecurityprincipal" && node.Name.EndsWith("-513"));
                if (domainUsersFound)
                {
                    data.CriticalObjectFound = true;
                }
                data.Nodes.Add(new SingleCompromiseGraphNodeData()
                {
                    Id         = nodenumber,
                    Name       = node.Name,
                    Type       = node.Type,
                    ShortName  = node.Shortname,
                    Distance   = node.Distance,
                    Suspicious = (node.Type == "user" && !directNodes.Contains(node.Id)),
                    Critical   = domainUsersFound,
                    ADItem     = node.ADItem,
                });
                idconversiontable[node.Id] = nodenumber++;
            }
            // END OF NODES

            // defensive programming: check for data consistency
            foreach (int key in links.Keys)
            {
                List <Relation> link = links[key];
                foreach (Relation detail in link)
                {
                    if (!idconversiontable.ContainsKey(detail.ToId))
                    {
                        Trace.WriteLine("Inconsistancy: node missing: Id=" + detail.ToId);
                    }
                    if (!idconversiontable.ContainsKey(detail.FromId))
                    {
                        Trace.WriteLine("Inconsistancy: node missing: Id=" + detail.FromId);
                    }
                }
            }

            // START LINKS
            data.Links = new List <SingleCompromiseGraphLinkData>();

            foreach (int key in links.Keys)
            {
                List <Relation> link = links[key];
                foreach (Relation detail in link)
                {
                    data.Links.Add(new SingleCompromiseGraphLinkData()
                    {
                        Source = idconversiontable[detail.ToId],
                        Target = idconversiontable[detail.FromId],
                        Hints  = detail.Hint,
                    });
                }
            }
            // END OF LINKS
            return(data);
        }
Exemplo n.º 12
0
        private SingleCompromiseGraphData BuildSingleCompromiseGraphData(int rootNodeId, Dictionary <int, Node> nodes, Dictionary <int, List <Relation> > links)
        {
            var data = new SingleCompromiseGraphData();
            Dictionary <int, int> idconversiontable = new Dictionary <int, int>();

            // START OF NODES

            data.Nodes = new List <SingleCompromiseGraphNodeData>();

            // it is important to put the root node as the first node for correct display
            int  nodenumber = 0;
            Node rootNode   = nodes[rootNodeId];

            data.Nodes.Add(new SingleCompromiseGraphNodeData()
            {
                Id        = nodenumber,
                Name      = rootNode.Name,
                Type      = rootNode.Type,
                ShortName = rootNode.Shortname,
                Distance  = 0,
            });
            idconversiontable[rootNode.Id] = nodenumber++;

            foreach (Node node in nodes.Values)
            {
                if (node.Id == rootNodeId)
                {
                    continue;
                }
                if (String.Equals(node.Type, "foreignsecurityprincipal", StringComparison.OrdinalIgnoreCase))
                {
                    if (String.Equals(node.Shortname, "S-1-5-11", StringComparison.OrdinalIgnoreCase))
                    {
                        data.Nodes.Add(new SingleCompromiseGraphNodeData()
                        {
                            Id        = nodenumber,
                            Name      = node.Name,
                            Type      = node.Type,
                            ShortName = "Authenticated Users",
                            Distance  = node.Distance,
                        });
                        data.UnusualGroup          = true;
                        idconversiontable[node.Id] = nodenumber++;
                        continue;
                    }
                    if (String.Equals(node.Shortname, "S-1-1-0", StringComparison.OrdinalIgnoreCase))
                    {
                        data.Nodes.Add(new SingleCompromiseGraphNodeData()
                        {
                            Id        = nodenumber,
                            Name      = node.Name,
                            Type      = node.Type,
                            ShortName = "Everyone",
                            Distance  = node.Distance,
                        });
                        data.UnusualGroup          = true;
                        idconversiontable[node.Id] = nodenumber++;
                        continue;
                    }
                }
                data.Nodes.Add(new SingleCompromiseGraphNodeData()
                {
                    Id        = nodenumber,
                    Name      = node.Name,
                    Type      = node.Type,
                    ShortName = node.Shortname,
                    Distance  = node.Distance,
                });
                idconversiontable[node.Id] = nodenumber++;
            }
            // END OF NODES

            // defensive programming: check for data consistency
            foreach (int key in links.Keys)
            {
                List <Relation> link = links[key];
                foreach (Relation detail in link)
                {
                    if (!idconversiontable.ContainsKey(detail.ToId))
                    {
                        Trace.WriteLine("Inconsistancy: node missing: Id=" + detail.ToId);
                    }
                    if (!idconversiontable.ContainsKey(detail.FromId))
                    {
                        Trace.WriteLine("Inconsistancy: node missing: Id=" + detail.FromId);
                    }
                }
            }

            // START LINKS
            data.Links = new List <SingleCompromiseGraphLinkData>();

            foreach (int key in links.Keys)
            {
                List <Relation> link = links[key];
                foreach (Relation detail in link)
                {
                    data.Links.Add(new SingleCompromiseGraphLinkData()
                    {
                        Source = idconversiontable[detail.ToId],
                        Target = idconversiontable[detail.FromId],
                        Hints  = detail.Hint,
                    });
                }
            }
            // END OF LINKS
            return(data);
        }