Summary
The HasKeyCredential edges that link AD principals to KeyCredential nodes are emitted in the same payload that carries metadata.source_kind, so BloodHound stamps KeyCredentialBase onto those existing AD User/Computer nodes; deleting the KeyCredentialBase source kind then deletes the contaminated AD nodes.
Location
- File(s):
parse.go, main.go
- Line(s) / function(s):
ParseResults() HasKeyCredential edge added to og (the source-kind graph); main() exports the single graph with metadata enabled
Category
state-management
Severity
high
Brief justification: Removing this collector's data from BloodHound (deleting its source kind) cascades into deletion of legitimate AD principal nodes ingested by SharpHound/AzureHound.
Reproduction / Evidence
Verified by code analysis against documented BloodHound OpenGraph behavior. The collector builds one graph with NewOpenGraph(KindKeyCredentialBase) and adds the HasKeyCredential edge (start = AD principal objectSid, an existing AD node not emitted by this collector) to that same graph. Since #15, the export emits metadata.source_kind = "KeyCredentialBase". Per the OpenGraph contract, when a payload sets metadata.source_kind and references existing AD/AZ nodes, that source kind is applied to the referenced nodes; deleting the source kind subsequently deletes those nodes. The fix is the documented two-step upload: the collector's own nodes and intra-collector edges in a source-kind payload, and the cross-collector edges (to AD) in a separate payload with no source_kind.
Expected Behavior
Cross-collector edges to AD principals are emitted in a payload that does not set metadata.source_kind, so AD nodes are never stamped with KeyCredentialBase and remain unaffected when the source kind is deleted.
Actual Behavior
The HasKeyCredential edges to AD principals share the source-kind payload, contaminating the referenced AD nodes.
Root Cause
A single graph/payload mixes the collector's own nodes (which need source_kind) with cross-collector edges to pre-existing AD nodes (which must not carry source_kind).
Summary
The
HasKeyCredentialedges that link AD principals to KeyCredential nodes are emitted in the same payload that carriesmetadata.source_kind, so BloodHound stampsKeyCredentialBaseonto those existing AD User/Computer nodes; deleting theKeyCredentialBasesource kind then deletes the contaminated AD nodes.Location
parse.go,main.goParseResults()HasKeyCredential edge added toog(the source-kind graph);main()exports the single graph with metadata enabledCategory
state-managementSeverity
highBrief justification: Removing this collector's data from BloodHound (deleting its source kind) cascades into deletion of legitimate AD principal nodes ingested by SharpHound/AzureHound.
Reproduction / Evidence
Verified by code analysis against documented BloodHound OpenGraph behavior. The collector builds one graph with
NewOpenGraph(KindKeyCredentialBase)and adds theHasKeyCredentialedge (start = AD principalobjectSid, an existing AD node not emitted by this collector) to that same graph. Since #15, the export emitsmetadata.source_kind = "KeyCredentialBase". Per the OpenGraph contract, when a payload setsmetadata.source_kindand references existing AD/AZ nodes, that source kind is applied to the referenced nodes; deleting the source kind subsequently deletes those nodes. The fix is the documented two-step upload: the collector's own nodes and intra-collector edges in a source-kind payload, and the cross-collector edges (to AD) in a separate payload with nosource_kind.Expected Behavior
Cross-collector edges to AD principals are emitted in a payload that does not set
metadata.source_kind, so AD nodes are never stamped withKeyCredentialBaseand remain unaffected when the source kind is deleted.Actual Behavior
The
HasKeyCredentialedges to AD principals share the source-kind payload, contaminating the referenced AD nodes.Root Cause
A single graph/payload mixes the collector's own nodes (which need
source_kind) with cross-collector edges to pre-existing AD nodes (which must not carrysource_kind).