ADCS ESC16 coverage
Description
Support for ADCS ESC16 attacks.
ESC16 is a certificate-based attack path that allows attackers to impersonate any domain user or computer by exploiting misconfigured Enterprise Certificate Authorities.
This PR implements:
- The two new EnterpriseCA properties: DisabledExtensionsCollected and DisabledExtensions
- A post-processed edge ADCSESC16 similar to ADCSESC6a with the following differences:
- Check that the EnterpriseCA has "1.3.6.1.4.1.311.25.2" in its DisabledExtensions property
- Do not check the CertTemplate’s NoSecurityExtension value
- A harness test for the ADCSESC16 edge
- Expanded the functions to read and parse arrows.app JSON files with new features
- A saved cypher query showing Enterprise CAs vulnerable to ESC16
Additional cleanup suggestions by coderabbit:
- Remove ExtendedByPolicy and WebClientRunning duplicates in ad.cue
- Remove ad.Owns and ad.WriteOwner duplicates in PostProcessedRelationships()
Motivation and Context
Resolves BED-6176
See ticket for rationale.
How Has This Been Tested?
Using the test harness and locally with this data: 20250611101235_BloodHound_esc16.zip
Screenshots (optional):
MATCH p=()-[r:ADCSESC16]->() RETURN p LIMIT 25
Types of changes
- New feature (non-breaking change which adds functionality)
Checklist:
- [x] I have met the contributing prerequisites
- Assigned myself to this PR
- Added the appropriate labels
- Associated an issue: https://github.com/SpecterOps/BloodHound/issues/672
- Read the Contributing guide: https://github.com/SpecterOps/BloodHound/wiki/Contributing
- [x] I have ensured that related documentation is up-to-date
- Open API docs
- Code comments (GoDocs / JSDocs)
- [x] I have followed proper test practices
- Added/updated tests to cover my changes
- All new and existing tests passed
Summary by CodeRabbit
- New Features
- ESC16 detection and visualization: new relationship kind, properties, edge-composition logic, UI help content, and added edge type to UI/graph schema.
- Tests
- Integration test and JSON harness added to validate ESC16 post-processing and resulting edges.
- Refactor
- Consolidated repetitive post-processing submissions into a uniform loop.
- Chores
- Ingest/graph writer extended for new properties/types; added common searches/queries for ESC16.
- Bug Fixes
- Removed a duplicate schema declaration.
Walkthrough
Adds ESC16 (ADCSESC16) support: schema and property additions, ingestion of DisabledExtensions, new ESC16 analysis and traversal logic, post-processing wiring and integration test with harness, graph IO enhancements, frontend saved searches and help-text components.
Changes
| Cohort / File(s) | Change Summary |
|---|---|
Integration test & harness cmd/api/src/analysis/ad/adcs_integration_test.go, cmd/api/src/test/integration/harnesses/ADCSESC16Harness.json |
New integration test that loads a harness, runs ADCSESC16 post-processing, writes/validates ADCSESC16 edges; new JSON harness describing nodes/relationships including ADCSESC16. |
Analysis core packages/go/analysis/ad/esc16.go, packages/go/analysis/ad/adcs.go, packages/go/analysis/ad/ad.go, packages/go/analysis/ad/post.go, packages/go/analysis/ad/queries.go |
New ESC16 detection/post-processing, edge-composition traversal (esc16.go); refactored post-processing loop to submit post jobs; wired ADCSESC16 into edge-composition, post-processed relationships, and ADC escalation traversals. |
Graph schema / properties packages/cue/bh/ad/ad.cue, packages/go/graphschema/ad/ad.go, packages/go/graphschema/common/common.go, packages/csharp/graphschema/PropertyNames.cs, packages/javascript/bh-shared-ui/src/graphSchema.ts |
Added ADCSESC16 relationship kind and properties DisabledExtensions / DisabledExtensionsCollected across CUE, Go, C#, and JS schema/mappings and relationship lists. |
Ingestion / incoming models packages/go/ein/ad.go, packages/go/ein/incoming_models.go |
Added DisabledExtensions to CARegistryData and parsing logic to include disabled extensions in ingested node properties. |
Graph fixture IO packages/go/lab/arrows/graph.go |
WriteGraphToDatabase now derives node kinds including AD/Azure Entity and lowercases property keys; added STRLIST and DECIMAL property parsing. |
Frontend: saved searches & types packages/javascript/bh-shared-ui/src/commonSearchesAGI.ts, packages/javascript/bh-shared-ui/src/commonSearchesAGT.ts, packages/javascript/bh-shared-ui/src/edgeTypes.tsx |
Added ESC16 Cypher searches and included ADCSESC16 in frontend edge-type listings. |
Frontend: help texts / components packages/javascript/bh-shared-ui/src/components/HelpTexts/ADCSESC16/*, packages/javascript/bh-shared-ui/src/components/HelpTexts/index.tsx |
New help-text React components (General, Composition, WindowsAbuse, LinuxAbuse, Opsec, References) and registration of ADCSESC16 in EdgeInfoComponents. |
Sequence Diagram(s)
sequenceDiagram
autonumber
actor Test as Integration Test
participant Loader as arrows
participant DB as Graph DB
participant Post as ADCS Analysis
participant Queue as PostRelationship Queue
Test->>Loader: Load ADCSESC16Harness.json
Loader->>DB: Create nodes/edges (omit ADCSESC16 edges)
Test->>Post: Trigger ADCSESC16 post-processing op
Post->>DB: Fetch prerequisites (CAs, domains, groups, cache)
Post->>Queue: Submit PostADCSESC16 jobs per EnterpriseCA
Queue-->>Post: Execute PostADCSESC16 jobs (create ADCSESC16 edges)
Post->>DB: Persist ADCSESC16 relationships
Test->>DB: Query and verify ADCSESC16 edges exist
Note over DB,Post: Frontend queries/saved-searches can then surface ADCSESC16
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
- SpecterOps/BloodHound#1672 — Adds/edits saved-search entries for ADCS/ESC queries (touches same frontend search files).
- SpecterOps/BloodHound#1698 — Changes to generated C# PropertyNames; related to adding DisabledExtensions property.
- SpecterOps/BloodHound#1546 — Modifies graphschema inbound/outbound relationship lists; related schema-list edits.
Suggested reviewers
- superlinkx
- mvlipka
- benwaples
Poem
"I hopped through graphs where nodes entwine,
I sniffed disabled OIDs on a vine.
Edges stitched, tests run clean and bright,
From harness to UI I dance tonight.
A rabbit cheers: ESC16 in sight! 🐇"
[!TIP]
🔌 Remote MCP (Model Context Protocol) integration is now available!
Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.
✨ Finishing Touches
- [ ] 📝 Generate Docstrings
🧪 Generate unit tests
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
- [ ] Commit unit tests in branch
adcsesc16
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
🪧 Tips
Chat
There are 3 ways to chat with CodeRabbit:
- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
I pushed a fix in commit <commit_id>, please review it.Open a follow-up GitHub issue for this discussion.
- Files and specific lines of code (under the "Files changed" tab): Tag
@coderabbitaiin a new review comment at the desired location with your query. - PR comments: Tag
@coderabbitaiin a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
Support
Need help? Create a ticket on our support page for assistance with any issues or questions.
CodeRabbit Commands (Invoked using PR/Issue comments)
Type @coderabbitai help to get the list of available commands.
Other keywords and placeholders
- Add
@coderabbitai ignoreanywhere in the PR description to prevent this PR from being reviewed. - Add
@coderabbitai summaryto generate the high-level summary at a specific location in the PR description. - Add
@coderabbitaianywhere in the PR title to generate the title automatically.
CodeRabbit Configuration File (.coderabbit.yaml)
- You can programmatically configure CodeRabbit by adding a
.coderabbit.yamlfile to the root of your repository. - Please see the configuration documentation for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation:
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
Status, Documentation and Community
- Visit our Status Page to check the current availability of CodeRabbit.
- Visit our Documentation for detailed information on how to use CodeRabbit.
- Join our Discord Community to get help, request features, and share feedback.
- Follow us on X/Twitter for updates and announcements.