Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BED-4965 - Owns/Owner Rework #993

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7b64bfb
wip: initial start on owns edge changes
rvazarkar Oct 29, 2024
c483187
wip: write post operations for writeowner/owns, update ingest
rvazarkar Oct 31, 2024
7e39e08
wip: fix return type
rvazarkar Oct 31, 2024
403d3c2
wip: remove unnecessary bool
rvazarkar Oct 31, 2024
073bd75
BED-4965: WIP merge changes to Owns/WriteOwner post-processing (#931)
Mayyhem Nov 4, 2024
df82766
Merge branch 'main' into BED-4965
rvazarkar Nov 4, 2024
44966c6
wip: fix post
rvazarkar Nov 4, 2024
9753ce9
Updated Owns/WriteOwner logic to check if any non-abusable ACEs grant…
Mayyhem Nov 7, 2024
686201c
Updated inherited vs. non-inherited benign ACE logic for WriteOwner
Mayyhem Nov 12, 2024
04b7915
Added Owns/WriteOwner to post-processed edges, deleted commented code
Mayyhem Nov 12, 2024
6d18b9c
Return stats for aggregation
Mayyhem Nov 13, 2024
9b132d6
Return cursor.Error() instead of nil
Mayyhem Nov 13, 2024
c6e2175
Updated Owns/WriteOwner[LimitedRights] help text
Mayyhem Nov 14, 2024
d5d421b
Fallback to add Owns/WriteOwner if fetching dSHeuristics/Admins fails
Mayyhem Nov 15, 2024
b64cafa
Update docs URL
Mayyhem Nov 15, 2024
0a01818
Initial harnesses for Owns/WriteOwner changes
Mayyhem Nov 15, 2024
c3f1808
Remove unused variable
Mayyhem Nov 18, 2024
5b22a33
Accounted for abusable permissions that are deleted on owner change
Mayyhem Nov 18, 2024
e15faee
Update Owns and WriteOwner setup harness
Mayyhem Nov 18, 2024
d5dbb95
Confirmed harness data is accurate and is processed as expected by Po…
Mayyhem Nov 19, 2024
6e86f50
Completed Owns edge tests
Mayyhem Nov 19, 2024
7d06e70
Completed WriteOwner edge tests
Mayyhem Nov 20, 2024
ef55a25
Accounted for all abusability and inheritance situations for user and…
Mayyhem Nov 20, 2024
c928b2d
Updated command to identify dSHeuristics, minor formatting
Mayyhem Nov 21, 2024
06790f2
Added test harness and integration testing for collector versions pri…
Mayyhem Nov 21, 2024
e44c9b7
Formatting changes from just generate
Mayyhem Nov 22, 2024
cbb9766
Updating schema with DoesAnyInheritedAceGrantOwnerRights
Mayyhem Nov 22, 2024
e40bb4a
Merge branch 'main' into BED-4965
Mayyhem Nov 22, 2024
6de74d5
Finished integration tests for post-processing collections from Sharp…
Mayyhem Nov 22, 2024
6f5ce5b
Merge remote-tracking branch 'origin/main' into BED-4965
Mayyhem Nov 25, 2024
0ad719d
Tested prior SharpHound collection file upload followed by newer vers…
Mayyhem Dec 2, 2024
5b31607
Merge branch 'main' into BED-4965
Mayyhem Dec 2, 2024
5409bbd
Fetch dSHeuristics and admin IDs once and do not return on error
Mayyhem Dec 4, 2024
a1a0cb8
Added null check for adminGroupIds
Mayyhem Dec 4, 2024
d262e0c
Remove unused variables
Mayyhem Dec 5, 2024
2b464aa
Return/log errors, fix comments, remove raw edges from ACLRelationshi…
Mayyhem Dec 12, 2024
efc4498
Prepare for code review
Mayyhem Dec 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
362 changes: 362 additions & 0 deletions cmd/api/src/analysis/ad/ad_integration_test.go

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions cmd/api/src/analysis/ad/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,15 @@ func Post(ctx context.Context, db graph.Database, adcsEnabled bool, citrixEnable
return &aggregateStats, err
} else if adcsStats, err := adAnalysis.PostADCS(ctx, db, groupExpansions, adcsEnabled); err != nil {
return &aggregateStats, err
} else if ownsStats, err := adAnalysis.PostOwnsAndWriteOwner(ctx, db, groupExpansions); err != nil {
return &aggregateStats, err
} else {
aggregateStats.Merge(stats)
aggregateStats.Merge(syncLAPSStats)
aggregateStats.Merge(dcSyncStats)
aggregateStats.Merge(localGroupStats)
aggregateStats.Merge(adcsStats)
aggregateStats.Merge(ownsStats)
return &aggregateStats, nil
}
}
54 changes: 32 additions & 22 deletions cmd/api/src/daemons/datapipe/convertors.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (

func convertComputerData(computer ein.Computer, converted *ConvertedData) {
baseNodeProp := ein.ConvertObjectToNode(computer.IngestBase, ad.Computer)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(computer.Aces, computer.ObjectIdentifier, ad.Computer)...)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, computer.Aces, computer.ObjectIdentifier, ad.Computer)...)
if primaryGroupRel := ein.ParsePrimaryGroup(computer.IngestBase, ad.Computer, computer.PrimaryGroupSID); primaryGroupRel.IsValid() {
converted.RelProps = append(converted.RelProps, primaryGroupRel)
}
Expand Down Expand Up @@ -59,30 +59,33 @@ func convertComputerData(computer ein.Computer, converted *ConvertedData) {
}

func convertUserData(user ein.User, converted *ConvertedData) {
converted.NodeProps = append(converted.NodeProps, ein.ConvertObjectToNode(user.IngestBase, ad.User))
converted.RelProps = append(converted.RelProps, ein.ParseACEData(user.Aces, user.ObjectIdentifier, ad.User)...)
baseNodeProp := ein.ConvertObjectToNode(user.IngestBase, ad.User)
rvazarkar marked this conversation as resolved.
Show resolved Hide resolved
converted.NodeProps = append(converted.NodeProps, baseNodeProp)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, user.Aces, user.ObjectIdentifier, ad.User)...)
if rel := ein.ParseObjectContainer(user.IngestBase, ad.User); rel.IsValid() {
converted.RelProps = append(converted.RelProps, rel)
}
converted.RelProps = append(converted.RelProps, ein.ParseUserMiscData(user)...)
}

func convertGroupData(group ein.Group, converted *ConvertedGroupData) {
converted.NodeProps = append(converted.NodeProps, ein.ConvertObjectToNode(group.IngestBase, ad.Group))
baseNodeProp := ein.ConvertObjectToNode(group.IngestBase, ad.Group)
converted.NodeProps = append(converted.NodeProps, baseNodeProp)

if rel := ein.ParseObjectContainer(group.IngestBase, ad.Group); rel.Source != "" && rel.Target != "" {
converted.RelProps = append(converted.RelProps, rel)
}
converted.RelProps = append(converted.RelProps, ein.ParseACEData(group.Aces, group.ObjectIdentifier, ad.Group)...)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, group.Aces, group.ObjectIdentifier, ad.Group)...)

groupMembershipData := ein.ParseGroupMembershipData(group)
converted.RelProps = append(converted.RelProps, groupMembershipData.RegularMembers...)
converted.DistinguishedNameProps = append(converted.DistinguishedNameProps, groupMembershipData.DistinguishedNameMembers...)
}

func convertDomainData(domain ein.Domain, converted *ConvertedData) {
converted.NodeProps = append(converted.NodeProps, ein.ConvertObjectToNode(domain.IngestBase, ad.Domain))
converted.RelProps = append(converted.RelProps, ein.ParseACEData(domain.Aces, domain.ObjectIdentifier, ad.Domain)...)
baseNodeProp := ein.ConvertObjectToNode(domain.IngestBase, ad.Domain)
converted.NodeProps = append(converted.NodeProps, baseNodeProp)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, domain.Aces, domain.ObjectIdentifier, ad.Domain)...)
if len(domain.ChildObjects) > 0 {
converted.RelProps = append(converted.RelProps, ein.ParseChildObjects(domain.ChildObjects, domain.ObjectIdentifier, ad.Domain)...)
}
Expand All @@ -97,13 +100,15 @@ func convertDomainData(domain ein.Domain, converted *ConvertedData) {
}

func convertGPOData(gpo ein.GPO, converted *ConvertedData) {
converted.NodeProps = append(converted.NodeProps, ein.ConvertObjectToNode(ein.IngestBase(gpo), ad.GPO))
converted.RelProps = append(converted.RelProps, ein.ParseACEData(gpo.Aces, gpo.ObjectIdentifier, ad.GPO)...)
baseNodeProp := ein.ConvertObjectToNode(ein.IngestBase(gpo), ad.GPO)
converted.NodeProps = append(converted.NodeProps, baseNodeProp)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, gpo.Aces, gpo.ObjectIdentifier, ad.GPO)...)
}

func convertOUData(ou ein.OU, converted *ConvertedData) {
converted.NodeProps = append(converted.NodeProps, ein.ConvertObjectToNode(ou.IngestBase, ad.OU))
converted.RelProps = append(converted.RelProps, ein.ParseACEData(ou.Aces, ou.ObjectIdentifier, ad.OU)...)
baseNodeProp := ein.ConvertObjectToNode(ou.IngestBase, ad.OU)
converted.NodeProps = append(converted.NodeProps, baseNodeProp)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, ou.Aces, ou.ObjectIdentifier, ad.OU)...)
if container := ein.ParseObjectContainer(ou.IngestBase, ad.OU); container.IsValid() {
converted.RelProps = append(converted.RelProps, container)
}
Expand All @@ -125,8 +130,9 @@ func CreateConvertedSessionData(count int) ConvertedSessionData {
}

func convertContainerData(container ein.Container, converted *ConvertedData) {
converted.NodeProps = append(converted.NodeProps, ein.ConvertObjectToNode(container.IngestBase, ad.Container))
converted.RelProps = append(converted.RelProps, ein.ParseACEData(container.Aces, container.ObjectIdentifier, ad.Container)...)
baseNodeProp := ein.ConvertObjectToNode(container.IngestBase, ad.Container)
converted.NodeProps = append(converted.NodeProps, baseNodeProp)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, container.Aces, container.ObjectIdentifier, ad.Container)...)

if rel := ein.ParseObjectContainer(container.IngestBase, ad.Container); rel.IsValid() {
converted.RelProps = append(converted.RelProps, rel)
Expand All @@ -138,17 +144,19 @@ func convertContainerData(container ein.Container, converted *ConvertedData) {
}

func convertAIACAData(aiaca ein.AIACA, converted *ConvertedData) {
converted.NodeProps = append(converted.NodeProps, ein.ConvertObjectToNode(ein.IngestBase(aiaca), ad.AIACA))
converted.RelProps = append(converted.RelProps, ein.ParseACEData(aiaca.Aces, aiaca.ObjectIdentifier, ad.AIACA)...)
baseNodeProp := ein.ConvertObjectToNode(ein.IngestBase(aiaca), ad.AIACA)
converted.NodeProps = append(converted.NodeProps, baseNodeProp)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, aiaca.Aces, aiaca.ObjectIdentifier, ad.AIACA)...)

if rel := ein.ParseObjectContainer(ein.IngestBase(aiaca), ad.AIACA); rel.IsValid() {
converted.RelProps = append(converted.RelProps, rel)
}
}

func convertRootCAData(rootca ein.RootCA, converted *ConvertedData) {
converted.NodeProps = append(converted.NodeProps, ein.ConvertObjectToNode(rootca.IngestBase, ad.RootCA))
converted.RelProps = append(converted.RelProps, ein.ParseACEData(rootca.Aces, rootca.ObjectIdentifier, ad.RootCA)...)
baseNodeProp := ein.ConvertObjectToNode(rootca.IngestBase, ad.RootCA)
converted.NodeProps = append(converted.NodeProps, baseNodeProp)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, rootca.Aces, rootca.ObjectIdentifier, ad.RootCA)...)
converted.RelProps = append(converted.RelProps, ein.ParseRootCAMiscData(rootca)...)

if rel := ein.ParseObjectContainer(rootca.IngestBase, ad.RootCA); rel.IsValid() {
Expand All @@ -167,18 +175,20 @@ func convertEnterpriseCAData(enterpriseca ein.EnterpriseCA, converted *Converted
}

func convertNTAuthStoreData(ntauthstore ein.NTAuthStore, converted *ConvertedData) {
converted.NodeProps = append(converted.NodeProps, ein.ConvertObjectToNode(ntauthstore.IngestBase, ad.NTAuthStore))
baseNodeProp := ein.ConvertObjectToNode(ntauthstore.IngestBase, ad.NTAuthStore)
converted.NodeProps = append(converted.NodeProps, baseNodeProp)
converted.RelProps = append(converted.RelProps, ein.ParseNTAuthStoreData(ntauthstore)...)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(ntauthstore.Aces, ntauthstore.ObjectIdentifier, ad.NTAuthStore)...)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, ntauthstore.Aces, ntauthstore.ObjectIdentifier, ad.NTAuthStore)...)

if rel := ein.ParseObjectContainer(ntauthstore.IngestBase, ad.NTAuthStore); rel.IsValid() {
converted.RelProps = append(converted.RelProps, rel)
}
}

func convertCertTemplateData(certtemplate ein.CertTemplate, converted *ConvertedData) {
converted.NodeProps = append(converted.NodeProps, ein.ConvertObjectToNode(ein.IngestBase(certtemplate), ad.CertTemplate))
converted.RelProps = append(converted.RelProps, ein.ParseACEData(certtemplate.Aces, certtemplate.ObjectIdentifier, ad.CertTemplate)...)
baseNodeProp := ein.ConvertObjectToNode(ein.IngestBase(certtemplate), ad.CertTemplate)
converted.NodeProps = append(converted.NodeProps, baseNodeProp)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(baseNodeProp, certtemplate.Aces, certtemplate.ObjectIdentifier, ad.CertTemplate)...)

if rel := ein.ParseObjectContainer(ein.IngestBase(certtemplate), ad.CertTemplate); rel.IsValid() {
converted.RelProps = append(converted.RelProps, rel)
Expand Down Expand Up @@ -206,7 +216,7 @@ func convertIssuancePolicy(issuancePolicy ein.IssuancePolicy, converted *Convert
}

converted.NodeProps = append(converted.NodeProps, props)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(issuancePolicy.Aces, issuancePolicy.ObjectIdentifier, ad.IssuancePolicy)...)
converted.RelProps = append(converted.RelProps, ein.ParseACEData(props, issuancePolicy.Aces, issuancePolicy.ObjectIdentifier, ad.IssuancePolicy)...)

if container := ein.ParseObjectContainer(issuancePolicy.IngestBase, ad.IssuancePolicy); container.IsValid() {
converted.RelProps = append(converted.RelProps, container)
Expand Down
Loading
Loading