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 35 commits into
base: main
Choose a base branch
from
Open

BED-4965 - Owns/Owner Rework #993

wants to merge 35 commits into from

Conversation

Mayyhem
Copy link
Collaborator

@Mayyhem Mayyhem commented Dec 2, 2024

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.

  • Display Owner SID in entity panel
  • Create OwnsLimitedRights, OwnsRaw, WriteOwnerLimitedRights, and WriteOwnerRaw edges during ingest
  • Create Owns and WriteOwner edges during post-processing

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:

  • just test
  • View > Testing > Go (all tests)
     
    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

  • Chore (a change that does not modify the application functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Database Migrations

Checklist:

rvazarkar and others added 30 commits October 29, 2024 11:17
* 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
… computer object ownership and WriteOwner permissions
@@ -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)
Copy link
Contributor

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

for rel := range cursor.Chan() {

// Get the dSHeuristics values for all domains
if dsHeuristicsCache, anyEnforced, err := GetDsHeuristicsCache(ctx, db); err != nil {
Copy link
Contributor

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

for rel := range cursor.Chan() {

// Get the dSHeuristics values for all domains
if dsHeuristicsCache, anyEnforced, err := GetDsHeuristicsCache(ctx, db); err != nil {
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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)
Copy link
Contributor

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 {
Copy link
Contributor

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect comment here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants