Skip to content

Commit

Permalink
feat: featureflag for auto tagging T0 AD group members
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasBK committed May 16, 2024
1 parent ee7fe29 commit 7a1edf2
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 11 deletions.
15 changes: 11 additions & 4 deletions cmd/api/src/daemons/datapipe/agi.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/specterops/bloodhound/log"
"github.com/specterops/bloodhound/src/database"
"github.com/specterops/bloodhound/src/model"
"github.com/specterops/bloodhound/src/model/appcfg"
"github.com/specterops/bloodhound/src/services/agi"
)

Expand Down Expand Up @@ -154,20 +155,26 @@ func ParallelTagAzureTierZero(ctx context.Context, db graph.Database) error {
return nil
}

func TagActiveDirectoryTierZero(ctx context.Context, db graph.Database) error {
func TagActiveDirectoryTierZero(ctx context.Context, db database.Database, graphDB graph.Database) error {
defer log.Measure(log.LevelInfo, "Finished tagging Active Directory Tier Zero")()

if domains, err := adAnalysis.FetchAllDomains(ctx, db); err != nil {
autoTagMembersFlag, err := db.GetFlagByKey(ctx, appcfg.FeatureAutoTagT0ADMembers)
if err != nil {
log.Errorf("error getting AutoTagT0ADMembers feature flag: %w", err)
return err
}

if domains, err := adAnalysis.FetchAllDomains(ctx, graphDB); err != nil {
return err
} else {
for _, domain := range domains {
if roots, err := adAnalysis.FetchActiveDirectoryTierZeroRoots(ctx, db, domain); err != nil {
if roots, err := adAnalysis.FetchActiveDirectoryTierZeroRoots(ctx, graphDB, domain, autoTagMembersFlag.Enabled); err != nil {
return err
} else {
properties := graph.NewProperties()
properties.Set(common.SystemTags.String(), ad.AdminTierZero)

if err := db.WriteTransaction(ctx, func(tx graph.Transaction) error {
if err := graphDB.WriteTransaction(ctx, func(tx graph.Transaction) error {
return tx.Nodes().Filter(query.InIDs(query.Node(), roots.IDs()...)).Update(properties)
}); err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion cmd/api/src/daemons/datapipe/analysis.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func RunAnalysisOperations(ctx context.Context, db database.Database, graphDB gr
collectedErrors = append(collectedErrors, fmt.Errorf("asset group isolation tagging failed: %w", err))
}

if err := TagActiveDirectoryTierZero(ctx, graphDB); err != nil {
if err := TagActiveDirectoryTierZero(ctx, db, graphDB); err != nil {
collectedErrors = append(collectedErrors, fmt.Errorf("active directory tier zero tagging failed: %w", err))
}

Expand Down
8 changes: 8 additions & 0 deletions cmd/api/src/model/appcfg/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const (
FeatureAdcs = "adcs"
FeatureClearGraphData = "clear_graph_data"
FeatureRiskExposureNewCalculation = "risk_exposure_new_calculation"
FeatureAutoTagT0ADMembers = "auto_tag_t0_ad_members"
)

// AvailableFlags returns a FeatureFlagSet of expected feature flags. Feature flag defaults introduced here will become the initial
Expand Down Expand Up @@ -101,6 +102,13 @@ func AvailableFlags() FeatureFlagSet {
Enabled: false,
UserUpdatable: false,
},
FeatureAutoTagT0ADMembers: {
Key: FeatureAutoTagT0ADMembers,
Name: "Automatically add members of Tier Zero AD groups to Tier Zero",
Description: "Members incl. nested members of AD Tier Zero groups are automatically added to Tier Zero during analysis.",
Enabled: true,
UserUpdatable: true,
},
}
}

Expand Down
14 changes: 8 additions & 6 deletions packages/go/analysis/ad/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func FetchAllDomains(ctx context.Context, db graph.Database) ([]*graph.Node, err
})
}

func FetchActiveDirectoryTierZeroRoots(ctx context.Context, db graph.Database, domain *graph.Node) (graph.NodeSet, error) {
func FetchActiveDirectoryTierZeroRoots(ctx context.Context, db graph.Database, domain *graph.Node, autoTagMembersFlag bool) (graph.NodeSet, error) {
defer log.LogAndMeasure(log.LevelInfo, "FetchActiveDirectoryTierZeroRoots")()

if domainSID, err := domain.Properties.Get(common.ObjectID.String()).String(); err != nil {
Expand All @@ -116,11 +116,13 @@ func FetchActiveDirectoryTierZeroRoots(ctx context.Context, db graph.Database, d
attackPathRoots.AddSet(wellKnownTierZeroNodes)
}

// Pull in all group members of attack path roots
if allGroupMembers, err := FetchAllGroupMembers(ctx, db, attackPathRoots); err != nil {
return nil, err
} else {
attackPathRoots.AddSet(allGroupMembers)
if (autoTagMembersFlag) {
// Pull in all group members of attack path roots
if allGroupMembers, err := FetchAllGroupMembers(ctx, db, attackPathRoots); err != nil {
return nil, err
} else {
attackPathRoots.AddSet(allGroupMembers)
}
}

// Add all enforced GPO nodes to the attack path roots
Expand Down

0 comments on commit 7a1edf2

Please sign in to comment.