-
Notifications
You must be signed in to change notification settings - Fork 119
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
base: main
Are you sure you want to change the base?
Conversation
* Added inheritance condition for WriteOwner abuse, added comments to Owns/WriteOwner logic * Saving changes to post Owns/WriteOwner
# Conflicts: # cmd/api/src/analysis/ad/post.go # packages/go/graphschema/ad/ad.go
…ing OWNER RIGHTS are present
… computer object ownership and WriteOwner permissions
…Hound versions prior to change
@@ -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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove the baseNodeProps changes since they're no longer necessary? We're pulling the props out and then putting them in the array
packages/go/analysis/ad/owns.go
Outdated
for rel := range cursor.Chan() { | ||
|
||
// Get the dSHeuristics values for all domains | ||
if dsHeuristicsCache, anyEnforced, err := GetDsHeuristicsCache(ctx, db); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull this and the next if statement out of the loop, as they're caching data that doesn't depend on the rels
packages/go/analysis/ad/owns.go
Outdated
for rel := range cursor.Chan() { | ||
|
||
// Get the dSHeuristics values for all domains | ||
if dsHeuristicsCache, anyEnforced, err := GetDsHeuristicsCache(ctx, db); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, pull these out of the loop
|
||
// Get the target node of the OwnsRaw relationship | ||
if targetNode, err := ops.FetchNode(tx, rel.EndID); err != nil { | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll want to log this case since that indicates a data integrity issue
continue | ||
|
||
} else if domainSid, err := targetNode.Properties.GetOrDefault(ad.DomainSID.String(), "").String(); err != nil { | ||
// Get the dSHeuristics value for the domain of the target node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is wrong
// Get the dSHeuristics values for all domains | ||
dsHeuristicsCache, anyEnforced, err := GetDsHeuristicsCache(ctx, db) | ||
if err != nil { | ||
log.Errorf("failed fetching dsheuristics values for postownsandwriteowner: %w", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking the called function, the only error case for this function is if we cant get the Domain nodes at all. I think we're actually safe to return an error here because its unlikely we're going to be able to process anything further if we cant fetch domain nodes at all
if anyEnforced { | ||
|
||
// Get the target node of the WriteOwner relationship | ||
if targetNode, err := ops.FetchNode(tx, rel.EndID); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Log this as well
continue | ||
|
||
} else if domainSid, err := targetNode.Properties.GetOrDefault(ad.DomainSID.String(), "").String(); err != nil { | ||
// Get the dSHeuristics value for the domain of the target node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect comment here
Description
This change was made to account for cases where the OWNER RIGHTS SID (S-1-3-4) is explicitly granted permissions on AD objects, which in some cases renders implicit owner rights non-abusable.
Please refer to https://specterops.atlassian.net/wiki/spaces/BE/pages/750157858/Owns+WriteOwner for details.
Motivation and Context
This PR addresses: https://specterops.atlassian.net/browse/BED-4965
How Has This Been Tested?
Integration tests were written for post-processed edges. Ingest edges were tested manually.
A test environment including test cases for OWNER RIGHTS permissions was configured using a PowerShell script included in the linked Confluence page. After generating test data for two domains, one where implicit owner rights were blocked and another where they were not, tests included:
... and confirming that expected ingest and post-processed edges were created or removed, where appropriate.
Also ran and passed:
This change does not account for inheritance hashes for ACEs but will require an update after that initiative is complete.
Screenshots (optional):
Types of changes
Checklist: