feat: gate ADCS ESC6/ESC9 on same-domain KDC certificate binding - #30
Merged
Conversation
**Added:** - Added `weakCertBindingDomains` and `kdcBoundADCSTechniques` in scoreboard generation to withhold credit for ESC6/ESC9 unless the certificate's own domain pins `StrongCertificateBindingEnforcement=0` via `adcs_esc10_case1` - cli/internal/scoreboard/generate.go - Added `checkESC9Enforcement` and `checkESC9KDCBinding` validation, gating ESC9 on both the template's `CT_FLAG_NO_SECURITY_EXTENSION` flag and a KDC binding of ≤1, with the template checked first so labs shipping no ESC9 template report INFO - cli/internal/validate/checks.go - Added `esc9_kdc_test.go` covering ESC9 KDC thresholds, template gating, missing flag, and same-domain DC resolution - cli/internal/validate/esc9_kdc_test.go - Added scoreboard topology tests asserting ESC6/ESC9 are credited only when the pin lives in the CA's own domain - cli/internal/scoreboard/topology_gating_test.go - Added a KDC restart to the esc10_case1 role so the new binding mode takes effect, since the running KDC otherwise stays on its old mode - ansible/roles/vulns_adcs_esc10_case1/tasks/main.yml and README.md - Added `adcs_esc10_case1` to the essos DC vuln lists so both labs pin the weak binding in the CA domain - ad/GOAD/data/config.json and ad/GOAD-variant-1/data/config.json - Documented KDC binding as a hard gate, including the KB5014754 default shift, the ESC6-vs-ESC9 threshold table, and event 39 level semantics - docs/GOAD-vulnerabilities-comprehensive.md, docs/domain-compromise-paths.md, docs/domains-and-users.md **Changed:** - Refactored ESC6's inline KDC read into a shared `readKDCBinding` helper returning a `kdcBinding` struct, and reused it for ESC9 - cli/internal/validate/checks.go - Changed the absent-value verdict from WARN to FAIL for both ESC6 and ESC9, since the shipped default is now Full Enforcement rather than unknown; the message advises pinning with `adcs_esc10_case1` - cli/internal/validate/checks.go - Renamed the ESC6 test helpers (`esc6Envelope`/`esc6Lab` → `kdcEnvelope`/`kdcBindingLab`) to reflect their shared use and updated the absent-value expectations to FAIL - cli/internal/validate/esc6_kdc_test.go
**Changed:** - Topology gating tests - Split the monolithic `TestTopologyGatedTechniques` into five focused functions (NoADCS, NoChildDomain, NHAWebEnrollment, HasADCS, VariantMatchesGOAD, KDCBound) to keep each under the repo's gocyclo threshold, updating subtest names to drop redundant prefixes - `cli/internal/scoreboard/topology_gating_test.go` - Documented that the KDC restart step is now conditional - `ansible/roles/vulns_adcs_esc10_case1/README.md`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Key Changes:
StrongCertificateBindingEnforcementvalue in the certificate's own domain, closing a gap where CA-side and template-side probes reported green while a patched KDC silently killed the attack routes (KB5014754 moved the default to Full Enforcement in Feb 2025)adcs_esc10_case1KDC binding pin to the DC that owns the CA and vulnerable templates in GOAD and GOAD-variant-1, and made the role restart the KDC so the new binding mode actually takes effectAdded:
adcs_esc10_case1role so the new binding mode takes effect immediately, gated on a changed registry write -ansible/roles/vulns_adcs_esc10_case1/tasks/main.ymlreadKDCBindinghelper andkdcBindingstruct that resolve the validating DC for a certificate's domain and read its enforcement value, shared by ESC6 and ESC9 -cli/internal/validate/checks.gocheckESC9Enforcement,checkESC9KDCBinding) that verify both the template drops the SID security extension and the KDC still accepts a weak mapping -cli/internal/validate/checks.goweakCertBindingDomainsandkdcBoundADCSTechniques, so ESC6/ESC9 are only credited when the pin lives in the CA's domain -cli/internal/scoreboard/generate.gocli/internal/validate/esc9_kdc_test.gocli/internal/scoreboard/topology_gating_test.godocs/GOAD-vulnerabilities-comprehensive.mdChanged:
StrongCertificateBindingEnforcementvalue as Full Enforcement (FAIL) rather than unknown (WARN), reflecting the KB5014754 default, and points operators to theadcs_esc10_case1vuln to pin it -cli/internal/validate/checks.goadcs_esc10_case1in the CA/template domain for both GOAD and GOAD-variant-1 -ad/GOAD/data/config.json,ad/GOAD-variant-1/data/config.jsonesc6Lab/esc6EnvelopetokdcBindingLab/kdcEnvelope) for reuse by ESC9 -cli/internal/scoreboard/topology_gating_test.go,cli/internal/validate/esc6_kdc_test.godocs/domain-compromise-paths.md,docs/domains-and-users.md,docs/GOAD-vulnerabilities-comprehensive.md,ansible/roles/vulns_adcs_esc10_case1/README.md