Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 8 additions & 8 deletions cmd/api/src/analysis/ad/ad_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1141,9 +1141,9 @@ func TestSyncLAPSPassword(t *testing.T) {
harness.SyncLAPSPasswordHarness.Setup(testContext)
return nil
}, func(harness integration.HarnessDetails, db graph.Database) {
if groupExpansions, err := adAnalysis.ExpandAllRDPLocalGroups(testContext.Context(), db); err != nil {
if localGroupData, err := adAnalysis.FetchLocalGroupData(testContext.Context(), db); err != nil {
t.Fatalf("error expanding groups in integration test; %v", err)
} else if _, err := adAnalysis.PostSyncLAPSPassword(testContext.Context(), db, groupExpansions); err != nil {
} else if _, err := adAnalysis.PostSyncLAPSPassword(testContext.Context(), db, localGroupData); err != nil {
t.Fatalf("error creating SyncLAPSPassword edges in integration test; %v", err)
} else {
db.ReadTransaction(context.Background(), func(tx graph.Transaction) error {
Expand Down Expand Up @@ -1172,9 +1172,9 @@ func TestDCSync(t *testing.T) {
harness.DCSyncHarness.Setup(testContext)
return nil
}, func(harness integration.HarnessDetails, db graph.Database) {
if groupExpansions, err := adAnalysis.ExpandAllRDPLocalGroups(testContext.Context(), db); err != nil {
if localGroupData, err := adAnalysis.FetchLocalGroupData(testContext.Context(), db); err != nil {
t.Fatalf("error expanding groups in integration test; %v", err)
} else if _, err := adAnalysis.PostDCSync(testContext.Context(), db, groupExpansions); err != nil {
} else if _, err := adAnalysis.PostDCSync(testContext.Context(), db, localGroupData); err != nil {
t.Fatalf("error creating DCSync edges in integration test; %v", err)
} else {
db.ReadTransaction(context.Background(), func(tx graph.Transaction) error {
Expand Down Expand Up @@ -1204,9 +1204,9 @@ func TestOwnsWriteOwnerPriorCollectorVersions(t *testing.T) {
// To verify in Neo4j: MATCH (n:Computer) MATCH (u:User) RETURN n, u
return nil
}, func(harness integration.HarnessDetails, db graph.Database) {
if groupExpansions, err := adAnalysis.ExpandAllRDPLocalGroups(testContext.Context(), db); err != nil {
if localGroupData, err := adAnalysis.FetchLocalGroupData(testContext.Context(), db); err != nil {
t.Fatalf("error expanding groups in integration test; %v", err)
} else if _, err := adAnalysis.PostOwnsAndWriteOwner(testContext.Context(), db, groupExpansions); err != nil {
} else if _, err := adAnalysis.PostOwnsAndWriteOwner(testContext.Context(), db, localGroupData); err != nil {
t.Fatalf("error creating Owns/WriteOwner edges in integration test; %v", err)
} else {
db.ReadTransaction(context.Background(), func(tx graph.Transaction) error {
Expand Down Expand Up @@ -1407,9 +1407,9 @@ func TestOwnsWriteOwner(t *testing.T) {
// To verify in Neo4j: MATCH (n:Computer) MATCH (u:User) RETURN n, u
return nil
}, func(harness integration.HarnessDetails, db graph.Database) {
if groupExpansions, err := adAnalysis.ExpandAllRDPLocalGroups(testContext.Context(), db); err != nil {
if localGroupData, err := adAnalysis.FetchLocalGroupData(testContext.Context(), db); err != nil {
t.Fatalf("error expanding groups in integration test; %v", err)
} else if _, err := adAnalysis.PostOwnsAndWriteOwner(testContext.Context(), db, groupExpansions); err != nil {
} else if _, err := adAnalysis.PostOwnsAndWriteOwner(testContext.Context(), db, localGroupData); err != nil {
t.Fatalf("error creating Owns/WriteOwner edges in integration test; %v", err)
} else {
db.ReadTransaction(context.Background(), func(tx graph.Transaction) error {
Expand Down
219 changes: 109 additions & 110 deletions cmd/api/src/analysis/ad/adcs_integration_test.go

Large diffs are not rendered by default.

43 changes: 21 additions & 22 deletions cmd/api/src/analysis/ad/ntlm_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/specterops/bloodhound/cmd/api/src/test/integration"
"github.com/specterops/bloodhound/packages/go/analysis"
ad2 "github.com/specterops/bloodhound/packages/go/analysis/ad"
"github.com/specterops/bloodhound/packages/go/analysis/impact"
"github.com/specterops/bloodhound/packages/go/graphschema"
"github.com/specterops/bloodhound/packages/go/graphschema/ad"
"github.com/specterops/bloodhound/packages/go/graphschema/common"
Expand All @@ -47,9 +46,9 @@ func TestPostNTLMRelayADCS(t *testing.T) {
return nil
}, func(harness integration.HarnessDetails, db graph.Database) {
operation := analysis.NewPostRelationshipOperation(context.Background(), db, "NTLM Post Process Test - CoerceAndRelayNTLMToADCS")
expansions, _, _, _, err := fetchNTLMPrereqs(db)
localGroupData, _, _, _, err := fetchNTLMPrereqs(db)
require.NoError(t, err)
ntlmCache, err := ad2.NewNTLMCache(context.Background(), db, expansions)
ntlmCache, err := ad2.NewNTLMCache(context.Background(), db, localGroupData)
require.NoError(t, err)

cache := ad2.NewADCSCache()
Expand Down Expand Up @@ -94,9 +93,9 @@ func TestNTLMRelayToADCSComposition(t *testing.T) {
return nil
}, func(harness integration.HarnessDetails, db graph.Database) {
operation := analysis.NewPostRelationshipOperation(context.Background(), db, "NTLM Composition Test - CoerceAndRelayNTLMToADCS")
expansions, _, _, _, err := fetchNTLMPrereqs(db)
localGroupData, _, _, _, err := fetchNTLMPrereqs(db)
require.NoError(t, err)
ntlmCache, err := ad2.NewNTLMCache(context.Background(), db, expansions)
ntlmCache, err := ad2.NewNTLMCache(context.Background(), db, localGroupData)
require.NoError(t, err)

cache := ad2.NewADCSCache()
Expand Down Expand Up @@ -152,9 +151,9 @@ func TestPostNTLMRelaySMB(t *testing.T) {
}, func(harness integration.HarnessDetails, db graph.Database) {
operation := analysis.NewPostRelationshipOperation(context.Background(), db, "NTLM Post Process Test - CoerceAndRelayNTLMToSMB")

groupExpansions, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
grouplocalGroupData, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
require.NoError(t, err)
ntlmCache, err := ad2.NewNTLMCache(context.Background(), db, groupExpansions)
ntlmCache, err := ad2.NewNTLMCache(context.Background(), db, grouplocalGroupData)
require.NoError(t, err)

err = operation.Operation.SubmitReader(func(ctx context.Context, tx graph.Transaction, outC chan<- analysis.CreatePostRelationshipJob) error {
Expand Down Expand Up @@ -228,9 +227,9 @@ func TestPostNTLMRelaySMB(t *testing.T) {
}, func(harness integration.HarnessDetails, db graph.Database) {
operation := analysis.NewPostRelationshipOperation(context.Background(), db, "NTLM - CoerceAndRelayNTLMToSMB - Relay To Self")

groupExpansions, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
grouplocalGroupData, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
require.NoError(t, err)
ntlmCache, err := ad2.NewNTLMCache(context.Background(), db, groupExpansions)
ntlmCache, err := ad2.NewNTLMCache(context.Background(), db, grouplocalGroupData)
require.NoError(t, err)

err = operation.Operation.SubmitReader(func(ctx context.Context, tx graph.Transaction, outC chan<- analysis.CreatePostRelationshipJob) error {
Expand Down Expand Up @@ -280,9 +279,9 @@ func TestNTLMRelayToSMBComposition(t *testing.T) {
}, func(harness integration.HarnessDetails, db graph.Database) {
operation := analysis.NewPostRelationshipOperation(context.Background(), db, "NTLM Composition Test - CoerceAndRelayNTLMToSMB")

groupExpansions, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
grouplocalGroupData, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
require.NoError(t, err)
ntlmCache, err := ad2.NewNTLMCache(context.Background(), db, groupExpansions)
ntlmCache, err := ad2.NewNTLMCache(context.Background(), db, grouplocalGroupData)
require.NoError(t, err)

err = operation.Operation.SubmitReader(func(ctx context.Context, tx graph.Transaction, outC chan<- analysis.CreatePostRelationshipJob) error {
Expand Down Expand Up @@ -352,13 +351,13 @@ func TestPostCoerceAndRelayNTLMToLDAP(t *testing.T) {
}, func(harness integration.HarnessDetails, db graph.Database) {
operation := analysis.NewPostRelationshipOperation(context.Background(), db, "NTLM Post Process Test - CoerceAndRelayNTLMToLDAP")

groupExpansions, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
grouplocalGroupData, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
require.NoError(t, err)

ldapSigningCache, err := ad2.FetchLDAPSigningCache(testContext.Context(), db)
require.NoError(t, err)

protectedUsersCache, err := ad2.FetchProtectedUsersMappedToDomains(testContext.Context(), db, groupExpansions)
protectedUsersCache, err := ad2.FetchProtectedUsersMappedToDomains(testContext.Context(), db, grouplocalGroupData)
require.NoError(t, err)

err = operation.Operation.SubmitReader(func(ctx context.Context, tx graph.Transaction, outC chan<- analysis.CreatePostRelationshipJob) error {
Expand Down Expand Up @@ -432,13 +431,13 @@ func TestPostCoerceAndRelayNTLMToLDAP(t *testing.T) {
}, func(harness integration.HarnessDetails, db graph.Database) {
operation := analysis.NewPostRelationshipOperation(context.Background(), db, "NTLM Post Process Test - CoerceAndRelayNTLMToLDAPS")

groupExpansions, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
grouplocalGroupData, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
require.NoError(t, err)

ldapSigningCache, err := ad2.FetchLDAPSigningCache(testContext.Context(), db)
require.NoError(t, err)

protectedUsersCache, err := ad2.FetchProtectedUsersMappedToDomains(testContext.Context(), db, groupExpansions)
protectedUsersCache, err := ad2.FetchProtectedUsersMappedToDomains(testContext.Context(), db, grouplocalGroupData)
require.NoError(t, err)

err = operation.Operation.SubmitReader(func(ctx context.Context, tx graph.Transaction, outC chan<- analysis.CreatePostRelationshipJob) error {
Expand Down Expand Up @@ -508,13 +507,13 @@ func TestPostCoerceAndRelayNTLMToLDAP(t *testing.T) {
}, func(harness integration.HarnessDetails, db graph.Database) {
operation := analysis.NewPostRelationshipOperation(context.Background(), db, "NTLM Post Process Test - CoerceAndRelayNTLMToLDAPS - Self Relay")

groupExpansions, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
grouplocalGroupData, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
require.NoError(t, err)

ldapSigningCache, err := ad2.FetchLDAPSigningCache(testContext.Context(), db)
require.NoError(t, err)

protectedUsersCache, err := ad2.FetchProtectedUsersMappedToDomains(testContext.Context(), db, groupExpansions)
protectedUsersCache, err := ad2.FetchProtectedUsersMappedToDomains(testContext.Context(), db, grouplocalGroupData)
require.NoError(t, err)

err = operation.Operation.SubmitReader(func(ctx context.Context, tx graph.Transaction, outC chan<- analysis.CreatePostRelationshipJob) error {
Expand Down Expand Up @@ -563,13 +562,13 @@ func TestPostCoerceAndRelayNTLMToLDAP(t *testing.T) {
}, func(harness integration.HarnessDetails, db graph.Database) {
operation := analysis.NewPostRelationshipOperation(context.Background(), db, "NTLM Post Process Test - CoerceAndRelayNTLMToLDAP - Self Relay")

groupExpansions, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
grouplocalGroupData, computers, _, authenticatedUsers, err := fetchNTLMPrereqs(db)
require.NoError(t, err)

ldapSigningCache, err := ad2.FetchLDAPSigningCache(testContext.Context(), db)
require.NoError(t, err)

protectedUsersCache, err := ad2.FetchProtectedUsersMappedToDomains(testContext.Context(), db, groupExpansions)
protectedUsersCache, err := ad2.FetchProtectedUsersMappedToDomains(testContext.Context(), db, grouplocalGroupData)
require.NoError(t, err)

err = operation.Operation.SubmitReader(func(ctx context.Context, tx graph.Transaction, outC chan<- analysis.CreatePostRelationshipJob) error {
Expand Down Expand Up @@ -611,9 +610,9 @@ func TestPostCoerceAndRelayNTLMToLDAP(t *testing.T) {
})
}

func fetchNTLMPrereqs(db graph.Database) (expansions impact.PathAggregator, computers []*graph.Node, domains []*graph.Node, authenticatedUsers map[string]graph.ID, err error) {
func fetchNTLMPrereqs(db graph.Database) (localGroupData *ad2.LocalGroupData, computers []*graph.Node, domains []*graph.Node, authenticatedUsers map[string]graph.ID, err error) {
cache := make(map[string]graph.ID)
if expansions, err = ad2.ExpandAllRDPLocalGroups(context.Background(), db); err != nil {
if localGroupData, err = ad2.FetchLocalGroupData(context.Background(), db); err != nil {
return nil, nil, nil, cache, err
} else if computers, err = ad2.FetchNodesByKind(context.Background(), db, ad.Computer); err != nil {
return nil, nil, nil, cache, err
Expand All @@ -627,6 +626,6 @@ func fetchNTLMPrereqs(db graph.Database) (expansions impact.PathAggregator, comp
} else if domains, err = ad2.FetchNodesByKind(context.Background(), db, ad.Domain); err != nil {
return nil, nil, nil, cache, err
} else {
return expansions, computers, domains, cache, nil
return localGroupData, computers, domains, cache, nil
}
}
27 changes: 16 additions & 11 deletions cmd/api/src/analysis/ad/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,36 +28,41 @@ import (

func Post(ctx context.Context, db graph.Database, adcsEnabled, citrixEnabled, ntlmEnabled bool, compositionCounter *analysis.CompositionCounter) (*analysis.AtomicPostProcessingStats, error) {
aggregateStats := analysis.NewAtomicPostProcessingStats()
if stats, err := analysis.DeleteTransitEdges(ctx, db, graph.Kinds{ad.Entity, azure.Entity}, ad.PostProcessedRelationships()...); err != nil {

if deleteTransitEdgesStats, err := analysis.DeleteTransitEdges(ctx, db, graph.Kinds{ad.Entity, azure.Entity}, ad.PostProcessedRelationships()...); err != nil {
return &aggregateStats, err
} else if groupExpansions, err := adAnalysis.ExpandAllRDPLocalGroups(ctx, db); err != nil {
} else if localGroupData, err := adAnalysis.FetchLocalGroupData(ctx, db); err != nil {
return &aggregateStats, err
} else if dcSyncStats, err := adAnalysis.PostDCSync(ctx, db, groupExpansions); err != nil {
} else if dcSyncStats, err := adAnalysis.PostDCSync(ctx, db, localGroupData); err != nil {
return &aggregateStats, err
} else if protectAdminGroupsStats, err := adAnalysis.PostProtectAdminGroups(ctx, db); err != nil {
return &aggregateStats, err
} else if syncLAPSStats, err := adAnalysis.PostSyncLAPSPassword(ctx, db, groupExpansions); err != nil {
} else if syncLAPSStats, err := adAnalysis.PostSyncLAPSPassword(ctx, db, localGroupData); err != nil {
return &aggregateStats, err
} else if hasTrustKeyStats, err := adAnalysis.PostHasTrustKeys(ctx, db); err != nil {
return &aggregateStats, err
} else if localGroupStats, err := adAnalysis.PostLocalGroups(ctx, db, groupExpansions, false, citrixEnabled); err != nil {
} else if localGroupStats, err := adAnalysis.PostLocalGroups(ctx, db, localGroupData); err != nil {
return &aggregateStats, err
} else if canRDPStats, err := adAnalysis.PostCanRDP(ctx, db, localGroupData, true, citrixEnabled); err != nil {
return &aggregateStats, err
} else if adcsStats, adcsCache, err := adAnalysis.PostADCS(ctx, db, groupExpansions, adcsEnabled); err != nil {
} else if adcsStats, adcsCache, err := adAnalysis.PostADCS(ctx, db, localGroupData, adcsEnabled); err != nil {
return &aggregateStats, err
} else if ownsStats, err := adAnalysis.PostOwnsAndWriteOwner(ctx, db, groupExpansions); err != nil {
} else if ownsStats, err := adAnalysis.PostOwnsAndWriteOwner(ctx, db, localGroupData); err != nil {
return &aggregateStats, err
} else if ntlmStats, err := adAnalysis.PostNTLM(ctx, db, groupExpansions, adcsCache, ntlmEnabled, compositionCounter); err != nil {
} else if ntlmStats, err := adAnalysis.PostNTLM(ctx, db, localGroupData, adcsCache, ntlmEnabled, compositionCounter); err != nil {
return &aggregateStats, err
} else {
aggregateStats.Merge(stats) // DeleteTransitEdges
aggregateStats.Merge(dcSyncStats) // PostDCSync
aggregateStats.Merge(protectAdminGroupsStats)
aggregateStats.Merge(deleteTransitEdgesStats)
aggregateStats.Merge(syncLAPSStats)
aggregateStats.Merge(hasTrustKeyStats)
aggregateStats.Merge(dcSyncStats)
aggregateStats.Merge(protectAdminGroupsStats)
aggregateStats.Merge(localGroupStats)
aggregateStats.Merge(canRDPStats)
aggregateStats.Merge(adcsStats)
aggregateStats.Merge(ownsStats)
aggregateStats.Merge(ntlmStats)

return &aggregateStats, nil
}
}
Loading