Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion cli/internal/scoreboard/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,16 @@ var adcsLabels = map[string]string{
"adcs_esc2": "ADCS ESC2",
"adcs_esc3": "ADCS ESC3",
"adcs_esc4": "ADCS ESC4",
"adcs_esc5": "ADCS ESC5",
"adcs_esc6": "ADCS ESC6",
"adcs_esc7": "ADCS ESC7",
"adcs_esc8": "ADCS ESC8",
"adcs_esc9": "ADCS ESC9",
"adcs_esc10_case1": "ADCS ESC10 (Case 1)",
"adcs_esc10_case2": "ADCS ESC10 (Case 2)",
"adcs_esc11": "ADCS ESC11",
"adcs_esc13": "ADCS ESC13",
"adcs_esc14": "ADCS ESC14",
"adcs_esc15": "ADCS ESC15",
}

Expand Down Expand Up @@ -355,7 +358,8 @@ func extractTechniques(lab map[string]any, asrep map[string][]string) []Objectiv
addKerberosTechniques(domains, asrep, add)
addHostTechniques(hosts, add)
addDomainTechniques(domains, add)
add("child_to_parent", "Child-to-Parent Domain Escalation", "domain_trust")
addADCSWebEnrollmentTechnique(domains, add)
addUniversalTechniques(add)

keys := make([]string, 0, len(techniques))
for k := range techniques {
Expand Down Expand Up @@ -496,6 +500,40 @@ func addPrivescTechniques(h map[string]any, add techniqueAdd) {
}
}

// addADCSWebEnrollmentTechnique credits ESC8 when any domain has Web Enrollment
// installed. ESC8 isn't a per-host vulns marker (Ansible would try to dispatch
// a non-existent vulns_adcs_esc8 role) — it's gated by the domain-level
// ca_web_enrollment flag, which defaults to true. Mirrors validate/checks.go's
// CAWebEnrollment() logic.
func addADCSWebEnrollmentTechnique(domains map[string]any, add techniqueAdd) {
for _, dRaw := range domains {
d, _ := dRaw.(map[string]any)
if v, ok := d["ca_web_enrollment"].(bool); ok && !v {
continue
}
add("adcs_esc8", "ADCS ESC8", "adcs")
return
}
}

// addUniversalTechniques credits techniques that are exploitable against any
// default-configured GOAD lab: cross-domain escalation, unpatched DC CVEs,
// ADCS-adjacent abuses (Certifried), IPv6 poisoning, and MAQ=10 chains. These
// don't have per-host markers — the lab's defaults (unpatched Server roles,
// MAQ=10, Print Spooler on, ca_web_enrollment=true) make them universally
// applicable. Documented in docs/GOAD-vulnerabilities-comprehensive.md.
func addUniversalTechniques(add techniqueAdd) {
add("child_to_parent", "Child-to-Parent Domain Escalation", "domain_trust")
add("nopac", "noPac (CVE-2021-42287/42278)", "cve")
add("printnightmare", "PrintNightmare (CVE-2021-1675)", "cve")
add("zerologon", "ZeroLogon (CVE-2020-1472)", "cve")
add("cve_2019_1040", "CVE-2019-1040 (Remove-MIC NTLM Bypass)", "cve")
add("certifried", "Certifried (CVE-2022-26923)", "adcs")
add("krbrelayup", "KrbRelayUp (RBCD self-relay)", "privilege_escalation")
add("machine_account_quota", "Machine Account Quota Abuse (MAQ=10)", "privilege_escalation")
add("mitm6", "MITM6 IPv6/DHCPv6 Poisoning", "network")
}

func addDomainTechniques(domains map[string]any, add techniqueAdd) {
addIfAnyDomainHas(domains, "acls", add, "acl_abuse", "ACL Abuse Chain", "acl_abuse")
addIfAnyDomainHas(domains, "trust", add, "cross_forest_trust", "Cross-Forest Trust Exploitation", "domain_trust")
Expand Down
4 changes: 3 additions & 1 deletion cli/internal/scoreboard/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func TestAnswerKeyHasAllExpectedTechniques(t *testing.T) {
want := []string{
"asrep_roast", "kerberoast",
"adcs_esc1", "adcs_esc2", "adcs_esc3", "adcs_esc4", "adcs_esc6",
"adcs_esc7", "adcs_esc9", "adcs_esc11", "adcs_esc13", "adcs_esc15",
"adcs_esc7", "adcs_esc8", "adcs_esc9", "adcs_esc11", "adcs_esc13", "adcs_esc15",
"adcs_esc10_case1", "adcs_esc10_case2",
"golden_ticket-essos.local",
"golden_ticket-north.sevenkingdoms.local",
Expand All @@ -126,6 +126,8 @@ func TestAnswerKeyHasAllExpectedTechniques(t *testing.T) {
"acl_abuse", "cross_forest_trust", "child_to_parent",
"constrained_delegation", "unconstrained_delegation",
"seimpersonate",
"nopac", "printnightmare", "zerologon", "cve_2019_1040",
"certifried", "krbrelayup", "machine_account_quota", "mitm6",
}
for _, w := range want {
if !techIDs[w] {
Expand Down
Loading