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-4907: Edge type shortcuts #895

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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: 16 additions & 0 deletions cmd/api/src/api/tools/analysis_schedule.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
// Copyright 2024 Specter Ops, Inc.
//
// Licensed under the Apache License, Version 2.0
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

package tools

import (
Expand Down
16 changes: 16 additions & 0 deletions cmd/api/src/api/tools/analysis_schedule_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
// Copyright 2024 Specter Ops, Inc.
//
// Licensed under the Apache License, Version 2.0
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

package tools_test

import (
Expand Down
2 changes: 1 addition & 1 deletion packages/cue/bh/ad/ad.cue
Original file line number Diff line number Diff line change
Expand Up @@ -1363,7 +1363,7 @@ RelationshipKinds: [
ADCSESC10a,
ADCSESC10b,
ADCSESC13,
SyncedToEntraUser,
SyncedToEntraUser
]

// ACL Relationships
Expand Down
2 changes: 1 addition & 1 deletion packages/cue/bh/azure/azure.cue
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ RelationshipKinds: [
AZMGAddSecret,
AZMGGrantAppRoles,
AZMGGrantRole,
SyncedToADUser,
SyncedToADUser
]

AppRoleTransitRelationshipKinds: [
Expand Down
14 changes: 14 additions & 0 deletions packages/cue/bh/common/common.cue
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,23 @@ MigrationData: types.#Kind & {
representation: "MigrationData"
}

AllADAttacks: types.#Kind & {
symbol: "AllADAttacks"
schema: "active_directory"
representation: "ALL_AD_ATTACKS"
}

AllAZAttacks: types.#Kind & {
symbol: "AllAZAttacks"
schema: "azure"
representation: "ALL_AZ_ATTACKS"
}

NodeKinds: [
MigrationData,
]

RelationshipKinds: [
AllADAttacks,
AllAZAttacks
]
18 changes: 16 additions & 2 deletions packages/go/cypher/models/cypher/format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import (
"strings"

"github.com/specterops/bloodhound/cypher/models/cypher"
"github.com/specterops/bloodhound/graphschema/ad"
"github.com/specterops/bloodhound/graphschema/azure"
"github.com/specterops/bloodhound/graphschema/common"

"github.com/specterops/bloodhound/dawgs/graph"
)
Expand All @@ -37,8 +40,19 @@ func writeJoinedKinds(output io.Writer, delimiter string, kinds graph.Kinds) err
}
}

if _, err := io.WriteString(output, kind.String()); err != nil {
return err
// if kind is a shortcut edge type, further expansion is required
if kind == common.AllADAttacks {
if err := writeJoinedKinds(output, delimiter, ad.PathfindingRelationships()); err != nil {
return err
}
} else if kind == common.AllAZAttacks {
if err := writeJoinedKinds(output, delimiter, azure.PathfindingRelationships()); err != nil {
return err
}
} else {
if _, err := io.WriteString(output, kind.String()); err != nil {
return err
}
}
}

Expand Down
32 changes: 32 additions & 0 deletions packages/go/cypher/test/cases/positive_tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,38 @@
"query": "match (u:User {dontreqpreauth: true}) return u",
"complexity": 1
}
},
{
"name": "ALL_AD_ATTACKS edge shortcut",
"type": "string_match",
"details": {
"query": "match p = ()-[:ALL_AD_ATTACKS]->() return p",
"matcher": "match\\s+p\\s*=\\s*\\(\\)\\s*-\\[:Owns\\|GenericAll\\|GenericWrite\\|WriteOwner\\|WriteDacl\\|MemberOf\\|ForceChangePassword\\|AllExtendedRights\\|AddMember\\|HasSession\\|Contains\\|GPLink\\|AllowedToDelegate\\|TrustedBy\\|AllowedToAct\\|AdminTo\\|CanPSRemote\\|CanRDP\\|ExecuteDCOM\\|HasSIDHistory\\|AddSelf\\|DCSync\\|ReadLAPSPassword\\|ReadGMSAPassword\\|DumpSMSAPassword\\|SQLAdmin\\|AddAllowedToAct\\|WriteSPN\\|AddKeyCredentialLink\\|SyncLAPSPassword\\|WriteAccountRestrictions\\|WriteGPLink\\|GoldenCert\\|ADCSESC1\\|ADCSESC3\\|ADCSESC4\\|ADCSESC5\\|ADCSESC6a\\|ADCSESC6b\\|ADCSESC7\\|ADCSESC9a\\|ADCSESC9b\\|ADCSESC10a\\|ADCSESC10b\\|ADCSESC13\\|DCFor\\|SyncedToEntraUser\\]->\\(\\)\\s+return\\s+p"
}
},
{
"name": "ALL_AZ_ATTACKS edge shortcut",
"type": "string_match",
"details": {
"query": "match p = ()-[:ALL_AZ_ATTACKS]->() return p",
"matcher": "match\\s+p\\s*=\\s*\\(\\)\\s*-\\[:AZAvereContributor\\|AZContains\\|AZContributor\\|AZGetCertificates\\|AZGetKeys\\|AZGetSecrets\\|AZHasRole\\|AZMemberOf\\|AZOwner\\|AZRunsAs\\|AZVMContributor\\|AZAutomationContributor\\|AZKeyVaultContributor\\|AZVMAdminLogin\\|AZAddMembers\\|AZAddSecret\\|AZExecuteCommand\\|AZGlobalAdmin\\|AZPrivilegedAuthAdmin\\|AZGrant\\|AZGrantSelf\\|AZPrivilegedRoleAdmin\\|AZResetPassword\\|AZUserAccessAdministrator\\|AZOwns\\|AZCloudAppAdmin\\|AZAppAdmin\\|AZAddOwner\\|AZManagedIdentity\\|AZAKSContributor\\|AZNodeResourceGroup\\|AZWebsiteContributor\\|AZLogicAppContributor\\|AZMGAddMember\\|AZMGAddOwner\\|AZMGAddSecret\\|AZMGGrantAppRoles\\|AZMGGrantRole\\|SyncedToADUser\\]->\\(\\)\\s+return\\s+p"
}
},
{
"name": "ALL_AD_ATTACKS edge shortcut with extra edge after",
"type": "string_match",
"details": {
"query": "match p = ()-[:ALL_AD_ATTACKS|ExtraEdge]->() return p",
"matcher": "match\\s+p\\s*=\\s*\\(\\)\\s*-\\[:Owns\\|GenericAll\\|GenericWrite\\|WriteOwner\\|WriteDacl\\|MemberOf\\|ForceChangePassword\\|AllExtendedRights\\|AddMember\\|HasSession\\|Contains\\|GPLink\\|AllowedToDelegate\\|TrustedBy\\|AllowedToAct\\|AdminTo\\|CanPSRemote\\|CanRDP\\|ExecuteDCOM\\|HasSIDHistory\\|AddSelf\\|DCSync\\|ReadLAPSPassword\\|ReadGMSAPassword\\|DumpSMSAPassword\\|SQLAdmin\\|AddAllowedToAct\\|WriteSPN\\|AddKeyCredentialLink\\|SyncLAPSPassword\\|WriteAccountRestrictions\\|WriteGPLink\\|GoldenCert\\|ADCSESC1\\|ADCSESC3\\|ADCSESC4\\|ADCSESC5\\|ADCSESC6a\\|ADCSESC6b\\|ADCSESC7\\|ADCSESC9a\\|ADCSESC9b\\|ADCSESC10a\\|ADCSESC10b\\|ADCSESC13\\|DCFor\\|SyncedToEntraUser\\|ExtraEdge\\]->\\(\\)\\s+return\\s+p"
}
},
{
"name": "ALL_AD_ATTACKS edge shortcut with extra edge before",
"type": "string_match",
"details": {
"query": "match p = ()-[:ExtraEdge|ALL_AD_ATTACKS]->() return p",
"matcher": "match\\s+p\\s*=\\s*\\(\\)\\s*-\\[:ExtraEdge\\|Owns\\|GenericAll\\|GenericWrite\\|WriteOwner\\|WriteDacl\\|MemberOf\\|ForceChangePassword\\|AllExtendedRights\\|AddMember\\|HasSession\\|Contains\\|GPLink\\|AllowedToDelegate\\|TrustedBy\\|AllowedToAct\\|AdminTo\\|CanPSRemote\\|CanRDP\\|ExecuteDCOM\\|HasSIDHistory\\|AddSelf\\|DCSync\\|ReadLAPSPassword\\|ReadGMSAPassword\\|DumpSMSAPassword\\|SQLAdmin\\|AddAllowedToAct\\|WriteSPN\\|AddKeyCredentialLink\\|SyncLAPSPassword\\|WriteAccountRestrictions\\|WriteGPLink\\|GoldenCert\\|ADCSESC1\\|ADCSESC3\\|ADCSESC4\\|ADCSESC5\\|ADCSESC6a\\|ADCSESC6b\\|ADCSESC7\\|ADCSESC9a\\|ADCSESC9b\\|ADCSESC10a\\|ADCSESC10b\\|ADCSESC13\\|DCFor\\|SyncedToEntraUser\\]->\\(\\)\\s+return\\s+p"
}
}
]
}
1 change: 0 additions & 1 deletion packages/go/graphschema/ad/ad.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/go/graphschema/azure/azure.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions packages/go/graphschema/common/common.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions packages/javascript/bh-shared-ui/src/commonSearches.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
//
// SPDX-License-Identifier: Apache-2.0

import { ActiveDirectoryPathfindingEdges, AzurePathfindingEdges } from './graphSchema';
import { CommonRelationshipKind } from './graphSchema';

const categoryAD = 'Active Directory';
const categoryAzure = 'Azure';

const azureTransitEdgeTypes = AzurePathfindingEdges().join('|');
const adTransitEdgeTypes = ActiveDirectoryPathfindingEdges().join('|');
const adTransitEdgeTypes = CommonRelationshipKind.AllADAttacks;
const azureTransitEdgeTypes = CommonRelationshipKind.AllAZAttacks;

const highPrivilegedRoleDisplayNameRegex =
'Global Administrator.*|User Administrator.*|Cloud Application Administrator.*|Authentication Policy Administrator.*|Exchange Administrator.*|Helpdesk Administrator.*|Privileged Authentication Administrator.*';
Expand Down
14 changes: 14 additions & 0 deletions packages/javascript/bh-shared-ui/src/graphSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,20 @@ export function CommonNodeKindToDisplay(value: CommonNodeKind): string | undefin
return undefined;
}
}
export enum CommonRelationshipKind {
AllADAttacks = 'ALL_AD_ATTACKS',
AllAZAttacks = 'ALL_AZ_ATTACKS',
}
export function CommonRelationshipKindToDisplay(value: CommonRelationshipKind): string | undefined {
switch (value) {
case CommonRelationshipKind.AllADAttacks:
return 'AllADAttacks';
case CommonRelationshipKind.AllAZAttacks:
return 'AllAZAttacks';
default:
return undefined;
}
}
export enum CommonKindProperties {
ObjectID = 'objectid',
Name = 'name',
Expand Down
Loading